Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines the CharUnits class
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_AST_CHARUNITS_H
  14. #define LLVM_CLANG_AST_CHARUNITS_H
  15.  
  16. #include "llvm/ADT/DenseMapInfo.h"
  17. #include "llvm/Support/Alignment.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 = 0;
  44.  
  45.       explicit CharUnits(QuantityType C) : Quantity(C) {}
  46.  
  47.     public:
  48.  
  49.       /// CharUnits - A default constructor.
  50.       CharUnits() = default;
  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.       /// fromQuantity - Construct a CharUnits quantity from an llvm::Align
  68.       /// quantity.
  69.       static CharUnits fromQuantity(llvm::Align Quantity) {
  70.         return CharUnits(Quantity.value());
  71.       }
  72.  
  73.       // Compound assignment.
  74.       CharUnits& operator+= (const CharUnits &Other) {
  75.         Quantity += Other.Quantity;
  76.         return *this;
  77.       }
  78.       CharUnits& operator++ () {
  79.         ++Quantity;
  80.         return *this;
  81.       }
  82.       CharUnits operator++ (int) {
  83.         return CharUnits(Quantity++);
  84.       }
  85.       CharUnits& operator-= (const CharUnits &Other) {
  86.         Quantity -= Other.Quantity;
  87.         return *this;
  88.       }
  89.       CharUnits& operator-- () {
  90.         --Quantity;
  91.         return *this;
  92.       }
  93.       CharUnits operator-- (int) {
  94.         return CharUnits(Quantity--);
  95.       }
  96.  
  97.       // Comparison operators.
  98.       bool operator== (const CharUnits &Other) const {
  99.         return Quantity == Other.Quantity;
  100.       }
  101.       bool operator!= (const CharUnits &Other) const {
  102.         return Quantity != Other.Quantity;
  103.       }
  104.  
  105.       // Relational operators.
  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.       bool operator>  (const CharUnits &Other) const {
  113.         return Quantity >  Other.Quantity;
  114.       }
  115.       bool operator>= (const CharUnits &Other) const {
  116.         return Quantity >= Other.Quantity;
  117.       }
  118.  
  119.       // Other predicates.
  120.  
  121.       /// isZero - Test whether the quantity equals zero.
  122.       bool isZero() const     { return Quantity == 0; }
  123.  
  124.       /// isOne - Test whether the quantity equals one.
  125.       bool isOne() const      { return Quantity == 1; }
  126.  
  127.       /// isPositive - Test whether the quantity is greater than zero.
  128.       bool isPositive() const { return Quantity  > 0; }
  129.  
  130.       /// isNegative - Test whether the quantity is less than zero.
  131.       bool isNegative() const { return Quantity  < 0; }
  132.  
  133.       /// isPowerOfTwo - Test whether the quantity is a power of two.
  134.       /// Zero is not a power of two.
  135.       bool isPowerOfTwo() const {
  136.         return (Quantity & -Quantity) == Quantity;
  137.       }
  138.  
  139.       /// Test whether this is a multiple of the other value.
  140.       ///
  141.       /// Among other things, this promises that
  142.       /// self.alignTo(N) will just return self.
  143.       bool isMultipleOf(CharUnits N) const {
  144.         return (*this % N) == 0;
  145.       }
  146.  
  147.       // Arithmetic operators.
  148.       CharUnits operator* (QuantityType N) const {
  149.         return CharUnits(Quantity * N);
  150.       }
  151.       CharUnits &operator*= (QuantityType N) {
  152.         Quantity *= N;
  153.         return *this;
  154.       }
  155.       CharUnits operator/ (QuantityType N) const {
  156.         return CharUnits(Quantity / N);
  157.       }
  158.       CharUnits &operator/= (QuantityType N) {
  159.         Quantity /= N;
  160.         return *this;
  161.       }
  162.       QuantityType operator/ (const CharUnits &Other) const {
  163.         return Quantity / Other.Quantity;
  164.       }
  165.       CharUnits operator% (QuantityType N) const {
  166.         return CharUnits(Quantity % N);
  167.       }
  168.       QuantityType operator% (const CharUnits &Other) const {
  169.         return Quantity % Other.Quantity;
  170.       }
  171.       CharUnits operator+ (const CharUnits &Other) const {
  172.         return CharUnits(Quantity + Other.Quantity);
  173.       }
  174.       CharUnits operator- (const CharUnits &Other) const {
  175.         return CharUnits(Quantity - Other.Quantity);
  176.       }
  177.       CharUnits operator- () const {
  178.         return CharUnits(-Quantity);
  179.       }
  180.  
  181.  
  182.       // Conversions.
  183.  
  184.       /// getQuantity - Get the raw integer representation of this quantity.
  185.       QuantityType getQuantity() const { return Quantity; }
  186.  
  187.       /// getAsAlign - Returns Quantity as a valid llvm::Align,
  188.       /// Beware llvm::Align assumes power of two 8-bit bytes.
  189.       llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
  190.  
  191.       /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or
  192.       /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit
  193.       /// bytes.
  194.       llvm::MaybeAlign getAsMaybeAlign() const {
  195.         return llvm::MaybeAlign(Quantity);
  196.       }
  197.  
  198.       /// alignTo - Returns the next integer (mod 2**64) that is
  199.       /// greater than or equal to this quantity and is a multiple of \p Align.
  200.       /// Align must be non-zero.
  201.       CharUnits alignTo(const CharUnits &Align) const {
  202.         return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
  203.       }
  204.  
  205.       /// Given that this is a non-zero alignment value, what is the
  206.       /// alignment at the given offset?
  207.       CharUnits alignmentAtOffset(CharUnits offset) const {
  208.         assert(Quantity != 0 && "offsetting from unknown alignment?");
  209.         return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
  210.       }
  211.  
  212.       /// Given that this is the alignment of the first element of an
  213.       /// array, return the minimum alignment of any element in the array.
  214.       CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
  215.         // Since we don't track offsetted alignments, the alignment of
  216.         // the second element (or any odd element) will be minimally
  217.         // aligned.
  218.         return alignmentAtOffset(elementSize);
  219.       }
  220.  
  221.  
  222.   }; // class CharUnit
  223. } // namespace clang
  224.  
  225. inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
  226.                                    const clang::CharUnits &CU) {
  227.   return CU * Scale;
  228. }
  229.  
  230. namespace llvm {
  231.  
  232. template<> struct DenseMapInfo<clang::CharUnits> {
  233.   static clang::CharUnits getEmptyKey() {
  234.     clang::CharUnits::QuantityType Quantity =
  235.       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
  236.  
  237.     return clang::CharUnits::fromQuantity(Quantity);
  238.   }
  239.  
  240.   static clang::CharUnits getTombstoneKey() {
  241.     clang::CharUnits::QuantityType Quantity =
  242.       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
  243.  
  244.     return clang::CharUnits::fromQuantity(Quantity);
  245.   }
  246.  
  247.   static unsigned getHashValue(const clang::CharUnits &CU) {
  248.     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
  249.     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
  250.   }
  251.  
  252.   static bool isEqual(const clang::CharUnits &LHS,
  253.                       const clang::CharUnits &RHS) {
  254.     return LHS == RHS;
  255.   }
  256. };
  257.  
  258. } // end namespace llvm
  259.  
  260. #endif // LLVM_CLANG_AST_CHARUNITS_H
  261.