Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
      explicit CharUnits(QuantityType C) : Quantity(C) {}
46
 
47
    public:
48
 
49
      /// CharUnits - A default constructor.
50
      CharUnits() = default;
51
 
52
      /// Zero - Construct a CharUnits quantity of zero.
53
      static CharUnits Zero() {
54
        return CharUnits(0);
55
      }
56
 
57
      /// One - Construct a CharUnits quantity of one.
58
      static CharUnits One() {
59
        return CharUnits(1);
60
      }
61
 
62
      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
63
      static CharUnits fromQuantity(QuantityType Quantity) {
64
        return CharUnits(Quantity);
65
      }
66
 
67
      /// fromQuantity - Construct a CharUnits quantity from an llvm::Align
68
      /// quantity.
69
      static CharUnits fromQuantity(llvm::Align Quantity) {
70
        return CharUnits(Quantity.value());
71
      }
72
 
73
      // Compound assignment.
74
      CharUnits& operator+= (const CharUnits &Other) {
75
        Quantity += Other.Quantity;
76
        return *this;
77
      }
78
      CharUnits& operator++ () {
79
        ++Quantity;
80
        return *this;
81
      }
82
      CharUnits operator++ (int) {
83
        return CharUnits(Quantity++);
84
      }
85
      CharUnits& operator-= (const CharUnits &Other) {
86
        Quantity -= Other.Quantity;
87
        return *this;
88
      }
89
      CharUnits& operator-- () {
90
        --Quantity;
91
        return *this;
92
      }
93
      CharUnits operator-- (int) {
94
        return CharUnits(Quantity--);
95
      }
96
 
97
      // Comparison operators.
98
      bool operator== (const CharUnits &Other) const {
99
        return Quantity == Other.Quantity;
100
      }
101
      bool operator!= (const CharUnits &Other) const {
102
        return Quantity != Other.Quantity;
103
      }
104
 
105
      // Relational operators.
106
      bool operator<  (const CharUnits &Other) const {
107
        return Quantity <  Other.Quantity;
108
      }
109
      bool operator<= (const CharUnits &Other) const {
110
        return Quantity <= Other.Quantity;
111
      }
112
      bool operator>  (const CharUnits &Other) const {
113
        return Quantity >  Other.Quantity;
114
      }
115
      bool operator>= (const CharUnits &Other) const {
116
        return Quantity >= Other.Quantity;
117
      }
118
 
119
      // Other predicates.
120
 
121
      /// isZero - Test whether the quantity equals zero.
122
      bool isZero() const     { return Quantity == 0; }
123
 
124
      /// isOne - Test whether the quantity equals one.
125
      bool isOne() const      { return Quantity == 1; }
126
 
127
      /// isPositive - Test whether the quantity is greater than zero.
128
      bool isPositive() const { return Quantity  > 0; }
129
 
130
      /// isNegative - Test whether the quantity is less than zero.
131
      bool isNegative() const { return Quantity  < 0; }
132
 
133
      /// isPowerOfTwo - Test whether the quantity is a power of two.
134
      /// Zero is not a power of two.
135
      bool isPowerOfTwo() const {
136
        return (Quantity & -Quantity) == Quantity;
137
      }
138
 
139
      /// Test whether this is a multiple of the other value.
140
      ///
141
      /// Among other things, this promises that
142
      /// self.alignTo(N) will just return self.
143
      bool isMultipleOf(CharUnits N) const {
144
        return (*this % N) == 0;
145
      }
146
 
147
      // Arithmetic operators.
148
      CharUnits operator* (QuantityType N) const {
149
        return CharUnits(Quantity * N);
150
      }
151
      CharUnits &operator*= (QuantityType N) {
152
        Quantity *= N;
153
        return *this;
154
      }
155
      CharUnits operator/ (QuantityType N) const {
156
        return CharUnits(Quantity / N);
157
      }
158
      CharUnits &operator/= (QuantityType N) {
159
        Quantity /= N;
160
        return *this;
161
      }
162
      QuantityType operator/ (const CharUnits &Other) const {
163
        return Quantity / Other.Quantity;
164
      }
165
      CharUnits operator% (QuantityType N) const {
166
        return CharUnits(Quantity % N);
167
      }
168
      QuantityType operator% (const CharUnits &Other) const {
169
        return Quantity % Other.Quantity;
170
      }
171
      CharUnits operator+ (const CharUnits &Other) const {
172
        return CharUnits(Quantity + Other.Quantity);
173
      }
174
      CharUnits operator- (const CharUnits &Other) const {
175
        return CharUnits(Quantity - Other.Quantity);
176
      }
177
      CharUnits operator- () const {
178
        return CharUnits(-Quantity);
179
      }
180
 
181
 
182
      // Conversions.
183
 
184
      /// getQuantity - Get the raw integer representation of this quantity.
185
      QuantityType getQuantity() const { return Quantity; }
186
 
187
      /// getAsAlign - Returns Quantity as a valid llvm::Align,
188
      /// Beware llvm::Align assumes power of two 8-bit bytes.
189
      llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
190
 
191
      /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or
192
      /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit
193
      /// bytes.
194
      llvm::MaybeAlign getAsMaybeAlign() const {
195
        return llvm::MaybeAlign(Quantity);
196
      }
197
 
198
      /// alignTo - Returns the next integer (mod 2**64) that is
199
      /// greater than or equal to this quantity and is a multiple of \p Align.
200
      /// Align must be non-zero.
201
      CharUnits alignTo(const CharUnits &Align) const {
202
        return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
203
      }
204
 
205
      /// Given that this is a non-zero alignment value, what is the
206
      /// alignment at the given offset?
207
      CharUnits alignmentAtOffset(CharUnits offset) const {
208
        assert(Quantity != 0 && "offsetting from unknown alignment?");
209
        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
210
      }
211
 
212
      /// Given that this is the alignment of the first element of an
213
      /// array, return the minimum alignment of any element in the array.
214
      CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
215
        // Since we don't track offsetted alignments, the alignment of
216
        // the second element (or any odd element) will be minimally
217
        // aligned.
218
        return alignmentAtOffset(elementSize);
219
      }
220
 
221
 
222
  }; // class CharUnit
223
} // namespace clang
224
 
225
inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
226
                                   const clang::CharUnits &CU) {
227
  return CU * Scale;
228
}
229
 
230
namespace llvm {
231
 
232
template<> struct DenseMapInfo<clang::CharUnits> {
233
  static clang::CharUnits getEmptyKey() {
234
    clang::CharUnits::QuantityType Quantity =
235
      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
236
 
237
    return clang::CharUnits::fromQuantity(Quantity);
238
  }
239
 
240
  static clang::CharUnits getTombstoneKey() {
241
    clang::CharUnits::QuantityType Quantity =
242
      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
243
 
244
    return clang::CharUnits::fromQuantity(Quantity);
245
  }
246
 
247
  static unsigned getHashValue(const clang::CharUnits &CU) {
248
    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
249
    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
250
  }
251
 
252
  static bool isEqual(const clang::CharUnits &LHS,
253
                      const clang::CharUnits &RHS) {
254
    return LHS == RHS;
255
  }
256
};
257
 
258
} // end namespace llvm
259
 
260
#endif // LLVM_CLANG_AST_CHARUNITS_H