1 //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the APSInt class, which is a simple class that
11 // represents an arbitrary sized integer that knows its signedness.
13 //===----------------------------------------------------------------------===//
18 #include "llvm/ADT/APInt.h"
23 class APSInt : public APInt {
26 /// Default constructor that creates an uninitialized APInt.
29 /// APSInt ctor - Create an APSInt with the specified width, default to
31 explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
32 : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
34 explicit APSInt(const APInt &I, bool isUnsigned = true)
35 : APInt(I), IsUnsigned(isUnsigned) {}
37 APSInt &operator=(const APSInt &RHS) {
38 APInt::operator=(RHS);
39 IsUnsigned = RHS.IsUnsigned;
43 APSInt &operator=(const APInt &RHS) {
44 // Retain our current sign.
45 APInt::operator=(RHS);
49 APSInt &operator=(uint64_t RHS) {
50 // Retain our current sign.
51 APInt::operator=(RHS);
55 // Query sign information.
56 bool isSigned() const { return !IsUnsigned; }
57 bool isUnsigned() const { return IsUnsigned; }
58 void setIsUnsigned(bool Val) { IsUnsigned = Val; }
59 void setIsSigned(bool Val) { IsUnsigned = !Val; }
61 /// This is used internally to convert an APInt to a string.
62 /// @brief Converts an APInt to a std::string
63 std::string toString(uint8_t Radix = 10) const {
64 return APInt::toString(Radix, isSigned());
67 APSInt& extend(uint32_t width) {
75 APSInt& extOrTrunc(uint32_t width) {
83 const APSInt &operator%=(const APSInt &RHS) {
84 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
91 const APSInt &operator/=(const APSInt &RHS) {
92 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
99 APSInt operator%(const APSInt &RHS) const {
100 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
101 return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
103 APSInt operator/(const APSInt &RHS) const {
104 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
105 return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
108 APSInt operator>>(unsigned Amt) const {
109 return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
111 APSInt& operator>>=(unsigned Amt) {
112 *this = *this >> Amt;
116 inline bool operator<(const APSInt& RHS) const {
117 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
118 return IsUnsigned ? ult(RHS) : slt(RHS);
120 inline bool operator>(const APSInt& RHS) const {
121 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122 return IsUnsigned ? ugt(RHS) : sgt(RHS);
124 inline bool operator<=(const APSInt& RHS) const {
125 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126 return IsUnsigned ? ule(RHS) : sle(RHS);
128 inline bool operator>=(const APSInt& RHS) const {
129 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130 return IsUnsigned ? uge(RHS) : sge(RHS);
133 // The remaining operators just wrap the logic of APInt, but retain the
134 // signedness information.
136 APSInt operator<<(unsigned Bits) const {
137 return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
139 APSInt& operator<<=(unsigned Amt) {
140 *this = *this << Amt;
144 APSInt& operator++() {
145 static_cast<APInt&>(*this)++;
148 APSInt& operator--() {
149 static_cast<APInt&>(*this)++;
152 APSInt operator++(int) {
153 return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
155 APSInt operator--(int) {
156 return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
158 APSInt operator-() const {
159 return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
161 APSInt& operator+=(const APSInt& RHS) {
162 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
163 static_cast<APInt&>(*this) += RHS;
166 APSInt& operator-=(const APSInt& RHS) {
167 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
168 static_cast<APInt&>(*this) -= RHS;
171 APSInt& operator*=(const APSInt& RHS) {
172 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
173 static_cast<APInt&>(*this) *= RHS;
176 APSInt& operator&=(const APSInt& RHS) {
177 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
178 static_cast<APInt&>(*this) &= RHS;
181 APSInt& operator|=(const APSInt& RHS) {
182 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
183 static_cast<APInt&>(*this) |= RHS;
186 APSInt& operator^=(const APSInt& RHS) {
187 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
188 static_cast<APInt&>(*this) ^= RHS;
192 APSInt operator&(const APSInt& RHS) const {
193 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
194 return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
196 APSInt And(const APSInt& RHS) const {
197 return this->operator&(RHS);
200 APSInt operator|(const APSInt& RHS) const {
201 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
202 return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
204 APSInt Or(const APSInt& RHS) const {
205 return this->operator|(RHS);
209 APSInt operator^(const APSInt& RHS) const {
210 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
211 return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
213 APSInt Xor(const APSInt& RHS) const {
214 return this->operator^(RHS);
217 APSInt operator*(const APSInt& RHS) const {
218 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
219 return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
221 APSInt operator+(const APSInt& RHS) const {
222 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
223 return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
225 APSInt operator-(const APSInt& RHS) const {
226 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
227 return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
229 APSInt operator~() const {
230 return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
233 /// Profile - Used to insert APSInt objects, or objects that contain APSInt
234 /// objects, into FoldingSets.
235 void Profile(FoldingSetNodeID& ID) const;
238 } // end namespace llvm