164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===// 264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// 364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// The LLVM Compiler Infrastructure 464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// 564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// This file is distributed under the University of Illinois Open Source 664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// License. See LICENSE.TXT for details. 764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// 864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck//===----------------------------------------------------------------------===// 964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// 1064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// This file defines the CharUnits class 1164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck// 1264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck//===----------------------------------------------------------------------===// 1364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 1464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck#ifndef LLVM_CLANG_AST_CHARUNITS_H 1564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck#define LLVM_CLANG_AST_CHARUNITS_H 1664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 1794ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson#include "llvm/ADT/DenseMapInfo.h" 1803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h" 193dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck#include "llvm/Support/MathExtras.h" 2064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 2164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dycknamespace clang { 227e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith 23c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// CharUnits - This is an opaque type for sizes expressed in character units. 247e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// Instances of this type represent a quantity as a multiple of the size 25c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// of the standard C type, char, on the target architecture. As an opaque 26c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// type, CharUnits protects you from accidentally combining operations on 277e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// quantities in bit units and character units. 287e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// 297e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned 307e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to 317e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// the same quantity of storage. However, we use the term 'character unit' 327e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// rather than 'byte' to avoid an implication that a character unit is 337e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// exactly 8 bits. 34c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// 357e17fdc617ee9db8270f3f6fb4ecd392fed47d80Richard Smith /// For portability, never assume that a target character is 8 bits wide. Use 36fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner /// CharUnit values wherever you calculate sizes, offsets, or alignments 37c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// in character units. 3864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck class CharUnits { 3964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck public: 40199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck typedef int64_t QuantityType; 4164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 4264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck private: 43199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck QuantityType Quantity; 4464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 45199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck explicit CharUnits(QuantityType C) : Quantity(C) {} 4664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 4764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck public: 4864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 49c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// CharUnits - A default constructor. 5064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck CharUnits() : Quantity(0) {} 5164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 52c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// Zero - Construct a CharUnits quantity of zero. 5364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck static CharUnits Zero() { 5464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(0); 5564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 5664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 57c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck /// One - Construct a CharUnits quantity of one. 5864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck static CharUnits One() { 5964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(1); 6064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 6164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 62199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck /// fromQuantity - Construct a CharUnits quantity from a raw integer type. 63199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck static CharUnits fromQuantity(QuantityType Quantity) { 6464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity); 6564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 6664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 67c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Compound assignment. 6864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck CharUnits& operator+= (const CharUnits &Other) { 6964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck Quantity += Other.Quantity; 7064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return *this; 7164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 72f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck CharUnits& operator++ () { 73f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck ++Quantity; 74f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck return *this; 75f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck } 76f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck CharUnits operator++ (int) { 77f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck return CharUnits(Quantity++); 78f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck } 7964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck CharUnits& operator-= (const CharUnits &Other) { 8064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck Quantity -= Other.Quantity; 8164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return *this; 8264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 83f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck CharUnits& operator-- () { 84f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck --Quantity; 85f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck return *this; 86f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck } 87f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck CharUnits operator-- (int) { 88f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck return CharUnits(Quantity--); 89f899af662801ee6bb82be871eb0b8d19b61503baKen Dyck } 9064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 91c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Comparison operators. 9264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator== (const CharUnits &Other) const { 9364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity == Other.Quantity; 9464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 9564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator!= (const CharUnits &Other) const { 9664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity != Other.Quantity; 9764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 9864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 99c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Relational operators. 10064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator< (const CharUnits &Other) const { 10164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity < Other.Quantity; 10264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 10364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator<= (const CharUnits &Other) const { 10464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity <= Other.Quantity; 10564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 10664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator> (const CharUnits &Other) const { 10764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity > Other.Quantity; 10864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 10964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool operator>= (const CharUnits &Other) const { 11064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity >= Other.Quantity; 11164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 11264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 113c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Other predicates. 11464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 11564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck /// isZero - Test whether the quantity equals zero. 11664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool isZero() const { return Quantity == 0; } 11764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 11864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck /// isOne - Test whether the quantity equals one. 11964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool isOne() const { return Quantity == 1; } 12064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 121199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck /// isPositive - Test whether the quantity is greater than zero. 12264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool isPositive() const { return Quantity > 0; } 12364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 12464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck /// isNegative - Test whether the quantity is less than zero. 12564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck bool isNegative() const { return Quantity < 0; } 12664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 127c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall /// isPowerOfTwo - Test whether the quantity is a power of two. 128c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall /// Zero is not a power of two. 129c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall bool isPowerOfTwo() const { 130c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall return (Quantity & -Quantity) == Quantity; 131c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall } 132c5d9a90b3a3c16324e0cceeccec3d2993888deb6John McCall 133c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Arithmetic operators. 134199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits operator* (QuantityType N) const { 13564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity * N); 13664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 137199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits operator/ (QuantityType N) const { 13864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity / N); 13964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 140199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck QuantityType operator/ (const CharUnits &Other) const { 14164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity / Other.Quantity; 14264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 143199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits operator% (QuantityType N) const { 14464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity % N); 14564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 146199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck QuantityType operator% (const CharUnits &Other) const { 14764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return Quantity % Other.Quantity; 14864437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 14964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck CharUnits operator+ (const CharUnits &Other) const { 15064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity + Other.Quantity); 15164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 15264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck CharUnits operator- (const CharUnits &Other) const { 15364437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CharUnits(Quantity - Other.Quantity); 15464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck } 15569fc1b330090853ced40436805258fc9a0a70bdcKen Dyck CharUnits operator- () const { 15669fc1b330090853ced40436805258fc9a0a70bdcKen Dyck return CharUnits(-Quantity); 15769fc1b330090853ced40436805258fc9a0a70bdcKen Dyck } 15869fc1b330090853ced40436805258fc9a0a70bdcKen Dyck 15964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 160c3c90b25cf321d851314f0f19f67e9a00df0da0dKen Dyck // Conversions. 16164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 162199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck /// getQuantity - Get the raw integer representation of this quantity. 163199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck QuantityType getQuantity() const { return Quantity; } 16464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 1653dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is 1661824d54df85a462ada812dadda18130f951d40f3Dmitri Gribenko /// greater than or equal to this quantity and is a multiple of \p Align. 1671824d54df85a462ada812dadda18130f951d40f3Dmitri Gribenko /// Align must be non-zero. 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits RoundUpToAlignment(const CharUnits &Align) const { 1693dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck return CharUnits(llvm::RoundUpToAlignment(Quantity, 1703dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck Align.Quantity)); 1713dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck } 1723dbdb58e2e920ad69fecbd56c25b58577ab693e8Ken Dyck 173372fe788f8ea815071d0ddffe46dd3abc397106eJohn McCall /// Given that this is a non-zero alignment value, what is the 174372fe788f8ea815071d0ddffe46dd3abc397106eJohn McCall /// alignment at the given offset? 175372fe788f8ea815071d0ddffe46dd3abc397106eJohn McCall CharUnits alignmentAtOffset(CharUnits offset) { 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); 177372fe788f8ea815071d0ddffe46dd3abc397106eJohn McCall } 178372fe788f8ea815071d0ddffe46dd3abc397106eJohn McCall 17964437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 18064437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck }; // class CharUnit 18164437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck} // namespace clang 18264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 183199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyckinline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 18464437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck const clang::CharUnits &CU) { 18564437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck return CU * Scale; 18664437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck} 18764437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck 18894ac122610ec875760c4b41e7376b79223a0de20Anders Carlssonnamespace llvm { 18994ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 19094ac122610ec875760c4b41e7376b79223a0de20Anders Carlssontemplate<> struct DenseMapInfo<clang::CharUnits> { 19194ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson static clang::CharUnits getEmptyKey() { 19294ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson clang::CharUnits::QuantityType Quantity = 19394ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey(); 19494ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 19594ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson return clang::CharUnits::fromQuantity(Quantity); 19694ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson } 19794ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 19894ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson static clang::CharUnits getTombstoneKey() { 19994ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson clang::CharUnits::QuantityType Quantity = 20094ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey(); 20194ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 20294ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson return clang::CharUnits::fromQuantity(Quantity); 20394ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson } 20494ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 20594ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson static unsigned getHashValue(const clang::CharUnits &CU) { 20694ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson clang::CharUnits::QuantityType Quantity = CU.getQuantity(); 20794ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity); 20894ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson } 20994ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 21094ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson static bool isEqual(const clang::CharUnits &LHS, 21194ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson const clang::CharUnits &RHS) { 21294ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson return LHS == RHS; 21394ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson } 21494ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson}; 21594ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 21694ac122610ec875760c4b41e7376b79223a0de20Anders Carlssontemplate <> struct isPodLike<clang::CharUnits> { 21794ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson static const bool value = true; 21894ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson}; 21994ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 22094ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson} // end namespace llvm 22194ac122610ec875760c4b41e7376b79223a0de20Anders Carlsson 22264437137888d69b8ef03f3057524e5056e7d9dd6Ken Dyck#endif // LLVM_CLANG_AST_CHARUNITS_H 223