]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/include/clang/AST/CharUnits.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / clang / include / clang / AST / CharUnits.h
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   /// 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;
44
45       explicit CharUnits(QuantityType C) : Quantity(C) {}
46
47     public:
48
49       /// CharUnits - A default constructor.
50       CharUnits() : Quantity(0) {}
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       // Compound assignment.
68       CharUnits& operator+= (const CharUnits &Other) {
69         Quantity += Other.Quantity;
70         return *this;
71       }
72       CharUnits& operator++ () {
73         ++Quantity;
74         return *this;
75       }
76       CharUnits operator++ (int) {
77         return CharUnits(Quantity++);
78       }
79       CharUnits& operator-= (const CharUnits &Other) {
80         Quantity -= Other.Quantity;
81         return *this;
82       }
83       CharUnits& operator-- () {
84         --Quantity;
85         return *this;
86       }
87       CharUnits operator-- (int) {
88         return CharUnits(Quantity--);
89       }
90        
91       // Comparison operators.
92       bool operator== (const CharUnits &Other) const {
93         return Quantity == Other.Quantity;
94       }
95       bool operator!= (const CharUnits &Other) const {
96         return Quantity != Other.Quantity;
97       }
98
99       // Relational operators.
100       bool operator<  (const CharUnits &Other) const { 
101         return Quantity <  Other.Quantity; 
102       }
103       bool operator<= (const CharUnits &Other) const { 
104         return Quantity <= Other.Quantity;
105       }
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
113       // Other predicates.
114       
115       /// isZero - Test whether the quantity equals zero.
116       bool isZero() const     { return Quantity == 0; }
117
118       /// isOne - Test whether the quantity equals one.
119       bool isOne() const      { return Quantity == 1; }
120
121       /// isPositive - Test whether the quantity is greater than zero.
122       bool isPositive() const { return Quantity  > 0; }
123
124       /// isNegative - Test whether the quantity is less than zero.
125       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       bool isPowerOfTwo() const {
130         return (Quantity & -Quantity) == Quantity;
131       }
132
133       // Arithmetic operators.
134       CharUnits operator* (QuantityType N) const {
135         return CharUnits(Quantity * N);
136       }
137       CharUnits operator/ (QuantityType N) const {
138         return CharUnits(Quantity / N);
139       }
140       QuantityType operator/ (const CharUnits &Other) const {
141         return Quantity / Other.Quantity;
142       }
143       CharUnits operator% (QuantityType N) const {
144         return CharUnits(Quantity % N);
145       }
146       QuantityType operator% (const CharUnits &Other) const {
147         return Quantity % Other.Quantity;
148       }
149       CharUnits operator+ (const CharUnits &Other) const {
150         return CharUnits(Quantity + Other.Quantity);
151       }
152       CharUnits operator- (const CharUnits &Other) const {
153         return CharUnits(Quantity - Other.Quantity);
154       }
155       CharUnits operator- () const {
156         return CharUnits(-Quantity);
157       }
158
159       
160       // Conversions.
161
162       /// getQuantity - Get the raw integer representation of this quantity.
163       QuantityType getQuantity() const { return Quantity; }
164
165       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
166       /// greater than or equal to this quantity and is a multiple of \p Align.
167       /// Align must be non-zero.
168       CharUnits RoundUpToAlignment(const CharUnits &Align) {
169         return CharUnits(llvm::RoundUpToAlignment(Quantity, 
170                                                   Align.Quantity));
171       }
172
173       /// Given that this is a non-zero alignment value, what is the
174       /// alignment at the given offset?
175       CharUnits alignmentAtOffset(CharUnits offset) {
176         // alignment: 0010000
177         // offset:    1011100
178         // lowBits:   0001011
179         // result:    0000100
180         QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
181         return CharUnits((lowBits + 1) & ~lowBits);
182       }
183
184
185   }; // class CharUnit
186 } // namespace clang
187
188 inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
189                                    const clang::CharUnits &CU) {
190   return CU * Scale;
191 }
192
193 namespace llvm {
194
195 template<> struct DenseMapInfo<clang::CharUnits> {
196   static clang::CharUnits getEmptyKey() {
197     clang::CharUnits::QuantityType Quantity =
198       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
199
200     return clang::CharUnits::fromQuantity(Quantity);
201   }
202
203   static clang::CharUnits getTombstoneKey() {
204     clang::CharUnits::QuantityType Quantity =
205       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
206     
207     return clang::CharUnits::fromQuantity(Quantity);    
208   }
209
210   static unsigned getHashValue(const clang::CharUnits &CU) {
211     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
212     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
213   }
214
215   static bool isEqual(const clang::CharUnits &LHS, 
216                       const clang::CharUnits &RHS) {
217     return LHS == RHS;
218   }
219 };
220
221 template <> struct isPodLike<clang::CharUnits> {
222   static const bool value = true;
223 };
224   
225 } // end namespace llvm
226
227 #endif // LLVM_CLANG_AST_CHARUNITS_H