APSInt.h revision 193323
1//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the APSInt class, which is a simple class that
11// represents an arbitrary sized integer that knows its signedness.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_APSINT_H
16#define LLVM_APSINT_H
17
18#include "llvm/ADT/APInt.h"
19
20namespace llvm {
21
22class APSInt : public APInt {
23  bool IsUnsigned;
24public:
25  /// Default constructor that creates an uninitialized APInt.
26  explicit APSInt() {}
27
28  /// APSInt ctor - Create an APSInt with the specified width, default to
29  /// unsigned.
30  explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
31   : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
32
33  explicit APSInt(const APInt &I, bool isUnsigned = true)
34   : APInt(I), IsUnsigned(isUnsigned) {}
35
36  APSInt &operator=(const APSInt &RHS) {
37    APInt::operator=(RHS);
38    IsUnsigned = RHS.IsUnsigned;
39    return *this;
40  }
41
42  APSInt &operator=(const APInt &RHS) {
43    // Retain our current sign.
44    APInt::operator=(RHS);
45    return *this;
46  }
47
48  APSInt &operator=(uint64_t RHS) {
49    // Retain our current sign.
50    APInt::operator=(RHS);
51    return *this;
52  }
53
54  // Query sign information.
55  bool isSigned() const { return !IsUnsigned; }
56  bool isUnsigned() const { return IsUnsigned; }
57  void setIsUnsigned(bool Val) { IsUnsigned = Val; }
58  void setIsSigned(bool Val) { IsUnsigned = !Val; }
59
60  /// toString - Append this APSInt to the specified SmallString.
61  void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
62    APInt::toString(Str, Radix, isSigned());
63  }
64  /// toString - Converts an APInt to a std::string.  This is an inefficient
65  /// method, your should prefer passing in a SmallString instead.
66  std::string toString(unsigned Radix) const {
67    return APInt::toString(Radix, isSigned());
68  }
69  using APInt::toString;
70
71  APSInt& extend(uint32_t width) {
72    if (IsUnsigned)
73      zext(width);
74    else
75      sext(width);
76    return *this;
77  }
78
79  APSInt& extOrTrunc(uint32_t width) {
80      if (IsUnsigned)
81        zextOrTrunc(width);
82      else
83        sextOrTrunc(width);
84      return *this;
85  }
86
87  const APSInt &operator%=(const APSInt &RHS) {
88    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
89    if (IsUnsigned)
90      *this = urem(RHS);
91    else
92      *this = srem(RHS);
93    return *this;
94  }
95  const APSInt &operator/=(const APSInt &RHS) {
96    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
97    if (IsUnsigned)
98      *this = udiv(RHS);
99    else
100      *this = sdiv(RHS);
101    return *this;
102  }
103  APSInt operator%(const APSInt &RHS) const {
104    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
105    return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
106  }
107  APSInt operator/(const APSInt &RHS) const {
108    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
109    return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
110  }
111
112  APSInt operator>>(unsigned Amt) const {
113    return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
114  }
115  APSInt& operator>>=(unsigned Amt) {
116    *this = *this >> Amt;
117    return *this;
118  }
119
120  inline bool operator<(const APSInt& RHS) const {
121    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122    return IsUnsigned ? ult(RHS) : slt(RHS);
123  }
124  inline bool operator>(const APSInt& RHS) const {
125    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126    return IsUnsigned ? ugt(RHS) : sgt(RHS);
127  }
128  inline bool operator<=(const APSInt& RHS) const {
129    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130    return IsUnsigned ? ule(RHS) : sle(RHS);
131  }
132  inline bool operator>=(const APSInt& RHS) const {
133    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
134    return IsUnsigned ? uge(RHS) : sge(RHS);
135  }
136
137  // The remaining operators just wrap the logic of APInt, but retain the
138  // signedness information.
139
140  APSInt operator<<(unsigned Bits) const {
141    return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
142  }
143  APSInt& operator<<=(unsigned Amt) {
144    *this = *this << Amt;
145    return *this;
146  }
147
148  APSInt& operator++() {
149    static_cast<APInt&>(*this)++;
150    return *this;
151  }
152  APSInt& operator--() {
153    static_cast<APInt&>(*this)--;
154    return *this;
155  }
156  APSInt operator++(int) {
157    return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
158  }
159  APSInt operator--(int) {
160    return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
161  }
162  APSInt operator-() const {
163    return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
164  }
165  APSInt& operator+=(const APSInt& RHS) {
166    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
167    static_cast<APInt&>(*this) += RHS;
168    return *this;
169  }
170  APSInt& operator-=(const APSInt& RHS) {
171    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
172    static_cast<APInt&>(*this) -= RHS;
173    return *this;
174  }
175  APSInt& operator*=(const APSInt& RHS) {
176    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
177    static_cast<APInt&>(*this) *= RHS;
178    return *this;
179  }
180  APSInt& operator&=(const APSInt& RHS) {
181    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
182    static_cast<APInt&>(*this) &= RHS;
183    return *this;
184  }
185  APSInt& operator|=(const APSInt& RHS) {
186    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
187    static_cast<APInt&>(*this) |= RHS;
188    return *this;
189  }
190  APSInt& operator^=(const APSInt& RHS) {
191    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
192    static_cast<APInt&>(*this) ^= RHS;
193    return *this;
194  }
195
196  APSInt operator&(const APSInt& RHS) const {
197    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
198    return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
199  }
200  APSInt And(const APSInt& RHS) const {
201    return this->operator&(RHS);
202  }
203
204  APSInt operator|(const APSInt& RHS) const {
205    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
206    return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
207  }
208  APSInt Or(const APSInt& RHS) const {
209    return this->operator|(RHS);
210  }
211
212
213  APSInt operator^(const APSInt& RHS) const {
214    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
215    return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
216  }
217  APSInt Xor(const APSInt& RHS) const {
218    return this->operator^(RHS);
219  }
220
221  APSInt operator*(const APSInt& RHS) const {
222    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
223    return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
224  }
225  APSInt operator+(const APSInt& RHS) const {
226    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
227    return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
228  }
229  APSInt operator-(const APSInt& RHS) const {
230    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
231    return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
232  }
233  APSInt operator~() const {
234    return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
235  }
236
237  /// getMaxValue - Return the APSInt representing the maximum integer value
238  ///  with the given bit width and signedness.
239  static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
240    return APSInt(Unsigned ? APInt::getMaxValue(numBits)
241                           : APInt::getSignedMaxValue(numBits), Unsigned);
242  }
243
244  /// getMinValue - Return the APSInt representing the minimum integer value
245  ///  with the given bit width and signedness.
246  static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
247    return APSInt(Unsigned ? APInt::getMinValue(numBits)
248                           : APInt::getSignedMinValue(numBits), Unsigned);
249  }
250
251  /// Profile - Used to insert APSInt objects, or objects that contain APSInt
252  ///  objects, into FoldingSets.
253  void Profile(FoldingSetNodeID& ID) const;
254};
255
256inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
257  I.print(OS, I.isSigned());
258  return OS;
259}
260
261
262} // end namespace llvm
263
264#endif
265