Add explicit keywords.
[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   /// 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