Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/CharUnits.h
Line
Count
Source (jump to first uncovered line)
1
//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines the CharUnits class
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_AST_CHARUNITS_H
14
#define LLVM_CLANG_AST_CHARUNITS_H
15
16
#include "llvm/ADT/DenseMapInfo.h"
17
#include "llvm/Support/Alignment.h"
18
#include "llvm/Support/DataTypes.h"
19
#include "llvm/Support/MathExtras.h"
20
21
namespace clang {
22
23
  /// CharUnits - This is an opaque type for sizes expressed in character units.
24
  /// Instances of this type represent a quantity as a multiple of the size
25
  /// of the standard C type, char, on the target architecture. As an opaque
26
  /// type, CharUnits protects you from accidentally combining operations on
27
  /// quantities in bit units and character units.
28
  ///
29
  /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
30
  /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
31
  /// the same quantity of storage. However, we use the term 'character unit'
32
  /// rather than 'byte' to avoid an implication that a character unit is
33
  /// exactly 8 bits.
34
  ///
35
  /// For portability, never assume that a target character is 8 bits wide. Use
36
  /// CharUnit values wherever you calculate sizes, offsets, or alignments
37
  /// in character units.
38
  class CharUnits {
39
    public:
40
      typedef int64_t QuantityType;
41
42
    private:
43
      QuantityType Quantity = 0;
44
45
32.5M
      explicit CharUnits(QuantityType C) : Quantity(C) {}
46
47
    public:
48
49
      /// CharUnits - A default constructor.
50
20.7M
      CharUnits() = default;
51
52
      /// Zero - Construct a CharUnits quantity of zero.
53
1.66M
      static CharUnits Zero() {
54
1.66M
        return CharUnits(0);
55
1.66M
      }
56
57
      /// One - Construct a CharUnits quantity of one.
58
1.75M
      static CharUnits One() {
59
1.75M
        return CharUnits(1);
60
1.75M
      }
61
62
      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
63
23.3M
      static CharUnits fromQuantity(QuantityType Quantity) {
64
23.3M
        return CharUnits(Quantity);
65
23.3M
      }
66
67
      // Compound assignment.
68
202k
      CharUnits& operator+= (const CharUnits &Other) {
69
202k
        Quantity += Other.Quantity;
70
202k
        return *this;
71
202k
      }
72
1.17k
      CharUnits& operator++ () {
73
1.17k
        ++Quantity;
74
1.17k
        return *this;
75
1.17k
      }
76
281
      CharUnits operator++ (int) {
77
281
        return CharUnits(Quantity++);
78
281
      }
79
1.28k
      CharUnits& operator-= (const CharUnits &Other) {
80
1.28k
        Quantity -= Other.Quantity;
81
1.28k
        return *this;
82
1.28k
      }
83
0
      CharUnits& operator-- () {
84
0
        --Quantity;
85
0
        return *this;
86
0
      }
87
0
      CharUnits operator-- (int) {
88
0
        return CharUnits(Quantity--);
89
0
      }
90
91
      // Comparison operators.
92
4.21M
      bool operator== (const CharUnits &Other) const {
93
4.21M
        return Quantity == Other.Quantity;
94
4.21M
      }
95
374k
      bool operator!= (const CharUnits &Other) const {
96
374k
        return Quantity != Other.Quantity;
97
374k
      }
98
99
      // Relational operators.
100
4.87M
      bool operator<  (const CharUnits &Other) const {
101
4.87M
        return Quantity <  Other.Quantity;
102
4.87M
      }
103
1.13M
      bool operator<= (const CharUnits &Other) const {
104
1.13M
        return Quantity <= Other.Quantity;
105
1.13M
      }
106
2.79M
      bool operator>  (const CharUnits &Other) const {
107
2.79M
        return Quantity >  Other.Quantity;
108
2.79M
      }
109
917k
      bool operator>= (const CharUnits &Other) const {
110
917k
        return Quantity >= Other.Quantity;
111
917k
      }
112
113
      // Other predicates.
114
115
      /// isZero - Test whether the quantity equals zero.
116
17.6M
      bool isZero() const     { return Quantity == 0; }
117
118
      /// isOne - Test whether the quantity equals one.
119
2.36k
      bool isOne() const      { return Quantity == 1; }
120
121
      /// isPositive - Test whether the quantity is greater than zero.
122
5.66k
      bool isPositive() const { return Quantity  > 0; }
123
124
      /// isNegative - Test whether the quantity is less than zero.
125
81.3k
      bool isNegative() const { return Quantity  < 0; }
126
127
      /// isPowerOfTwo - Test whether the quantity is a power of two.
128
      /// Zero is not a power of two.
129
620
      bool isPowerOfTwo() const {
130
620
        return (Quantity & -Quantity) == Quantity;
131
620
      }
132
133
      /// Test whether this is a multiple of the other value.
134
      ///
135
      /// Among other things, this promises that
136
      /// self.alignTo(N) will just return self.
137
25.0k
      bool isMultipleOf(CharUnits N) const {
138
25.0k
        return (*this % N) == 0;
139
25.0k
      }
140
141
      // Arithmetic operators.
142
95.7k
      CharUnits operator* (QuantityType N) const {
143
95.7k
        return CharUnits(Quantity * N);
144
95.7k
      }
145
4.33k
      CharUnits &operator*= (QuantityType N) {
146
4.33k
        Quantity *= N;
147
4.33k
        return *this;
148
4.33k
      }
149
238
      CharUnits operator/ (QuantityType N) const {
150
238
        return CharUnits(Quantity / N);
151
238
      }
152
60
      CharUnits &operator/= (QuantityType N) {
153
60
        Quantity /= N;
154
60
        return *this;
155
60
      }
156
786
      QuantityType operator/ (const CharUnits &Other) const {
157
786
        return Quantity / Other.Quantity;
158
786
      }
159
122
      CharUnits operator% (QuantityType N) const {
160
122
        return CharUnits(Quantity % N);
161
122
      }
162
465k
      QuantityType operator% (const CharUnits &Other) const {
163
465k
        return Quantity % Other.Quantity;
164
465k
      }
165
3.42M
      CharUnits operator+ (const CharUnits &Other) const {
166
3.42M
        return CharUnits(Quantity + Other.Quantity);
167
3.42M
      }
168
44.9k
      CharUnits operator- (const CharUnits &Other) const {
169
44.9k
        return CharUnits(Quantity - Other.Quantity);
170
44.9k
      }
171
11.3k
      CharUnits operator- () const {
172
11.3k
        return CharUnits(-Quantity);
173
11.3k
      }
174
175
176
      // Conversions.
177
178
      /// getQuantity - Get the raw integer representation of this quantity.
179
20.3M
      QuantityType getQuantity() const { return Quantity; }
180
181
      /// getAsAlign - Returns Quantity as a valid llvm::Align,
182
      /// Beware llvm::Align assumes power of two 8-bit bytes.
183
2.93M
      llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
184
185
      /// alignTo - Returns the next integer (mod 2**64) that is
186
      /// greater than or equal to this quantity and is a multiple of \p Align.
187
      /// Align must be non-zero.
188
1.89M
      CharUnits alignTo(const CharUnits &Align) const {
189
1.89M
        return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
190
1.89M
      }
191
192
      /// Given that this is a non-zero alignment value, what is the
193
      /// alignment at the given offset?
194
312k
      CharUnits alignmentAtOffset(CharUnits offset) const {
195
312k
        assert(Quantity != 0 && "offsetting from unknown alignment?");
196
312k
        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
197
312k
      }
198
199
      /// Given that this is the alignment of the first element of an
200
      /// array, return the minimum alignment of any element in the array.
201
33.2k
      CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
202
33.2k
        // Since we don't track offsetted alignments, the alignment of
203
33.2k
        // the second element (or any odd element) will be minimally
204
33.2k
        // aligned.
205
33.2k
        return alignmentAtOffset(elementSize);
206
33.2k
      }
207
208
209
  }; // class CharUnit
210
} // namespace clang
211
212
inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
213
88.3k
                                   const clang::CharUnits &CU) {
214
88.3k
  return CU * Scale;
215
88.3k
}
216
217
namespace llvm {
218
219
template<> struct DenseMapInfo<clang::CharUnits> {
220
391k
  static clang::CharUnits getEmptyKey() {
221
391k
    clang::CharUnits::QuantityType Quantity =
222
391k
      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
223
391k
224
391k
    return clang::CharUnits::fromQuantity(Quantity);
225
391k
  }
226
227
272k
  static clang::CharUnits getTombstoneKey() {
228
272k
    clang::CharUnits::QuantityType Quantity =
229
272k
      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
230
272k
231
272k
    return clang::CharUnits::fromQuantity(Quantity);
232
272k
  }
233
234
253k
  static unsigned getHashValue(const clang::CharUnits &CU) {
235
253k
    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
236
253k
    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
237
253k
  }
238
239
  static bool isEqual(const clang::CharUnits &LHS,
240
3.33M
                      const clang::CharUnits &RHS) {
241
3.33M
    return LHS == RHS;
242
3.33M
  }
243
};
244
245
} // end namespace llvm
246
247
#endif // LLVM_CLANG_AST_CHARUNITS_H