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