Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:29

0001 //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the CharUnits class
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_CHARUNITS_H
0014 #define LLVM_CLANG_AST_CHARUNITS_H
0015 
0016 #include "llvm/ADT/DenseMapInfo.h"
0017 #include "llvm/Support/Alignment.h"
0018 #include "llvm/Support/DataTypes.h"
0019 #include "llvm/Support/MathExtras.h"
0020 
0021 namespace clang {
0022 
0023   /// CharUnits - This is an opaque type for sizes expressed in character units.
0024   /// Instances of this type represent a quantity as a multiple of the size
0025   /// of the standard C type, char, on the target architecture. As an opaque
0026   /// type, CharUnits protects you from accidentally combining operations on
0027   /// quantities in bit units and character units.
0028   ///
0029   /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
0030   /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
0031   /// the same quantity of storage. However, we use the term 'character unit'
0032   /// rather than 'byte' to avoid an implication that a character unit is
0033   /// exactly 8 bits.
0034   ///
0035   /// For portability, never assume that a target character is 8 bits wide. Use
0036   /// CharUnit values wherever you calculate sizes, offsets, or alignments
0037   /// in character units.
0038   class CharUnits {
0039     public:
0040       typedef int64_t QuantityType;
0041 
0042     private:
0043       QuantityType Quantity = 0;
0044 
0045       explicit CharUnits(QuantityType C) : Quantity(C) {}
0046 
0047     public:
0048 
0049       /// CharUnits - A default constructor.
0050       CharUnits() = default;
0051 
0052       /// Zero - Construct a CharUnits quantity of zero.
0053       static CharUnits Zero() {
0054         return CharUnits(0);
0055       }
0056 
0057       /// One - Construct a CharUnits quantity of one.
0058       static CharUnits One() {
0059         return CharUnits(1);
0060       }
0061 
0062       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
0063       static CharUnits fromQuantity(QuantityType Quantity) {
0064         return CharUnits(Quantity);
0065       }
0066 
0067       /// fromQuantity - Construct a CharUnits quantity from an llvm::Align
0068       /// quantity.
0069       static CharUnits fromQuantity(llvm::Align Quantity) {
0070         return CharUnits(Quantity.value());
0071       }
0072 
0073       // Compound assignment.
0074       CharUnits& operator+= (const CharUnits &Other) {
0075         Quantity += Other.Quantity;
0076         return *this;
0077       }
0078       CharUnits& operator++ () {
0079         ++Quantity;
0080         return *this;
0081       }
0082       CharUnits operator++ (int) {
0083         return CharUnits(Quantity++);
0084       }
0085       CharUnits& operator-= (const CharUnits &Other) {
0086         Quantity -= Other.Quantity;
0087         return *this;
0088       }
0089       CharUnits& operator-- () {
0090         --Quantity;
0091         return *this;
0092       }
0093       CharUnits operator-- (int) {
0094         return CharUnits(Quantity--);
0095       }
0096 
0097       // Comparison operators.
0098       bool operator== (const CharUnits &Other) const {
0099         return Quantity == Other.Quantity;
0100       }
0101       bool operator!= (const CharUnits &Other) const {
0102         return Quantity != Other.Quantity;
0103       }
0104 
0105       // Relational operators.
0106       bool operator<  (const CharUnits &Other) const {
0107         return Quantity <  Other.Quantity;
0108       }
0109       bool operator<= (const CharUnits &Other) const {
0110         return Quantity <= Other.Quantity;
0111       }
0112       bool operator>  (const CharUnits &Other) const {
0113         return Quantity >  Other.Quantity;
0114       }
0115       bool operator>= (const CharUnits &Other) const {
0116         return Quantity >= Other.Quantity;
0117       }
0118 
0119       // Other predicates.
0120 
0121       /// isZero - Test whether the quantity equals zero.
0122       bool isZero() const     { return Quantity == 0; }
0123 
0124       /// isOne - Test whether the quantity equals one.
0125       bool isOne() const      { return Quantity == 1; }
0126 
0127       /// isPositive - Test whether the quantity is greater than zero.
0128       bool isPositive() const { return Quantity  > 0; }
0129 
0130       /// isNegative - Test whether the quantity is less than zero.
0131       bool isNegative() const { return Quantity  < 0; }
0132 
0133       /// isPowerOfTwo - Test whether the quantity is a power of two.
0134       /// Zero is not a power of two.
0135       bool isPowerOfTwo() const {
0136         return (Quantity & -Quantity) == Quantity;
0137       }
0138 
0139       /// Test whether this is a multiple of the other value.
0140       ///
0141       /// Among other things, this promises that
0142       /// self.alignTo(N) will just return self.
0143       bool isMultipleOf(CharUnits N) const {
0144         return (*this % N) == 0;
0145       }
0146 
0147       // Arithmetic operators.
0148       CharUnits operator* (QuantityType N) const {
0149         return CharUnits(Quantity * N);
0150       }
0151       CharUnits &operator*= (QuantityType N) {
0152         Quantity *= N;
0153         return *this;
0154       }
0155       CharUnits operator/ (QuantityType N) const {
0156         return CharUnits(Quantity / N);
0157       }
0158       CharUnits &operator/= (QuantityType N) {
0159         Quantity /= N;
0160         return *this;
0161       }
0162       QuantityType operator/ (const CharUnits &Other) const {
0163         return Quantity / Other.Quantity;
0164       }
0165       CharUnits operator% (QuantityType N) const {
0166         return CharUnits(Quantity % N);
0167       }
0168       QuantityType operator% (const CharUnits &Other) const {
0169         return Quantity % Other.Quantity;
0170       }
0171       CharUnits operator+ (const CharUnits &Other) const {
0172         return CharUnits(Quantity + Other.Quantity);
0173       }
0174       CharUnits operator- (const CharUnits &Other) const {
0175         return CharUnits(Quantity - Other.Quantity);
0176       }
0177       CharUnits operator- () const {
0178         return CharUnits(-Quantity);
0179       }
0180 
0181 
0182       // Conversions.
0183 
0184       /// getQuantity - Get the raw integer representation of this quantity.
0185       QuantityType getQuantity() const { return Quantity; }
0186 
0187       /// getAsAlign - Returns Quantity as a valid llvm::Align,
0188       /// Beware llvm::Align assumes power of two 8-bit bytes.
0189       llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
0190 
0191       /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or
0192       /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit
0193       /// bytes.
0194       llvm::MaybeAlign getAsMaybeAlign() const {
0195         return llvm::MaybeAlign(Quantity);
0196       }
0197 
0198       /// alignTo - Returns the next integer (mod 2**64) that is
0199       /// greater than or equal to this quantity and is a multiple of \p Align.
0200       /// Align must be non-zero.
0201       CharUnits alignTo(const CharUnits &Align) const {
0202         return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
0203       }
0204 
0205       /// Given that this is a non-zero alignment value, what is the
0206       /// alignment at the given offset?
0207       CharUnits alignmentAtOffset(CharUnits offset) const {
0208         assert(Quantity != 0 && "offsetting from unknown alignment?");
0209         return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
0210       }
0211 
0212       /// Given that this is the alignment of the first element of an
0213       /// array, return the minimum alignment of any element in the array.
0214       CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
0215         // Since we don't track offsetted alignments, the alignment of
0216         // the second element (or any odd element) will be minimally
0217         // aligned.
0218         return alignmentAtOffset(elementSize);
0219       }
0220 
0221 
0222   }; // class CharUnit
0223 } // namespace clang
0224 
0225 inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
0226                                    const clang::CharUnits &CU) {
0227   return CU * Scale;
0228 }
0229 
0230 namespace llvm {
0231 
0232 template<> struct DenseMapInfo<clang::CharUnits> {
0233   static clang::CharUnits getEmptyKey() {
0234     clang::CharUnits::QuantityType Quantity =
0235       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
0236 
0237     return clang::CharUnits::fromQuantity(Quantity);
0238   }
0239 
0240   static clang::CharUnits getTombstoneKey() {
0241     clang::CharUnits::QuantityType Quantity =
0242       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
0243 
0244     return clang::CharUnits::fromQuantity(Quantity);
0245   }
0246 
0247   static unsigned getHashValue(const clang::CharUnits &CU) {
0248     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
0249     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
0250   }
0251 
0252   static bool isEqual(const clang::CharUnits &LHS,
0253                       const clang::CharUnits &RHS) {
0254     return LHS == RHS;
0255   }
0256 };
0257 
0258 } // end namespace llvm
0259 
0260 #endif // LLVM_CLANG_AST_CHARUNITS_H