123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the CharUnits class
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_CHARUNITS_H
- #define LLVM_CLANG_AST_CHARUNITS_H
- #include "llvm/ADT/DenseMapInfo.h"
- #include "llvm/Support/Alignment.h"
- #include "llvm/Support/DataTypes.h"
- #include "llvm/Support/MathExtras.h"
- namespace clang {
- /// CharUnits - This is an opaque type for sizes expressed in character units.
- /// Instances of this type represent a quantity as a multiple of the size
- /// of the standard C type, char, on the target architecture. As an opaque
- /// type, CharUnits protects you from accidentally combining operations on
- /// quantities in bit units and character units.
- ///
- /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
- /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
- /// the same quantity of storage. However, we use the term 'character unit'
- /// rather than 'byte' to avoid an implication that a character unit is
- /// exactly 8 bits.
- ///
- /// For portability, never assume that a target character is 8 bits wide. Use
- /// CharUnit values wherever you calculate sizes, offsets, or alignments
- /// in character units.
- class CharUnits {
- public:
- typedef int64_t QuantityType;
- private:
- QuantityType Quantity = 0;
- explicit CharUnits(QuantityType C) : Quantity(C) {}
- public:
- /// CharUnits - A default constructor.
- CharUnits() = default;
- /// Zero - Construct a CharUnits quantity of zero.
- static CharUnits Zero() {
- return CharUnits(0);
- }
- /// One - Construct a CharUnits quantity of one.
- static CharUnits One() {
- return CharUnits(1);
- }
- /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
- static CharUnits fromQuantity(QuantityType Quantity) {
- return CharUnits(Quantity);
- }
- // Compound assignment.
- CharUnits& operator+= (const CharUnits &Other) {
- Quantity += Other.Quantity;
- return *this;
- }
- CharUnits& operator++ () {
- ++Quantity;
- return *this;
- }
- CharUnits operator++ (int) {
- return CharUnits(Quantity++);
- }
- CharUnits& operator-= (const CharUnits &Other) {
- Quantity -= Other.Quantity;
- return *this;
- }
- CharUnits& operator-- () {
- --Quantity;
- return *this;
- }
- CharUnits operator-- (int) {
- return CharUnits(Quantity--);
- }
- // Comparison operators.
- bool operator== (const CharUnits &Other) const {
- return Quantity == Other.Quantity;
- }
- bool operator!= (const CharUnits &Other) const {
- return Quantity != Other.Quantity;
- }
- // Relational operators.
- bool operator< (const CharUnits &Other) const {
- return Quantity < Other.Quantity;
- }
- bool operator<= (const CharUnits &Other) const {
- return Quantity <= Other.Quantity;
- }
- bool operator> (const CharUnits &Other) const {
- return Quantity > Other.Quantity;
- }
- bool operator>= (const CharUnits &Other) const {
- return Quantity >= Other.Quantity;
- }
- // Other predicates.
- /// isZero - Test whether the quantity equals zero.
- bool isZero() const { return Quantity == 0; }
- /// isOne - Test whether the quantity equals one.
- bool isOne() const { return Quantity == 1; }
- /// isPositive - Test whether the quantity is greater than zero.
- bool isPositive() const { return Quantity > 0; }
- /// isNegative - Test whether the quantity is less than zero.
- bool isNegative() const { return Quantity < 0; }
- /// isPowerOfTwo - Test whether the quantity is a power of two.
- /// Zero is not a power of two.
- bool isPowerOfTwo() const {
- return (Quantity & -Quantity) == Quantity;
- }
- /// Test whether this is a multiple of the other value.
- ///
- /// Among other things, this promises that
- /// self.alignTo(N) will just return self.
- bool isMultipleOf(CharUnits N) const {
- return (*this % N) == 0;
- }
- // Arithmetic operators.
- CharUnits operator* (QuantityType N) const {
- return CharUnits(Quantity * N);
- }
- CharUnits &operator*= (QuantityType N) {
- Quantity *= N;
- return *this;
- }
- CharUnits operator/ (QuantityType N) const {
- return CharUnits(Quantity / N);
- }
- CharUnits &operator/= (QuantityType N) {
- Quantity /= N;
- return *this;
- }
- QuantityType operator/ (const CharUnits &Other) const {
- return Quantity / Other.Quantity;
- }
- CharUnits operator% (QuantityType N) const {
- return CharUnits(Quantity % N);
- }
- QuantityType operator% (const CharUnits &Other) const {
- return Quantity % Other.Quantity;
- }
- CharUnits operator+ (const CharUnits &Other) const {
- return CharUnits(Quantity + Other.Quantity);
- }
- CharUnits operator- (const CharUnits &Other) const {
- return CharUnits(Quantity - Other.Quantity);
- }
- CharUnits operator- () const {
- return CharUnits(-Quantity);
- }
- // Conversions.
- /// getQuantity - Get the raw integer representation of this quantity.
- QuantityType getQuantity() const { return Quantity; }
- /// getAsAlign - Returns Quantity as a valid llvm::Align,
- /// Beware llvm::Align assumes power of two 8-bit bytes.
- llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
- /// alignTo - Returns the next integer (mod 2**64) that is
- /// greater than or equal to this quantity and is a multiple of \p Align.
- /// Align must be non-zero.
- CharUnits alignTo(const CharUnits &Align) const {
- return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
- }
- /// Given that this is a non-zero alignment value, what is the
- /// alignment at the given offset?
- CharUnits alignmentAtOffset(CharUnits offset) const {
- assert(Quantity != 0 && "offsetting from unknown alignment?");
- return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
- }
- /// Given that this is the alignment of the first element of an
- /// array, return the minimum alignment of any element in the array.
- CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
- // Since we don't track offsetted alignments, the alignment of
- // the second element (or any odd element) will be minimally
- // aligned.
- return alignmentAtOffset(elementSize);
- }
- }; // class CharUnit
- } // namespace clang
- inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
- const clang::CharUnits &CU) {
- return CU * Scale;
- }
- namespace llvm {
- template<> struct DenseMapInfo<clang::CharUnits> {
- static clang::CharUnits getEmptyKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
- return clang::CharUnits::fromQuantity(Quantity);
- }
- static clang::CharUnits getTombstoneKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
- return clang::CharUnits::fromQuantity(Quantity);
- }
- static unsigned getHashValue(const clang::CharUnits &CU) {
- clang::CharUnits::QuantityType Quantity = CU.getQuantity();
- return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
- }
- static bool isEqual(const clang::CharUnits &LHS,
- const clang::CharUnits &RHS) {
- return LHS == RHS;
- }
- };
- } // end namespace llvm
- #endif // LLVM_CLANG_AST_CHARUNITS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|