CharUnits.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the CharUnits class
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_AST_CHARUNITS_H
  18. #define LLVM_CLANG_AST_CHARUNITS_H
  19. #include "llvm/ADT/DenseMapInfo.h"
  20. #include "llvm/Support/Alignment.h"
  21. #include "llvm/Support/DataTypes.h"
  22. #include "llvm/Support/MathExtras.h"
  23. namespace clang {
  24. /// CharUnits - This is an opaque type for sizes expressed in character units.
  25. /// Instances of this type represent a quantity as a multiple of the size
  26. /// of the standard C type, char, on the target architecture. As an opaque
  27. /// type, CharUnits protects you from accidentally combining operations on
  28. /// quantities in bit units and character units.
  29. ///
  30. /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
  31. /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
  32. /// the same quantity of storage. However, we use the term 'character unit'
  33. /// rather than 'byte' to avoid an implication that a character unit is
  34. /// exactly 8 bits.
  35. ///
  36. /// For portability, never assume that a target character is 8 bits wide. Use
  37. /// CharUnit values wherever you calculate sizes, offsets, or alignments
  38. /// in character units.
  39. class CharUnits {
  40. public:
  41. typedef int64_t QuantityType;
  42. private:
  43. QuantityType Quantity = 0;
  44. explicit CharUnits(QuantityType C) : Quantity(C) {}
  45. public:
  46. /// CharUnits - A default constructor.
  47. CharUnits() = default;
  48. /// Zero - Construct a CharUnits quantity of zero.
  49. static CharUnits Zero() {
  50. return CharUnits(0);
  51. }
  52. /// One - Construct a CharUnits quantity of one.
  53. static CharUnits One() {
  54. return CharUnits(1);
  55. }
  56. /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
  57. static CharUnits fromQuantity(QuantityType Quantity) {
  58. return CharUnits(Quantity);
  59. }
  60. // Compound assignment.
  61. CharUnits& operator+= (const CharUnits &Other) {
  62. Quantity += Other.Quantity;
  63. return *this;
  64. }
  65. CharUnits& operator++ () {
  66. ++Quantity;
  67. return *this;
  68. }
  69. CharUnits operator++ (int) {
  70. return CharUnits(Quantity++);
  71. }
  72. CharUnits& operator-= (const CharUnits &Other) {
  73. Quantity -= Other.Quantity;
  74. return *this;
  75. }
  76. CharUnits& operator-- () {
  77. --Quantity;
  78. return *this;
  79. }
  80. CharUnits operator-- (int) {
  81. return CharUnits(Quantity--);
  82. }
  83. // Comparison operators.
  84. bool operator== (const CharUnits &Other) const {
  85. return Quantity == Other.Quantity;
  86. }
  87. bool operator!= (const CharUnits &Other) const {
  88. return Quantity != Other.Quantity;
  89. }
  90. // Relational operators.
  91. bool operator< (const CharUnits &Other) const {
  92. return Quantity < Other.Quantity;
  93. }
  94. bool operator<= (const CharUnits &Other) const {
  95. return Quantity <= Other.Quantity;
  96. }
  97. bool operator> (const CharUnits &Other) const {
  98. return Quantity > Other.Quantity;
  99. }
  100. bool operator>= (const CharUnits &Other) const {
  101. return Quantity >= Other.Quantity;
  102. }
  103. // Other predicates.
  104. /// isZero - Test whether the quantity equals zero.
  105. bool isZero() const { return Quantity == 0; }
  106. /// isOne - Test whether the quantity equals one.
  107. bool isOne() const { return Quantity == 1; }
  108. /// isPositive - Test whether the quantity is greater than zero.
  109. bool isPositive() const { return Quantity > 0; }
  110. /// isNegative - Test whether the quantity is less than zero.
  111. bool isNegative() const { return Quantity < 0; }
  112. /// isPowerOfTwo - Test whether the quantity is a power of two.
  113. /// Zero is not a power of two.
  114. bool isPowerOfTwo() const {
  115. return (Quantity & -Quantity) == Quantity;
  116. }
  117. /// Test whether this is a multiple of the other value.
  118. ///
  119. /// Among other things, this promises that
  120. /// self.alignTo(N) will just return self.
  121. bool isMultipleOf(CharUnits N) const {
  122. return (*this % N) == 0;
  123. }
  124. // Arithmetic operators.
  125. CharUnits operator* (QuantityType N) const {
  126. return CharUnits(Quantity * N);
  127. }
  128. CharUnits &operator*= (QuantityType N) {
  129. Quantity *= N;
  130. return *this;
  131. }
  132. CharUnits operator/ (QuantityType N) const {
  133. return CharUnits(Quantity / N);
  134. }
  135. CharUnits &operator/= (QuantityType N) {
  136. Quantity /= N;
  137. return *this;
  138. }
  139. QuantityType operator/ (const CharUnits &Other) const {
  140. return Quantity / Other.Quantity;
  141. }
  142. CharUnits operator% (QuantityType N) const {
  143. return CharUnits(Quantity % N);
  144. }
  145. QuantityType operator% (const CharUnits &Other) const {
  146. return Quantity % Other.Quantity;
  147. }
  148. CharUnits operator+ (const CharUnits &Other) const {
  149. return CharUnits(Quantity + Other.Quantity);
  150. }
  151. CharUnits operator- (const CharUnits &Other) const {
  152. return CharUnits(Quantity - Other.Quantity);
  153. }
  154. CharUnits operator- () const {
  155. return CharUnits(-Quantity);
  156. }
  157. // Conversions.
  158. /// getQuantity - Get the raw integer representation of this quantity.
  159. QuantityType getQuantity() const { return Quantity; }
  160. /// getAsAlign - Returns Quantity as a valid llvm::Align,
  161. /// Beware llvm::Align assumes power of two 8-bit bytes.
  162. llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
  163. /// alignTo - Returns the next integer (mod 2**64) that is
  164. /// greater than or equal to this quantity and is a multiple of \p Align.
  165. /// Align must be non-zero.
  166. CharUnits alignTo(const CharUnits &Align) const {
  167. return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
  168. }
  169. /// Given that this is a non-zero alignment value, what is the
  170. /// alignment at the given offset?
  171. CharUnits alignmentAtOffset(CharUnits offset) const {
  172. assert(Quantity != 0 && "offsetting from unknown alignment?");
  173. return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
  174. }
  175. /// Given that this is the alignment of the first element of an
  176. /// array, return the minimum alignment of any element in the array.
  177. CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
  178. // Since we don't track offsetted alignments, the alignment of
  179. // the second element (or any odd element) will be minimally
  180. // aligned.
  181. return alignmentAtOffset(elementSize);
  182. }
  183. }; // class CharUnit
  184. } // namespace clang
  185. inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
  186. const clang::CharUnits &CU) {
  187. return CU * Scale;
  188. }
  189. namespace llvm {
  190. template<> struct DenseMapInfo<clang::CharUnits> {
  191. static clang::CharUnits getEmptyKey() {
  192. clang::CharUnits::QuantityType Quantity =
  193. DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
  194. return clang::CharUnits::fromQuantity(Quantity);
  195. }
  196. static clang::CharUnits getTombstoneKey() {
  197. clang::CharUnits::QuantityType Quantity =
  198. DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
  199. return clang::CharUnits::fromQuantity(Quantity);
  200. }
  201. static unsigned getHashValue(const clang::CharUnits &CU) {
  202. clang::CharUnits::QuantityType Quantity = CU.getQuantity();
  203. return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
  204. }
  205. static bool isEqual(const clang::CharUnits &LHS,
  206. const clang::CharUnits &RHS) {
  207. return LHS == RHS;
  208. }
  209. };
  210. } // end namespace llvm
  211. #endif // LLVM_CLANG_AST_CHARUNITS_H
  212. #ifdef __GNUC__
  213. #pragma GCC diagnostic pop
  214. #endif