Home | History | Annotate | Download | only in AST
      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 
     46       explicit CharUnits(QuantityType C) : Quantity(C) {}
     47 
     48     public:
     49 
     50       /// CharUnits - A default constructor.
     51       CharUnits() : Quantity(0) {}
     52 
     53       /// Zero - Construct a CharUnits quantity of zero.
     54       static CharUnits Zero() {
     55         return CharUnits(0);
     56       }
     57 
     58       /// One - Construct a CharUnits quantity of one.
     59       static CharUnits One() {
     60         return CharUnits(1);
     61       }
     62 
     63       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
     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.
    117       bool isZero() const     { return Quantity == 0; }
    118 
    119       /// isOne - Test whether the quantity equals one.
    120       bool isOne() const      { return Quantity == 1; }
    121 
    122       /// isPositive - Test whether the quantity is greater than zero.
    123       bool isPositive() const { return Quantity  > 0; }
    124 
    125       /// isNegative - Test whether the quantity is less than zero.
    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.
    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.
    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.
    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?
    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