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