Reduce heap trashing due to std::string construction / concatenation via caching...
[oota-llvm.git] / include / llvm / ADT / APSInt.h
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
20 namespace llvm {
21   
22   
23 class APSInt : public APInt {
24   bool IsUnsigned;
25 public:
26   /// Default constructor that creates an uninitialized APInt.
27   explicit APSInt() {}
28
29   /// APSInt ctor - Create an APSInt with the specified width, default to
30   /// unsigned.
31   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 
32    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
33
34   explicit APSInt(const APInt &I, bool isUnsigned = true) 
35    : APInt(I), IsUnsigned(isUnsigned) {}
36
37   APSInt &operator=(const APSInt &RHS) {
38     APInt::operator=(RHS); 
39     IsUnsigned = RHS.IsUnsigned;
40     return *this;
41   }
42
43   APSInt &operator=(const APInt &RHS) {
44     // Retain our current sign.
45     APInt::operator=(RHS); 
46     return *this;
47   }
48
49   APSInt &operator=(uint64_t RHS) {
50     // Retain our current sign.
51     APInt::operator=(RHS); 
52     return *this;
53   }
54
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; }
60   
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());
65   }
66   
67   APSInt& extend(uint32_t width) {
68     if (IsUnsigned)
69       zext(width);
70     else
71       sext(width);
72     return *this;
73   }
74   
75   APSInt& extOrTrunc(uint32_t width) {
76       if (IsUnsigned)
77         zextOrTrunc(width);
78       else
79         sextOrTrunc(width);
80       return *this;
81   }
82   
83   const APSInt &operator%=(const APSInt &RHS) {
84     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
85     if (IsUnsigned)
86       *this = urem(RHS);
87     else
88       *this = srem(RHS);
89     return *this;
90   }
91   const APSInt &operator/=(const APSInt &RHS) {
92     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
93     if (IsUnsigned)
94       *this = udiv(RHS);
95     else
96       *this = sdiv(RHS);
97     return *this;
98   }
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);
102   }
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);
106   }
107   
108   APSInt operator>>(unsigned Amt) const {
109     return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
110   }
111   APSInt& operator>>=(unsigned Amt) {
112     *this = *this >> Amt;
113     return *this;
114   }
115   
116   inline bool operator<(const APSInt& RHS) const {
117     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
118     return IsUnsigned ? ult(RHS) : slt(RHS);
119   }
120   inline bool operator>(const APSInt& RHS) const {
121     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122     return IsUnsigned ? ugt(RHS) : sgt(RHS);
123   }
124   inline bool operator<=(const APSInt& RHS) const {
125     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126     return IsUnsigned ? ule(RHS) : sle(RHS);
127   }
128   inline bool operator>=(const APSInt& RHS) const {
129     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130     return IsUnsigned ? uge(RHS) : sge(RHS);
131   }
132   
133   // The remaining operators just wrap the logic of APInt, but retain the
134   // signedness information.
135   
136   APSInt operator<<(unsigned Bits) const {
137     return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
138   }  
139   APSInt& operator<<=(unsigned Amt) {
140     *this = *this << Amt;
141     return *this;
142   }
143   
144   APSInt& operator++() {
145     static_cast<APInt&>(*this)++;
146     return *this;
147   }
148   APSInt& operator--() {
149     static_cast<APInt&>(*this)++;
150     return *this;
151   }
152   APSInt operator++(int) {
153     return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
154   }
155   APSInt operator--(int) {
156     return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
157   } 
158   APSInt operator-() const {
159     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
160   }  
161   APSInt& operator+=(const APSInt& RHS) {
162     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
163     static_cast<APInt&>(*this) += RHS;
164     return *this;
165   }  
166   APSInt& operator-=(const APSInt& RHS) {
167     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
168     static_cast<APInt&>(*this) -= RHS;
169     return *this;
170   }    
171   APSInt& operator*=(const APSInt& RHS) {
172     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
173     static_cast<APInt&>(*this) *= RHS;
174     return *this;
175   }
176   APSInt& operator&=(const APSInt& RHS) {
177     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
178     static_cast<APInt&>(*this) &= RHS;
179     return *this;
180   }
181   APSInt& operator|=(const APSInt& RHS) {
182     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
183     static_cast<APInt&>(*this) |= RHS;
184     return *this;
185   }
186   APSInt& operator^=(const APSInt& RHS) {
187     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
188     static_cast<APInt&>(*this) ^= RHS;
189     return *this;
190   }
191
192   APSInt operator&(const APSInt& RHS) const {    
193     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
194     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
195   }
196   APSInt And(const APSInt& RHS) const {
197     return this->operator&(RHS);
198   }
199   
200   APSInt operator|(const APSInt& RHS) const {    
201     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
202     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
203   }
204   APSInt Or(const APSInt& RHS) const {
205     return this->operator|(RHS);
206   }
207   
208   
209   APSInt operator^(const APSInt& RHS) const {    
210     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
211     return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
212   }
213   APSInt Xor(const APSInt& RHS) const {
214     return this->operator^(RHS);
215   }  
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-(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 {    
230     return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
231   }
232   
233   /// Profile - Used to insert APSInt objects, or objects that contain APSInt
234   ///  objects, into FoldingSets.
235   void Profile(FoldingSetNodeID& ID) const;
236 };
237   
238 } // end namespace llvm
239
240 #endif