xref: /minix3/external/bsd/llvm/dist/clang/include/clang/AST/CharUnits.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the CharUnits class
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #ifndef LLVM_CLANG_AST_CHARUNITS_H
15f4a2713aSLionel Sambuc #define LLVM_CLANG_AST_CHARUNITS_H
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMapInfo.h"
18f4a2713aSLionel Sambuc #include "llvm/Support/DataTypes.h"
19f4a2713aSLionel Sambuc #include "llvm/Support/MathExtras.h"
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc namespace clang {
22f4a2713aSLionel Sambuc 
23f4a2713aSLionel Sambuc   /// CharUnits - This is an opaque type for sizes expressed in character units.
24f4a2713aSLionel Sambuc   /// Instances of this type represent a quantity as a multiple of the size
25f4a2713aSLionel Sambuc   /// of the standard C type, char, on the target architecture. As an opaque
26f4a2713aSLionel Sambuc   /// type, CharUnits protects you from accidentally combining operations on
27f4a2713aSLionel Sambuc   /// quantities in bit units and character units.
28f4a2713aSLionel Sambuc   ///
29f4a2713aSLionel Sambuc   /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
30f4a2713aSLionel Sambuc   /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
31f4a2713aSLionel Sambuc   /// the same quantity of storage. However, we use the term 'character unit'
32f4a2713aSLionel Sambuc   /// rather than 'byte' to avoid an implication that a character unit is
33f4a2713aSLionel Sambuc   /// exactly 8 bits.
34f4a2713aSLionel Sambuc   ///
35f4a2713aSLionel Sambuc   /// For portability, never assume that a target character is 8 bits wide. Use
36f4a2713aSLionel Sambuc   /// CharUnit values wherever you calculate sizes, offsets, or alignments
37f4a2713aSLionel Sambuc   /// in character units.
38f4a2713aSLionel Sambuc   class CharUnits {
39f4a2713aSLionel Sambuc     public:
40f4a2713aSLionel Sambuc       typedef int64_t QuantityType;
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc     private:
43f4a2713aSLionel Sambuc       QuantityType Quantity;
44f4a2713aSLionel Sambuc 
CharUnits(QuantityType C)45f4a2713aSLionel Sambuc       explicit CharUnits(QuantityType C) : Quantity(C) {}
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc     public:
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc       /// CharUnits - A default constructor.
CharUnits()50f4a2713aSLionel Sambuc       CharUnits() : Quantity(0) {}
51f4a2713aSLionel Sambuc 
52f4a2713aSLionel Sambuc       /// Zero - Construct a CharUnits quantity of zero.
Zero()53f4a2713aSLionel Sambuc       static CharUnits Zero() {
54f4a2713aSLionel Sambuc         return CharUnits(0);
55f4a2713aSLionel Sambuc       }
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc       /// One - Construct a CharUnits quantity of one.
One()58f4a2713aSLionel Sambuc       static CharUnits One() {
59f4a2713aSLionel Sambuc         return CharUnits(1);
60f4a2713aSLionel Sambuc       }
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
fromQuantity(QuantityType Quantity)63f4a2713aSLionel Sambuc       static CharUnits fromQuantity(QuantityType Quantity) {
64f4a2713aSLionel Sambuc         return CharUnits(Quantity);
65f4a2713aSLionel Sambuc       }
66f4a2713aSLionel Sambuc 
67f4a2713aSLionel Sambuc       // Compound assignment.
68f4a2713aSLionel Sambuc       CharUnits& operator+= (const CharUnits &Other) {
69f4a2713aSLionel Sambuc         Quantity += Other.Quantity;
70f4a2713aSLionel Sambuc         return *this;
71f4a2713aSLionel Sambuc       }
72f4a2713aSLionel Sambuc       CharUnits& operator++ () {
73f4a2713aSLionel Sambuc         ++Quantity;
74f4a2713aSLionel Sambuc         return *this;
75f4a2713aSLionel Sambuc       }
76f4a2713aSLionel Sambuc       CharUnits operator++ (int) {
77f4a2713aSLionel Sambuc         return CharUnits(Quantity++);
78f4a2713aSLionel Sambuc       }
79f4a2713aSLionel Sambuc       CharUnits& operator-= (const CharUnits &Other) {
80f4a2713aSLionel Sambuc         Quantity -= Other.Quantity;
81f4a2713aSLionel Sambuc         return *this;
82f4a2713aSLionel Sambuc       }
83f4a2713aSLionel Sambuc       CharUnits& operator-- () {
84f4a2713aSLionel Sambuc         --Quantity;
85f4a2713aSLionel Sambuc         return *this;
86f4a2713aSLionel Sambuc       }
87f4a2713aSLionel Sambuc       CharUnits operator-- (int) {
88f4a2713aSLionel Sambuc         return CharUnits(Quantity--);
89f4a2713aSLionel Sambuc       }
90f4a2713aSLionel Sambuc 
91f4a2713aSLionel Sambuc       // Comparison operators.
92f4a2713aSLionel Sambuc       bool operator== (const CharUnits &Other) const {
93f4a2713aSLionel Sambuc         return Quantity == Other.Quantity;
94f4a2713aSLionel Sambuc       }
95f4a2713aSLionel Sambuc       bool operator!= (const CharUnits &Other) const {
96f4a2713aSLionel Sambuc         return Quantity != Other.Quantity;
97f4a2713aSLionel Sambuc       }
98f4a2713aSLionel Sambuc 
99f4a2713aSLionel Sambuc       // Relational operators.
100f4a2713aSLionel Sambuc       bool operator<  (const CharUnits &Other) const {
101f4a2713aSLionel Sambuc         return Quantity <  Other.Quantity;
102f4a2713aSLionel Sambuc       }
103f4a2713aSLionel Sambuc       bool operator<= (const CharUnits &Other) const {
104f4a2713aSLionel Sambuc         return Quantity <= Other.Quantity;
105f4a2713aSLionel Sambuc       }
106f4a2713aSLionel Sambuc       bool operator>  (const CharUnits &Other) const {
107f4a2713aSLionel Sambuc         return Quantity >  Other.Quantity;
108f4a2713aSLionel Sambuc       }
109f4a2713aSLionel Sambuc       bool operator>= (const CharUnits &Other) const {
110f4a2713aSLionel Sambuc         return Quantity >= Other.Quantity;
111f4a2713aSLionel Sambuc       }
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc       // Other predicates.
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc       /// isZero - Test whether the quantity equals zero.
isZero()116f4a2713aSLionel Sambuc       bool isZero() const     { return Quantity == 0; }
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc       /// isOne - Test whether the quantity equals one.
isOne()119f4a2713aSLionel Sambuc       bool isOne() const      { return Quantity == 1; }
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc       /// isPositive - Test whether the quantity is greater than zero.
isPositive()122f4a2713aSLionel Sambuc       bool isPositive() const { return Quantity  > 0; }
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc       /// isNegative - Test whether the quantity is less than zero.
isNegative()125f4a2713aSLionel Sambuc       bool isNegative() const { return Quantity  < 0; }
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc       /// isPowerOfTwo - Test whether the quantity is a power of two.
128f4a2713aSLionel Sambuc       /// Zero is not a power of two.
isPowerOfTwo()129f4a2713aSLionel Sambuc       bool isPowerOfTwo() const {
130f4a2713aSLionel Sambuc         return (Quantity & -Quantity) == Quantity;
131f4a2713aSLionel Sambuc       }
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc       // Arithmetic operators.
134f4a2713aSLionel Sambuc       CharUnits operator* (QuantityType N) const {
135f4a2713aSLionel Sambuc         return CharUnits(Quantity * N);
136f4a2713aSLionel Sambuc       }
137f4a2713aSLionel Sambuc       CharUnits operator/ (QuantityType N) const {
138f4a2713aSLionel Sambuc         return CharUnits(Quantity / N);
139f4a2713aSLionel Sambuc       }
140f4a2713aSLionel Sambuc       QuantityType operator/ (const CharUnits &Other) const {
141f4a2713aSLionel Sambuc         return Quantity / Other.Quantity;
142f4a2713aSLionel Sambuc       }
143f4a2713aSLionel Sambuc       CharUnits operator% (QuantityType N) const {
144f4a2713aSLionel Sambuc         return CharUnits(Quantity % N);
145f4a2713aSLionel Sambuc       }
146f4a2713aSLionel Sambuc       QuantityType operator% (const CharUnits &Other) const {
147f4a2713aSLionel Sambuc         return Quantity % Other.Quantity;
148f4a2713aSLionel Sambuc       }
149f4a2713aSLionel Sambuc       CharUnits operator+ (const CharUnits &Other) const {
150f4a2713aSLionel Sambuc         return CharUnits(Quantity + Other.Quantity);
151f4a2713aSLionel Sambuc       }
152f4a2713aSLionel Sambuc       CharUnits operator- (const CharUnits &Other) const {
153f4a2713aSLionel Sambuc         return CharUnits(Quantity - Other.Quantity);
154f4a2713aSLionel Sambuc       }
155f4a2713aSLionel Sambuc       CharUnits operator- () const {
156f4a2713aSLionel Sambuc         return CharUnits(-Quantity);
157f4a2713aSLionel Sambuc       }
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc 
160f4a2713aSLionel Sambuc       // Conversions.
161f4a2713aSLionel Sambuc 
162f4a2713aSLionel Sambuc       /// getQuantity - Get the raw integer representation of this quantity.
getQuantity()163f4a2713aSLionel Sambuc       QuantityType getQuantity() const { return Quantity; }
164f4a2713aSLionel Sambuc 
165f4a2713aSLionel Sambuc       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
166f4a2713aSLionel Sambuc       /// greater than or equal to this quantity and is a multiple of \p Align.
167f4a2713aSLionel Sambuc       /// Align must be non-zero.
RoundUpToAlignment(const CharUnits & Align)168*0a6a1f1dSLionel Sambuc       CharUnits RoundUpToAlignment(const CharUnits &Align) const {
169f4a2713aSLionel Sambuc         return CharUnits(llvm::RoundUpToAlignment(Quantity,
170f4a2713aSLionel Sambuc                                                   Align.Quantity));
171f4a2713aSLionel Sambuc       }
172f4a2713aSLionel Sambuc 
173f4a2713aSLionel Sambuc       /// Given that this is a non-zero alignment value, what is the
174f4a2713aSLionel Sambuc       /// alignment at the given offset?
alignmentAtOffset(CharUnits offset)175f4a2713aSLionel Sambuc       CharUnits alignmentAtOffset(CharUnits offset) {
176*0a6a1f1dSLionel Sambuc         return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
177f4a2713aSLionel Sambuc       }
178f4a2713aSLionel Sambuc 
179f4a2713aSLionel Sambuc 
180f4a2713aSLionel Sambuc   }; // class CharUnit
181f4a2713aSLionel Sambuc } // namespace clang
182f4a2713aSLionel Sambuc 
183f4a2713aSLionel Sambuc inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
184f4a2713aSLionel Sambuc                                    const clang::CharUnits &CU) {
185f4a2713aSLionel Sambuc   return CU * Scale;
186f4a2713aSLionel Sambuc }
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc namespace llvm {
189f4a2713aSLionel Sambuc 
190f4a2713aSLionel Sambuc template<> struct DenseMapInfo<clang::CharUnits> {
191f4a2713aSLionel Sambuc   static clang::CharUnits getEmptyKey() {
192f4a2713aSLionel Sambuc     clang::CharUnits::QuantityType Quantity =
193f4a2713aSLionel Sambuc       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
194f4a2713aSLionel Sambuc 
195f4a2713aSLionel Sambuc     return clang::CharUnits::fromQuantity(Quantity);
196f4a2713aSLionel Sambuc   }
197f4a2713aSLionel Sambuc 
198f4a2713aSLionel Sambuc   static clang::CharUnits getTombstoneKey() {
199f4a2713aSLionel Sambuc     clang::CharUnits::QuantityType Quantity =
200f4a2713aSLionel Sambuc       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
201f4a2713aSLionel Sambuc 
202f4a2713aSLionel Sambuc     return clang::CharUnits::fromQuantity(Quantity);
203f4a2713aSLionel Sambuc   }
204f4a2713aSLionel Sambuc 
205f4a2713aSLionel Sambuc   static unsigned getHashValue(const clang::CharUnits &CU) {
206f4a2713aSLionel Sambuc     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
207f4a2713aSLionel Sambuc     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
208f4a2713aSLionel Sambuc   }
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc   static bool isEqual(const clang::CharUnits &LHS,
211f4a2713aSLionel Sambuc                       const clang::CharUnits &RHS) {
212f4a2713aSLionel Sambuc     return LHS == RHS;
213f4a2713aSLionel Sambuc   }
214f4a2713aSLionel Sambuc };
215f4a2713aSLionel Sambuc 
216f4a2713aSLionel Sambuc template <> struct isPodLike<clang::CharUnits> {
217f4a2713aSLionel Sambuc   static const bool value = true;
218f4a2713aSLionel Sambuc };
219f4a2713aSLionel Sambuc 
220f4a2713aSLionel Sambuc } // end namespace llvm
221f4a2713aSLionel Sambuc 
222f4a2713aSLionel Sambuc #endif // LLVM_CLANG_AST_CHARUNITS_H
223