LLVM API Documentation
00001 //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the APSInt class, which is a simple class that 00011 // represents an arbitrary sized integer that knows its signedness. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_APSINT_H 00016 #define LLVM_APSINT_H 00017 00018 #include "llvm/ADT/APInt.h" 00019 00020 namespace llvm { 00021 00022 class APSInt : public APInt { 00023 bool IsUnsigned; 00024 public: 00025 /// Default constructor that creates an uninitialized APInt. 00026 explicit APSInt() {} 00027 00028 /// APSInt ctor - Create an APSInt with the specified width, default to 00029 /// unsigned. 00030 explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 00031 : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} 00032 00033 explicit APSInt(const APInt &I, bool isUnsigned = true) 00034 : APInt(I), IsUnsigned(isUnsigned) {} 00035 00036 APSInt &operator=(const APSInt &RHS) { 00037 APInt::operator=(RHS); 00038 IsUnsigned = RHS.IsUnsigned; 00039 return *this; 00040 } 00041 00042 APSInt &operator=(const APInt &RHS) { 00043 // Retain our current sign. 00044 APInt::operator=(RHS); 00045 return *this; 00046 } 00047 00048 APSInt &operator=(uint64_t RHS) { 00049 // Retain our current sign. 00050 APInt::operator=(RHS); 00051 return *this; 00052 } 00053 00054 // Query sign information. 00055 bool isSigned() const { return !IsUnsigned; } 00056 bool isUnsigned() const { return IsUnsigned; } 00057 void setIsUnsigned(bool Val) { IsUnsigned = Val; } 00058 void setIsSigned(bool Val) { IsUnsigned = !Val; } 00059 00060 /// toString - Append this APSInt to the specified SmallString. 00061 void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { 00062 return APInt::toString(Str, Radix, isSigned()); 00063 } 00064 /// toString - Converts an APInt to a std::string. This is an inefficient 00065 /// method, your should prefer passing in a SmallString instead. 00066 std::string toString(unsigned Radix) const { 00067 return APInt::toString(Radix, isSigned()); 00068 } 00069 using APInt::toString; 00070 00071 APSInt& extend(uint32_t width) { 00072 if (IsUnsigned) 00073 zext(width); 00074 else 00075 sext(width); 00076 return *this; 00077 } 00078 00079 APSInt& extOrTrunc(uint32_t width) { 00080 if (IsUnsigned) 00081 zextOrTrunc(width); 00082 else 00083 sextOrTrunc(width); 00084 return *this; 00085 } 00086 00087 const APSInt &operator%=(const APSInt &RHS) { 00088 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00089 if (IsUnsigned) 00090 *this = urem(RHS); 00091 else 00092 *this = srem(RHS); 00093 return *this; 00094 } 00095 const APSInt &operator/=(const APSInt &RHS) { 00096 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00097 if (IsUnsigned) 00098 *this = udiv(RHS); 00099 else 00100 *this = sdiv(RHS); 00101 return *this; 00102 } 00103 APSInt operator%(const APSInt &RHS) const { 00104 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00105 return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false); 00106 } 00107 APSInt operator/(const APSInt &RHS) const { 00108 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00109 return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false); 00110 } 00111 00112 APSInt operator>>(unsigned Amt) const { 00113 return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); 00114 } 00115 APSInt& operator>>=(unsigned Amt) { 00116 *this = *this >> Amt; 00117 return *this; 00118 } 00119 00120 inline bool operator<(const APSInt& RHS) const { 00121 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00122 return IsUnsigned ? ult(RHS) : slt(RHS); 00123 } 00124 inline bool operator>(const APSInt& RHS) const { 00125 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00126 return IsUnsigned ? ugt(RHS) : sgt(RHS); 00127 } 00128 inline bool operator<=(const APSInt& RHS) const { 00129 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00130 return IsUnsigned ? ule(RHS) : sle(RHS); 00131 } 00132 inline bool operator>=(const APSInt& RHS) const { 00133 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00134 return IsUnsigned ? uge(RHS) : sge(RHS); 00135 } 00136 00137 // The remaining operators just wrap the logic of APInt, but retain the 00138 // signedness information. 00139 00140 APSInt operator<<(unsigned Bits) const { 00141 return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); 00142 } 00143 APSInt& operator<<=(unsigned Amt) { 00144 *this = *this << Amt; 00145 return *this; 00146 } 00147 00148 APSInt& operator++() { 00149 static_cast<APInt&>(*this)++; 00150 return *this; 00151 } 00152 APSInt& operator--() { 00153 static_cast<APInt&>(*this)++; 00154 return *this; 00155 } 00156 APSInt operator++(int) { 00157 return APSInt(++static_cast<APInt&>(*this), IsUnsigned); 00158 } 00159 APSInt operator--(int) { 00160 return APSInt(--static_cast<APInt&>(*this), IsUnsigned); 00161 } 00162 APSInt operator-() const { 00163 return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); 00164 } 00165 APSInt& operator+=(const APSInt& RHS) { 00166 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00167 static_cast<APInt&>(*this) += RHS; 00168 return *this; 00169 } 00170 APSInt& operator-=(const APSInt& RHS) { 00171 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00172 static_cast<APInt&>(*this) -= RHS; 00173 return *this; 00174 } 00175 APSInt& operator*=(const APSInt& RHS) { 00176 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00177 static_cast<APInt&>(*this) *= RHS; 00178 return *this; 00179 } 00180 APSInt& operator&=(const APSInt& RHS) { 00181 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00182 static_cast<APInt&>(*this) &= RHS; 00183 return *this; 00184 } 00185 APSInt& operator|=(const APSInt& RHS) { 00186 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00187 static_cast<APInt&>(*this) |= RHS; 00188 return *this; 00189 } 00190 APSInt& operator^=(const APSInt& RHS) { 00191 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00192 static_cast<APInt&>(*this) ^= RHS; 00193 return *this; 00194 } 00195 00196 APSInt operator&(const APSInt& RHS) const { 00197 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00198 return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); 00199 } 00200 APSInt And(const APSInt& RHS) const { 00201 return this->operator&(RHS); 00202 } 00203 00204 APSInt operator|(const APSInt& RHS) const { 00205 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00206 return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); 00207 } 00208 APSInt Or(const APSInt& RHS) const { 00209 return this->operator|(RHS); 00210 } 00211 00212 00213 APSInt operator^(const APSInt& RHS) const { 00214 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00215 return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); 00216 } 00217 APSInt Xor(const APSInt& RHS) const { 00218 return this->operator^(RHS); 00219 } 00220 00221 APSInt operator*(const APSInt& RHS) const { 00222 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00223 return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned); 00224 } 00225 APSInt operator+(const APSInt& RHS) const { 00226 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00227 return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned); 00228 } 00229 APSInt operator-(const APSInt& RHS) const { 00230 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 00231 return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned); 00232 } 00233 APSInt operator~() const { 00234 return APSInt(~static_cast<const APInt&>(*this), IsUnsigned); 00235 } 00236 00237 /// getMaxValue - Return the APSInt representing the maximum integer value 00238 /// with the given bit width and signedness. 00239 static APSInt getMaxValue(uint32_t numBits, bool Unsigned) { 00240 return APSInt(Unsigned ? APInt::getMaxValue(numBits) 00241 : APInt::getSignedMaxValue(numBits), Unsigned); 00242 } 00243 00244 /// getMinValue - Return the APSInt representing the minimum integer value 00245 /// with the given bit width and signedness. 00246 static APSInt getMinValue(uint32_t numBits, bool Unsigned) { 00247 return APSInt(Unsigned ? APInt::getMinValue(numBits) 00248 : APInt::getSignedMinValue(numBits), Unsigned); 00249 } 00250 00251 /// Profile - Used to insert APSInt objects, or objects that contain APSInt 00252 /// objects, into FoldingSets. 00253 void Profile(FoldingSetNodeID& ID) const; 00254 }; 00255 00256 inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { 00257 I.print(OS, I.isSigned()); 00258 return OS; 00259 } 00260 00261 00262 } // end namespace llvm 00263 00264 #endif