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