APSInt.h revision 193323
1193323Sed//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the APSInt class, which is a simple class that
11193323Sed// represents an arbitrary sized integer that knows its signedness.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#ifndef LLVM_APSINT_H
16193323Sed#define LLVM_APSINT_H
17193323Sed
18193323Sed#include "llvm/ADT/APInt.h"
19193323Sed
20193323Sednamespace llvm {
21193323Sed
22193323Sedclass APSInt : public APInt {
23193323Sed  bool IsUnsigned;
24193323Sedpublic:
25193323Sed  /// Default constructor that creates an uninitialized APInt.
26193323Sed  explicit APSInt() {}
27193323Sed
28193323Sed  /// APSInt ctor - Create an APSInt with the specified width, default to
29193323Sed  /// unsigned.
30193323Sed  explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
31193323Sed   : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
32193323Sed
33193323Sed  explicit APSInt(const APInt &I, bool isUnsigned = true)
34193323Sed   : APInt(I), IsUnsigned(isUnsigned) {}
35193323Sed
36193323Sed  APSInt &operator=(const APSInt &RHS) {
37193323Sed    APInt::operator=(RHS);
38193323Sed    IsUnsigned = RHS.IsUnsigned;
39193323Sed    return *this;
40193323Sed  }
41193323Sed
42193323Sed  APSInt &operator=(const APInt &RHS) {
43193323Sed    // Retain our current sign.
44193323Sed    APInt::operator=(RHS);
45193323Sed    return *this;
46193323Sed  }
47193323Sed
48193323Sed  APSInt &operator=(uint64_t RHS) {
49193323Sed    // Retain our current sign.
50193323Sed    APInt::operator=(RHS);
51193323Sed    return *this;
52193323Sed  }
53193323Sed
54193323Sed  // Query sign information.
55193323Sed  bool isSigned() const { return !IsUnsigned; }
56193323Sed  bool isUnsigned() const { return IsUnsigned; }
57193323Sed  void setIsUnsigned(bool Val) { IsUnsigned = Val; }
58193323Sed  void setIsSigned(bool Val) { IsUnsigned = !Val; }
59193323Sed
60193323Sed  /// toString - Append this APSInt to the specified SmallString.
61193323Sed  void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
62193323Sed    APInt::toString(Str, Radix, isSigned());
63193323Sed  }
64193323Sed  /// toString - Converts an APInt to a std::string.  This is an inefficient
65193323Sed  /// method, your should prefer passing in a SmallString instead.
66193323Sed  std::string toString(unsigned Radix) const {
67193323Sed    return APInt::toString(Radix, isSigned());
68193323Sed  }
69193323Sed  using APInt::toString;
70193323Sed
71193323Sed  APSInt& extend(uint32_t width) {
72193323Sed    if (IsUnsigned)
73193323Sed      zext(width);
74193323Sed    else
75193323Sed      sext(width);
76193323Sed    return *this;
77193323Sed  }
78193323Sed
79193323Sed  APSInt& extOrTrunc(uint32_t width) {
80193323Sed      if (IsUnsigned)
81193323Sed        zextOrTrunc(width);
82193323Sed      else
83193323Sed        sextOrTrunc(width);
84193323Sed      return *this;
85193323Sed  }
86193323Sed
87193323Sed  const APSInt &operator%=(const APSInt &RHS) {
88193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
89193323Sed    if (IsUnsigned)
90193323Sed      *this = urem(RHS);
91193323Sed    else
92193323Sed      *this = srem(RHS);
93193323Sed    return *this;
94193323Sed  }
95193323Sed  const APSInt &operator/=(const APSInt &RHS) {
96193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
97193323Sed    if (IsUnsigned)
98193323Sed      *this = udiv(RHS);
99193323Sed    else
100193323Sed      *this = sdiv(RHS);
101193323Sed    return *this;
102193323Sed  }
103193323Sed  APSInt operator%(const APSInt &RHS) const {
104193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
105193323Sed    return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
106193323Sed  }
107193323Sed  APSInt operator/(const APSInt &RHS) const {
108193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
109193323Sed    return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
110193323Sed  }
111193323Sed
112193323Sed  APSInt operator>>(unsigned Amt) const {
113193323Sed    return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
114193323Sed  }
115193323Sed  APSInt& operator>>=(unsigned Amt) {
116193323Sed    *this = *this >> Amt;
117193323Sed    return *this;
118193323Sed  }
119193323Sed
120193323Sed  inline bool operator<(const APSInt& RHS) const {
121193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122193323Sed    return IsUnsigned ? ult(RHS) : slt(RHS);
123193323Sed  }
124193323Sed  inline bool operator>(const APSInt& RHS) const {
125193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126193323Sed    return IsUnsigned ? ugt(RHS) : sgt(RHS);
127193323Sed  }
128193323Sed  inline bool operator<=(const APSInt& RHS) const {
129193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130193323Sed    return IsUnsigned ? ule(RHS) : sle(RHS);
131193323Sed  }
132193323Sed  inline bool operator>=(const APSInt& RHS) const {
133193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
134193323Sed    return IsUnsigned ? uge(RHS) : sge(RHS);
135193323Sed  }
136193323Sed
137193323Sed  // The remaining operators just wrap the logic of APInt, but retain the
138193323Sed  // signedness information.
139193323Sed
140193323Sed  APSInt operator<<(unsigned Bits) const {
141193323Sed    return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
142193323Sed  }
143193323Sed  APSInt& operator<<=(unsigned Amt) {
144193323Sed    *this = *this << Amt;
145193323Sed    return *this;
146193323Sed  }
147193323Sed
148193323Sed  APSInt& operator++() {
149193323Sed    static_cast<APInt&>(*this)++;
150193323Sed    return *this;
151193323Sed  }
152193323Sed  APSInt& operator--() {
153193323Sed    static_cast<APInt&>(*this)--;
154193323Sed    return *this;
155193323Sed  }
156193323Sed  APSInt operator++(int) {
157193323Sed    return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
158193323Sed  }
159193323Sed  APSInt operator--(int) {
160193323Sed    return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
161193323Sed  }
162193323Sed  APSInt operator-() const {
163193323Sed    return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
164193323Sed  }
165193323Sed  APSInt& operator+=(const APSInt& RHS) {
166193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
167193323Sed    static_cast<APInt&>(*this) += RHS;
168193323Sed    return *this;
169193323Sed  }
170193323Sed  APSInt& operator-=(const APSInt& RHS) {
171193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
172193323Sed    static_cast<APInt&>(*this) -= RHS;
173193323Sed    return *this;
174193323Sed  }
175193323Sed  APSInt& operator*=(const APSInt& RHS) {
176193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
177193323Sed    static_cast<APInt&>(*this) *= RHS;
178193323Sed    return *this;
179193323Sed  }
180193323Sed  APSInt& operator&=(const APSInt& RHS) {
181193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
182193323Sed    static_cast<APInt&>(*this) &= RHS;
183193323Sed    return *this;
184193323Sed  }
185193323Sed  APSInt& operator|=(const APSInt& RHS) {
186193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
187193323Sed    static_cast<APInt&>(*this) |= RHS;
188193323Sed    return *this;
189193323Sed  }
190193323Sed  APSInt& operator^=(const APSInt& RHS) {
191193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
192193323Sed    static_cast<APInt&>(*this) ^= RHS;
193193323Sed    return *this;
194193323Sed  }
195193323Sed
196193323Sed  APSInt operator&(const APSInt& RHS) const {
197193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
198193323Sed    return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
199193323Sed  }
200193323Sed  APSInt And(const APSInt& RHS) const {
201193323Sed    return this->operator&(RHS);
202193323Sed  }
203193323Sed
204193323Sed  APSInt operator|(const APSInt& RHS) const {
205193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
206193323Sed    return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
207193323Sed  }
208193323Sed  APSInt Or(const APSInt& RHS) const {
209193323Sed    return this->operator|(RHS);
210193323Sed  }
211193323Sed
212193323Sed
213193323Sed  APSInt operator^(const APSInt& RHS) const {
214193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
215193323Sed    return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
216193323Sed  }
217193323Sed  APSInt Xor(const APSInt& RHS) const {
218193323Sed    return this->operator^(RHS);
219193323Sed  }
220193323Sed
221193323Sed  APSInt operator*(const APSInt& RHS) const {
222193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
223193323Sed    return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
224193323Sed  }
225193323Sed  APSInt operator+(const APSInt& RHS) const {
226193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
227193323Sed    return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
228193323Sed  }
229193323Sed  APSInt operator-(const APSInt& RHS) const {
230193323Sed    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
231193323Sed    return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
232193323Sed  }
233193323Sed  APSInt operator~() const {
234193323Sed    return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
235193323Sed  }
236193323Sed
237193323Sed  /// getMaxValue - Return the APSInt representing the maximum integer value
238193323Sed  ///  with the given bit width and signedness.
239193323Sed  static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
240193323Sed    return APSInt(Unsigned ? APInt::getMaxValue(numBits)
241193323Sed                           : APInt::getSignedMaxValue(numBits), Unsigned);
242193323Sed  }
243193323Sed
244193323Sed  /// getMinValue - Return the APSInt representing the minimum integer value
245193323Sed  ///  with the given bit width and signedness.
246193323Sed  static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
247193323Sed    return APSInt(Unsigned ? APInt::getMinValue(numBits)
248193323Sed                           : APInt::getSignedMinValue(numBits), Unsigned);
249193323Sed  }
250193323Sed
251193323Sed  /// Profile - Used to insert APSInt objects, or objects that contain APSInt
252193323Sed  ///  objects, into FoldingSets.
253193323Sed  void Profile(FoldingSetNodeID& ID) const;
254193323Sed};
255193323Sed
256193323Sedinline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
257193323Sed  I.print(OS, I.isSigned());
258193323Sed  return OS;
259193323Sed}
260193323Sed
261193323Sed
262193323Sed} // end namespace llvm
263193323Sed
264193323Sed#endif
265