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