• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines the CharUnits class
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_CHARUNITS_H
15 #define LLVM_CLANG_AST_CHARUNITS_H
16 
17 #include "llvm/ADT/DenseMapInfo.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   /// It should be noted that characters and bytes are distinct concepts. Bytes
30   /// refer to addressable units of data storage on the target machine, and
31   /// characters are members of a set of elements used for the organization,
32   /// control, or representation of data. According to C99, bytes are allowed
33   /// to exceed characters in size, although currently, clang only supports
34   /// architectures where the two are the same size.
35   ///
36   /// For portability, never assume that a target character is 8 bits wide. Use
37   /// CharUnit values wherever you calculate sizes, offsets, or alignments
38   /// in character units.
39   class CharUnits {
40     public:
41       typedef int64_t QuantityType;
42 
43     private:
44       QuantityType Quantity;
45 
CharUnits(QuantityType C)46       explicit CharUnits(QuantityType C) : Quantity(C) {}
47 
48     public:
49 
50       /// CharUnits - A default constructor.
CharUnits()51       CharUnits() : Quantity(0) {}
52 
53       /// Zero - Construct a CharUnits quantity of zero.
Zero()54       static CharUnits Zero() {
55         return CharUnits(0);
56       }
57 
58       /// One - Construct a CharUnits quantity of one.
One()59       static CharUnits One() {
60         return CharUnits(1);
61       }
62 
63       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
fromQuantity(QuantityType Quantity)64       static CharUnits fromQuantity(QuantityType Quantity) {
65         return CharUnits(Quantity);
66       }
67 
68       // Compound assignment.
69       CharUnits& operator+= (const CharUnits &Other) {
70         Quantity += Other.Quantity;
71         return *this;
72       }
73       CharUnits& operator++ () {
74         ++Quantity;
75         return *this;
76       }
77       CharUnits operator++ (int) {
78         return CharUnits(Quantity++);
79       }
80       CharUnits& operator-= (const CharUnits &Other) {
81         Quantity -= Other.Quantity;
82         return *this;
83       }
84       CharUnits& operator-- () {
85         --Quantity;
86         return *this;
87       }
88       CharUnits operator-- (int) {
89         return CharUnits(Quantity--);
90       }
91 
92       // Comparison operators.
93       bool operator== (const CharUnits &Other) const {
94         return Quantity == Other.Quantity;
95       }
96       bool operator!= (const CharUnits &Other) const {
97         return Quantity != Other.Quantity;
98       }
99 
100       // Relational operators.
101       bool operator<  (const CharUnits &Other) const {
102         return Quantity <  Other.Quantity;
103       }
104       bool operator<= (const CharUnits &Other) const {
105         return Quantity <= Other.Quantity;
106       }
107       bool operator>  (const CharUnits &Other) const {
108         return Quantity >  Other.Quantity;
109       }
110       bool operator>= (const CharUnits &Other) const {
111         return Quantity >= Other.Quantity;
112       }
113 
114       // Other predicates.
115 
116       /// isZero - Test whether the quantity equals zero.
isZero()117       bool isZero() const     { return Quantity == 0; }
118 
119       /// isOne - Test whether the quantity equals one.
isOne()120       bool isOne() const      { return Quantity == 1; }
121 
122       /// isPositive - Test whether the quantity is greater than zero.
isPositive()123       bool isPositive() const { return Quantity  > 0; }
124 
125       /// isNegative - Test whether the quantity is less than zero.
isNegative()126       bool isNegative() const { return Quantity  < 0; }
127 
128       /// isPowerOfTwo - Test whether the quantity is a power of two.
129       /// Zero is not a power of two.
isPowerOfTwo()130       bool isPowerOfTwo() const {
131         return (Quantity & -Quantity) == Quantity;
132       }
133 
134       // Arithmetic operators.
135       CharUnits operator* (QuantityType N) const {
136         return CharUnits(Quantity * N);
137       }
138       CharUnits operator/ (QuantityType N) const {
139         return CharUnits(Quantity / N);
140       }
141       QuantityType operator/ (const CharUnits &Other) const {
142         return Quantity / Other.Quantity;
143       }
144       CharUnits operator% (QuantityType N) const {
145         return CharUnits(Quantity % N);
146       }
147       QuantityType operator% (const CharUnits &Other) const {
148         return Quantity % Other.Quantity;
149       }
150       CharUnits operator+ (const CharUnits &Other) const {
151         return CharUnits(Quantity + Other.Quantity);
152       }
153       CharUnits operator- (const CharUnits &Other) const {
154         return CharUnits(Quantity - Other.Quantity);
155       }
156       CharUnits operator- () const {
157         return CharUnits(-Quantity);
158       }
159 
160 
161       // Conversions.
162 
163       /// getQuantity - Get the raw integer representation of this quantity.
getQuantity()164       QuantityType getQuantity() const { return Quantity; }
165 
166       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
167       /// greater than or equal to this quantity and is a multiple of \p Align.
168       /// Align must be non-zero.
RoundUpToAlignment(const CharUnits & Align)169       CharUnits RoundUpToAlignment(const CharUnits &Align) {
170         return CharUnits(llvm::RoundUpToAlignment(Quantity,
171                                                   Align.Quantity));
172       }
173 
174       /// Given that this is a non-zero alignment value, what is the
175       /// alignment at the given offset?
alignmentAtOffset(CharUnits offset)176       CharUnits alignmentAtOffset(CharUnits offset) {
177         // alignment: 0010000
178         // offset:    1011100
179         // lowBits:   0001011
180         // result:    0000100
181         QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
182         return CharUnits((lowBits + 1) & ~lowBits);
183       }
184 
185 
186   }; // class CharUnit
187 } // namespace clang
188 
189 inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
190                                    const clang::CharUnits &CU) {
191   return CU * Scale;
192 }
193 
194 namespace llvm {
195 
196 template<> struct DenseMapInfo<clang::CharUnits> {
197   static clang::CharUnits getEmptyKey() {
198     clang::CharUnits::QuantityType Quantity =
199       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
200 
201     return clang::CharUnits::fromQuantity(Quantity);
202   }
203 
204   static clang::CharUnits getTombstoneKey() {
205     clang::CharUnits::QuantityType Quantity =
206       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
207 
208     return clang::CharUnits::fromQuantity(Quantity);
209   }
210 
211   static unsigned getHashValue(const clang::CharUnits &CU) {
212     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
213     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
214   }
215 
216   static bool isEqual(const clang::CharUnits &LHS,
217                       const clang::CharUnits &RHS) {
218     return LHS == RHS;
219   }
220 };
221 
222 template <> struct isPodLike<clang::CharUnits> {
223   static const bool value = true;
224 };
225 
226 } // end namespace llvm
227 
228 #endif // LLVM_CLANG_AST_CHARUNITS_H
229