APSInt.h revision cadf873c83ad7ea7c638e6d98fc5f20752702b03
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
22
23class APSInt : public APInt {
24  bool IsUnsigned;
25public:
26  /// APSInt ctor - Create an APSInt with the specified width, default to
27  /// unsigned.
28  explicit APSInt(uint32_t BitWidth) : APInt(BitWidth, 0), IsUnsigned(true) {}
29
30  explicit APSInt(const APInt &I, bool isUnsigned = true)
31   : APInt(I), IsUnsigned(isUnsigned) {}
32
33  APSInt &operator=(const APSInt &RHS) {
34    APInt::operator=(RHS);
35    IsUnsigned = RHS.IsUnsigned;
36    return *this;
37  }
38
39  APSInt &operator=(const APInt &RHS) {
40    // Retain our current sign.
41    APInt::operator=(RHS);
42    return *this;
43  }
44
45  APSInt &operator=(uint64_t RHS) {
46    // Retain our current sign.
47    APInt::operator=(RHS);
48    return *this;
49  }
50
51  // Query sign information.
52  bool isSigned() const { return !IsUnsigned; }
53  bool isUnsigned() const { return IsUnsigned; }
54  void setIsUnsigned(bool Val) { IsUnsigned = Val; }
55  void setIsSigned(bool Val) { IsUnsigned = !Val; }
56
57  /// This is used internally to convert an APInt to a string.
58  /// @brief Converts an APInt to a std::string
59  std::string toString(uint8_t Radix = 10) const {
60    return APInt::toString(Radix, isSigned());
61  }
62
63  APSInt& extend(uint32_t width) {
64    if (IsUnsigned)
65      zext(width);
66    else
67      sext(width);
68    return *this;
69  }
70
71  APSInt& extOrTrunc(uint32_t width) {
72      if (IsUnsigned)
73        zextOrTrunc(width);
74      else
75        sextOrTrunc(width);
76      return *this;
77  }
78
79  const APSInt &operator%=(const APSInt &RHS) {
80    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
81    if (IsUnsigned)
82      *this = urem(RHS);
83    else
84      *this = srem(RHS);
85    return *this;
86  }
87  const APSInt &operator/=(const APSInt &RHS) {
88    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
89    if (IsUnsigned)
90      *this = udiv(RHS);
91    else
92      *this = sdiv(RHS);
93    return *this;
94  }
95  APSInt operator%(const APSInt &RHS) const {
96    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
97    return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
98  }
99  APSInt operator/(const APSInt &RHS) const {
100    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
101    return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
102  }
103
104  APSInt operator>>(unsigned Amt) const {
105    return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
106  }
107  APSInt& operator>>=(unsigned Amt) {
108    *this = *this >> Amt;
109    return *this;
110  }
111
112  inline bool operator<(const APSInt& RHS) const {
113    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
114    return IsUnsigned ? ult(RHS) : slt(RHS);
115  }
116  inline bool operator>(const APSInt& RHS) const {
117    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
118    return IsUnsigned ? ugt(RHS) : sgt(RHS);
119  }
120  inline bool operator<=(const APSInt& RHS) const {
121    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122    return IsUnsigned ? ule(RHS) : sle(RHS);
123  }
124  inline bool operator>=(const APSInt& RHS) const {
125    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126    return IsUnsigned ? uge(RHS) : sge(RHS);
127  }
128
129  // The remaining operators just wrap the logic of APInt, but retain the
130  // signedness information.
131
132  APSInt operator<<(unsigned Bits) {
133    return APSInt(static_cast<APInt&>(*this) << Bits, IsUnsigned);
134  }
135  APSInt& operator<<=(unsigned Amt) {
136    *this = *this << Amt;
137    return *this;
138  }
139
140  APSInt& operator++() {
141    static_cast<APInt&>(*this)++;
142    return *this;
143  }
144  APSInt& operator--() {
145    static_cast<APInt&>(*this)++;
146    return *this;
147  }
148  APSInt operator++(int) {
149    return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
150  }
151  APSInt operator--(int) {
152    return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
153  }
154  APSInt operator-() const {
155    return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
156  }
157  APSInt& operator+=(const APSInt& RHS) {
158    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
159    static_cast<APInt&>(*this) += RHS;
160    return *this;
161  }
162  APSInt& operator-=(const APSInt& RHS) {
163    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
164    static_cast<APInt&>(*this) -= RHS;
165    return *this;
166  }
167  APSInt& operator*=(const APSInt& RHS) {
168    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
169    static_cast<APInt&>(*this) *= RHS;
170    return *this;
171  }
172  APSInt& operator&=(const APSInt& RHS) {
173    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
174    static_cast<APInt&>(*this) &= RHS;
175    return *this;
176  }
177  APSInt& operator|=(const APSInt& RHS) {
178    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
179    static_cast<APInt&>(*this) |= RHS;
180    return *this;
181  }
182  APSInt& operator^=(const APSInt& RHS) {
183    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
184    static_cast<APInt&>(*this) ^= RHS;
185    return *this;
186  }
187
188  APSInt operator&(const APSInt& RHS) const {
189    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
190    return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
191  }
192  APSInt And(const APSInt& RHS) const {
193    return this->operator&(RHS);
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 Or(const APSInt& RHS) const {
201    return this->operator|(RHS);
202  }
203
204
205  APSInt operator^(const APSInt& RHS) const {
206    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
207    return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
208  }
209  APSInt Xor(const APSInt& RHS) const {
210    return this->operator^(RHS);
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 operator+(const APSInt& RHS) const {
218    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
219    return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
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~() {
226    return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
227  }
228
229  /// Profile - Used to insert APSInt objects, or objects that contain APSInt
230  ///  objects, into FoldingSets.
231  void Profile(FoldingSetNodeID& ID) const;
232};
233
234} // end namespace llvm
235
236#endif
237