APSInt.h revision 193323
1193323Sed//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the APSInt class, which is a simple class that 11193323Sed// represents an arbitrary sized integer that knows its signedness. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#ifndef LLVM_APSINT_H 16193323Sed#define LLVM_APSINT_H 17193323Sed 18193323Sed#include "llvm/ADT/APInt.h" 19193323Sed 20193323Sednamespace llvm { 21193323Sed 22193323Sedclass APSInt : public APInt { 23193323Sed bool IsUnsigned; 24193323Sedpublic: 25193323Sed /// Default constructor that creates an uninitialized APInt. 26193323Sed explicit APSInt() {} 27193323Sed 28193323Sed /// APSInt ctor - Create an APSInt with the specified width, default to 29193323Sed /// unsigned. 30193323Sed explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 31193323Sed : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} 32193323Sed 33193323Sed explicit APSInt(const APInt &I, bool isUnsigned = true) 34193323Sed : APInt(I), IsUnsigned(isUnsigned) {} 35193323Sed 36193323Sed APSInt &operator=(const APSInt &RHS) { 37193323Sed APInt::operator=(RHS); 38193323Sed IsUnsigned = RHS.IsUnsigned; 39193323Sed return *this; 40193323Sed } 41193323Sed 42193323Sed APSInt &operator=(const APInt &RHS) { 43193323Sed // Retain our current sign. 44193323Sed APInt::operator=(RHS); 45193323Sed return *this; 46193323Sed } 47193323Sed 48193323Sed APSInt &operator=(uint64_t RHS) { 49193323Sed // Retain our current sign. 50193323Sed APInt::operator=(RHS); 51193323Sed return *this; 52193323Sed } 53193323Sed 54193323Sed // Query sign information. 55193323Sed bool isSigned() const { return !IsUnsigned; } 56193323Sed bool isUnsigned() const { return IsUnsigned; } 57193323Sed void setIsUnsigned(bool Val) { IsUnsigned = Val; } 58193323Sed void setIsSigned(bool Val) { IsUnsigned = !Val; } 59193323Sed 60193323Sed /// toString - Append this APSInt to the specified SmallString. 61193323Sed void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { 62193323Sed APInt::toString(Str, Radix, isSigned()); 63193323Sed } 64193323Sed /// toString - Converts an APInt to a std::string. This is an inefficient 65193323Sed /// method, your should prefer passing in a SmallString instead. 66193323Sed std::string toString(unsigned Radix) const { 67193323Sed return APInt::toString(Radix, isSigned()); 68193323Sed } 69193323Sed using APInt::toString; 70193323Sed 71193323Sed APSInt& extend(uint32_t width) { 72193323Sed if (IsUnsigned) 73193323Sed zext(width); 74193323Sed else 75193323Sed sext(width); 76193323Sed return *this; 77193323Sed } 78193323Sed 79193323Sed APSInt& extOrTrunc(uint32_t width) { 80193323Sed if (IsUnsigned) 81193323Sed zextOrTrunc(width); 82193323Sed else 83193323Sed sextOrTrunc(width); 84193323Sed return *this; 85193323Sed } 86193323Sed 87193323Sed const APSInt &operator%=(const APSInt &RHS) { 88193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 89193323Sed if (IsUnsigned) 90193323Sed *this = urem(RHS); 91193323Sed else 92193323Sed *this = srem(RHS); 93193323Sed return *this; 94193323Sed } 95193323Sed const APSInt &operator/=(const APSInt &RHS) { 96193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 97193323Sed if (IsUnsigned) 98193323Sed *this = udiv(RHS); 99193323Sed else 100193323Sed *this = sdiv(RHS); 101193323Sed return *this; 102193323Sed } 103193323Sed APSInt operator%(const APSInt &RHS) const { 104193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 105193323Sed return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false); 106193323Sed } 107193323Sed APSInt operator/(const APSInt &RHS) const { 108193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 109193323Sed return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false); 110193323Sed } 111193323Sed 112193323Sed APSInt operator>>(unsigned Amt) const { 113193323Sed return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); 114193323Sed } 115193323Sed APSInt& operator>>=(unsigned Amt) { 116193323Sed *this = *this >> Amt; 117193323Sed return *this; 118193323Sed } 119193323Sed 120193323Sed inline bool operator<(const APSInt& RHS) const { 121193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 122193323Sed return IsUnsigned ? ult(RHS) : slt(RHS); 123193323Sed } 124193323Sed inline bool operator>(const APSInt& RHS) const { 125193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 126193323Sed return IsUnsigned ? ugt(RHS) : sgt(RHS); 127193323Sed } 128193323Sed inline bool operator<=(const APSInt& RHS) const { 129193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 130193323Sed return IsUnsigned ? ule(RHS) : sle(RHS); 131193323Sed } 132193323Sed inline bool operator>=(const APSInt& RHS) const { 133193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 134193323Sed return IsUnsigned ? uge(RHS) : sge(RHS); 135193323Sed } 136193323Sed 137193323Sed // The remaining operators just wrap the logic of APInt, but retain the 138193323Sed // signedness information. 139193323Sed 140193323Sed APSInt operator<<(unsigned Bits) const { 141193323Sed return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); 142193323Sed } 143193323Sed APSInt& operator<<=(unsigned Amt) { 144193323Sed *this = *this << Amt; 145193323Sed return *this; 146193323Sed } 147193323Sed 148193323Sed APSInt& operator++() { 149193323Sed static_cast<APInt&>(*this)++; 150193323Sed return *this; 151193323Sed } 152193323Sed APSInt& operator--() { 153193323Sed static_cast<APInt&>(*this)--; 154193323Sed return *this; 155193323Sed } 156193323Sed APSInt operator++(int) { 157193323Sed return APSInt(++static_cast<APInt&>(*this), IsUnsigned); 158193323Sed } 159193323Sed APSInt operator--(int) { 160193323Sed return APSInt(--static_cast<APInt&>(*this), IsUnsigned); 161193323Sed } 162193323Sed APSInt operator-() const { 163193323Sed return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); 164193323Sed } 165193323Sed APSInt& operator+=(const APSInt& RHS) { 166193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 167193323Sed static_cast<APInt&>(*this) += RHS; 168193323Sed return *this; 169193323Sed } 170193323Sed APSInt& operator-=(const APSInt& RHS) { 171193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 172193323Sed static_cast<APInt&>(*this) -= RHS; 173193323Sed return *this; 174193323Sed } 175193323Sed APSInt& operator*=(const APSInt& RHS) { 176193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 177193323Sed static_cast<APInt&>(*this) *= RHS; 178193323Sed return *this; 179193323Sed } 180193323Sed APSInt& operator&=(const APSInt& RHS) { 181193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 182193323Sed static_cast<APInt&>(*this) &= RHS; 183193323Sed return *this; 184193323Sed } 185193323Sed APSInt& operator|=(const APSInt& RHS) { 186193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 187193323Sed static_cast<APInt&>(*this) |= RHS; 188193323Sed return *this; 189193323Sed } 190193323Sed APSInt& operator^=(const APSInt& RHS) { 191193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 192193323Sed static_cast<APInt&>(*this) ^= RHS; 193193323Sed return *this; 194193323Sed } 195193323Sed 196193323Sed APSInt operator&(const APSInt& RHS) const { 197193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 198193323Sed return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); 199193323Sed } 200193323Sed APSInt And(const APSInt& RHS) const { 201193323Sed return this->operator&(RHS); 202193323Sed } 203193323Sed 204193323Sed APSInt operator|(const APSInt& RHS) const { 205193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 206193323Sed return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); 207193323Sed } 208193323Sed APSInt Or(const APSInt& RHS) const { 209193323Sed return this->operator|(RHS); 210193323Sed } 211193323Sed 212193323Sed 213193323Sed APSInt operator^(const APSInt& RHS) const { 214193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 215193323Sed return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); 216193323Sed } 217193323Sed APSInt Xor(const APSInt& RHS) const { 218193323Sed return this->operator^(RHS); 219193323Sed } 220193323Sed 221193323Sed APSInt operator*(const APSInt& RHS) const { 222193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 223193323Sed return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned); 224193323Sed } 225193323Sed APSInt operator+(const APSInt& RHS) const { 226193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 227193323Sed return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned); 228193323Sed } 229193323Sed APSInt operator-(const APSInt& RHS) const { 230193323Sed assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 231193323Sed return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned); 232193323Sed } 233193323Sed APSInt operator~() const { 234193323Sed return APSInt(~static_cast<const APInt&>(*this), IsUnsigned); 235193323Sed } 236193323Sed 237193323Sed /// getMaxValue - Return the APSInt representing the maximum integer value 238193323Sed /// with the given bit width and signedness. 239193323Sed static APSInt getMaxValue(uint32_t numBits, bool Unsigned) { 240193323Sed return APSInt(Unsigned ? APInt::getMaxValue(numBits) 241193323Sed : APInt::getSignedMaxValue(numBits), Unsigned); 242193323Sed } 243193323Sed 244193323Sed /// getMinValue - Return the APSInt representing the minimum integer value 245193323Sed /// with the given bit width and signedness. 246193323Sed static APSInt getMinValue(uint32_t numBits, bool Unsigned) { 247193323Sed return APSInt(Unsigned ? APInt::getMinValue(numBits) 248193323Sed : APInt::getSignedMinValue(numBits), Unsigned); 249193323Sed } 250193323Sed 251193323Sed /// Profile - Used to insert APSInt objects, or objects that contain APSInt 252193323Sed /// objects, into FoldingSets. 253193323Sed void Profile(FoldingSetNodeID& ID) const; 254193323Sed}; 255193323Sed 256193323Sedinline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { 257193323Sed I.print(OS, I.isSigned()); 258193323Sed return OS; 259193323Sed} 260193323Sed 261193323Sed 262193323Sed} // end namespace llvm 263193323Sed 264193323Sed#endif 265