17f46734b66306bb81720fbe617c15b1184b13807Ted Kremenek//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
2db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//
3db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//                     The LLVM Compiler Infrastructure
4db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//
8db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//===----------------------------------------------------------------------===//
9db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//
10db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// This file implements the APSInt class, which is a simple class that
11db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// represents an arbitrary sized integer that knows its signedness.
12db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//
13db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//===----------------------------------------------------------------------===//
14db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_ADT_APSINT_H
16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_ADT_APSINT_H
17db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
18db8918a98ff001d0c37abf41bc62364595340035Chris Lattner#include "llvm/ADT/APInt.h"
19db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
20db8918a98ff001d0c37abf41bc62364595340035Chris Lattnernamespace llvm {
213a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
22db8918a98ff001d0c37abf41bc62364595340035Chris Lattnerclass APSInt : public APInt {
23db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  bool IsUnsigned;
24db8918a98ff001d0c37abf41bc62364595340035Chris Lattnerpublic:
257fb842420a87d984196454b3e43fc54267f79edcDaniel Dunbar  /// Default constructor that creates an uninitialized APInt.
26e8ce626308eb047d226847660e7dceed1169038fRichard Smith  explicit APSInt() : IsUnsigned(false) {}
277fb842420a87d984196454b3e43fc54267f79edcDaniel Dunbar
28db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  /// APSInt ctor - Create an APSInt with the specified width, default to
29db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  /// unsigned.
303a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
31d25c9cd3ff5786655201c550ae76f1b89815e1c7Ted Kremenek   : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
32cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  explicit APSInt(APInt I, bool isUnsigned = true)
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
35db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  APSInt &operator=(APInt RHS) {
37db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    // Retain our current sign.
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    APInt::operator=(std::move(RHS));
39db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return *this;
40db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
41db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
42db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  APSInt &operator=(uint64_t RHS) {
43db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    // Retain our current sign.
443a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman    APInt::operator=(RHS);
45db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return *this;
46db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
47db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
48db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  // Query sign information.
49db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  bool isSigned() const { return !IsUnsigned; }
50db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  bool isUnsigned() const { return IsUnsigned; }
51db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  void setIsUnsigned(bool Val) { IsUnsigned = Val; }
52f7b71c64cfe805d0a48d18d55a739ce8a7e6851aChris Lattner  void setIsSigned(bool Val) { IsUnsigned = !Val; }
533a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
54fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  /// toString - Append this APSInt to the specified SmallString.
55fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
56af9b6b264f2bf4315c25b286a1c24331038545e0Bill Wendling    APInt::toString(Str, Radix, isSigned());
57fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  }
58fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  /// toString - Converts an APInt to a std::string.  This is an inefficient
59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  /// method; you should prefer passing in a SmallString instead.
60fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  std::string toString(unsigned Radix) const {
61028760fd88081964ace51e4205e28ff52fc1f47aChris Lattner    return APInt::toString(Radix, isSigned());
629132a2b81842b0e2b77703fab3e6fe7467f859bbChris Lattner  }
63fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  using APInt::toString;
643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Get the correctly-extended \c int64_t value.
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  int64_t getExtValue() const {
67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return isSigned() ? getSExtValue() : getZExtValue();
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
71b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const {
7240f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad    return APSInt(APInt::trunc(width), IsUnsigned);
7340f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad  }
7440f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad
75b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extend(uint32_t width) const {
76cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    if (IsUnsigned)
7740f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad      return APSInt(zext(width), IsUnsigned);
78cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    else
7940f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad      return APSInt(sext(width), IsUnsigned);
80cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
813a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
82b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extOrTrunc(uint32_t width) const {
83cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek      if (IsUnsigned)
8440f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad        return APSInt(zextOrTrunc(width), IsUnsigned);
85cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek      else
8640f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad        return APSInt(sextOrTrunc(width), IsUnsigned);
87cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
883a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
89db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  const APSInt &operator%=(const APSInt &RHS) {
90db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
91db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    if (IsUnsigned)
92db8918a98ff001d0c37abf41bc62364595340035Chris Lattner      *this = urem(RHS);
93db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    else
94db8918a98ff001d0c37abf41bc62364595340035Chris Lattner      *this = srem(RHS);
95db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return *this;
96db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
97db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  const APSInt &operator/=(const APSInt &RHS) {
98db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
99db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    if (IsUnsigned)
100db8918a98ff001d0c37abf41bc62364595340035Chris Lattner      *this = udiv(RHS);
101db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    else
102db8918a98ff001d0c37abf41bc62364595340035Chris Lattner      *this = sdiv(RHS);
103db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return *this;
104db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
105403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner  APSInt operator%(const APSInt &RHS) const {
106403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
107cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
108403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner  }
109403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner  APSInt operator/(const APSInt &RHS) const {
110403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
111cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
112403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner  }
1133a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
114cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator>>(unsigned Amt) const {
115cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
116db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
117cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator>>=(unsigned Amt) {
118cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    *this = *this >> Amt;
1197ccd9ec4f40d1cdf740c98dab8e212943a4b4863Anders Carlsson    return *this;
1207ccd9ec4f40d1cdf740c98dab8e212943a4b4863Anders Carlsson  }
1213a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
122db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  inline bool operator<(const APSInt& RHS) const {
123db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
124db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return IsUnsigned ? ult(RHS) : slt(RHS);
125db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
126db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  inline bool operator>(const APSInt& RHS) const {
127db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
128db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return IsUnsigned ? ugt(RHS) : sgt(RHS);
129db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
130db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  inline bool operator<=(const APSInt& RHS) const {
131db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
132db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return IsUnsigned ? ule(RHS) : sle(RHS);
133db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
134db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  inline bool operator>=(const APSInt& RHS) const {
135db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
136db8918a98ff001d0c37abf41bc62364595340035Chris Lattner    return IsUnsigned ? uge(RHS) : sge(RHS);
137db8918a98ff001d0c37abf41bc62364595340035Chris Lattner  }
1385e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu  inline bool operator==(const APSInt& RHS) const {
1395e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
1405e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu    return eq(RHS);
1415e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu  }
1425e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu  inline bool operator!=(const APSInt& RHS) const {
1435e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu    return !((*this) == RHS);
1445e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu  }
145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator==(int64_t RHS) const {
147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) == 0;
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator!=(int64_t RHS) const {
150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) != 0;
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator<=(int64_t RHS) const {
153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) <= 0;
154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator>=(int64_t RHS) const {
156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) >= 0;
157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator<(int64_t RHS) const {
159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) < 0;
160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool operator>(int64_t RHS) const {
162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return compareValues(*this, get(RHS)) > 0;
1635e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu  }
1643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
165cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  // The remaining operators just wrap the logic of APInt, but retain the
166cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  // signedness information.
1673a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
16886383e1f7cc8c31eafc6e3d8a67ce6f23d1bce63Ted Kremenek  APSInt operator<<(unsigned Bits) const {
16986383e1f7cc8c31eafc6e3d8a67ce6f23d1bce63Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
1703a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
171cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator<<=(unsigned Amt) {
172cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    *this = *this << Amt;
173cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
174cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
1753a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
176cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator++() {
1772adf8ccbf0611df6393c30737d87faaf38cdcd0cJakub Staszak    ++(static_cast<APInt&>(*this));
178cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
179cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
180cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator--() {
1812adf8ccbf0611df6393c30737d87faaf38cdcd0cJakub Staszak    --(static_cast<APInt&>(*this));
182cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
183cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
184cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator++(int) {
185cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
186cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
187cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator--(int) {
188cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
1893a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
190cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator-() const {
191cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
1923a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
193cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator+=(const APSInt& RHS) {
194cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
195cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) += RHS;
196cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
1973a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
198cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator-=(const APSInt& RHS) {
199cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
200cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) -= RHS;
201cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
2023a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
203cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator*=(const APSInt& RHS) {
204cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
205cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) *= RHS;
206cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
207cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
208cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator&=(const APSInt& RHS) {
209cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
210cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) &= RHS;
211cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
212cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
213cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator|=(const APSInt& RHS) {
214cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
215cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) |= RHS;
216cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
217cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
218cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt& operator^=(const APSInt& RHS) {
219cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
220cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    static_cast<APInt&>(*this) ^= RHS;
221cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return *this;
222cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
223cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek
2243a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  APSInt operator&(const APSInt& RHS) const {
225cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
226cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
227cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
228b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APSInt& RHS) const {
229cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return this->operator&(RHS);
230cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
2313a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
2323a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  APSInt operator|(const APSInt& RHS) const {
233cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
234cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
235cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
236b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APSInt& RHS) const {
237cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return this->operator|(RHS);
238cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
2393a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
2403a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
2413a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  APSInt operator^(const APSInt& RHS) const {
242cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
243cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
244cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
245b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APSInt& RHS) const {
246cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return this->operator^(RHS);
2473a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  }
2483a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
249cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator*(const APSInt& RHS) const {
250cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
251cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
252cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
2533a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  APSInt operator+(const APSInt& RHS) const {
254cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
255cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
256cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
257cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  APSInt operator-(const APSInt& RHS) const {
258cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
259cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
260cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
2613a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman  APSInt operator~() const {
262cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek    return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
263cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek  }
2643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
265ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  /// getMaxValue - Return the APSInt representing the maximum integer value
266ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  ///  with the given bit width and signedness.
267072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner  static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
268072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner    return APSInt(Unsigned ? APInt::getMaxValue(numBits)
269072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner                           : APInt::getSignedMaxValue(numBits), Unsigned);
270ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  }
2713a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
272ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  /// getMinValue - Return the APSInt representing the minimum integer value
273ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  ///  with the given bit width and signedness.
274072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner  static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
275072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner    return APSInt(Unsigned ? APInt::getMinValue(numBits)
276072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner                           : APInt::getSignedMinValue(numBits), Unsigned);
277ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek  }
2783a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
2795449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher  /// \brief Determine if two APSInts have the same value, zero- or
2805449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher  /// sign-extending as needed.
2815449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher  static bool isSameValue(const APSInt &I1, const APSInt &I2) {
282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return !compareValues(I1, I2);
283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Compare underlying values of two numbers.
286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  static int compareValues(const APSInt &I1, const APSInt &I2) {
2875449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher    if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return I1 == I2 ? 0 : I1 > I2 ? 1 : -1;
2895449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher
2905449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher    // Check for a bit-width mismatch.
2915449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher    if (I1.getBitWidth() > I2.getBitWidth())
292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return compareValues(I1, I2.extend(I1.getBitWidth()));
2935449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher    else if (I2.getBitWidth() > I1.getBitWidth())
294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return compareValues(I1.extend(I2.getBitWidth()), I2);
2955449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher
29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // We have a signedness mismatch. Check for negative values and do an
297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // unsigned compare if both are positive.
298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (I1.isSigned()) {
299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(!I2.isSigned() && "Expected signed mismatch");
300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (I1.isNegative())
301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return -1;
302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(I2.isSigned() && "Expected signed mismatch");
304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (I2.isNegative())
305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return 1;
306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
3075449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher
308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1;
3095449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher  }
3105449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher
311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  static APSInt getUnsigned(uint64_t X) { return APSInt(APInt(64, X), true); }
313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3144048a082847cea72431aa8235f54941ed064913bTed Kremenek  /// Profile - Used to insert APSInt objects, or objects that contain APSInt
3154048a082847cea72431aa8235f54941ed064913bTed Kremenek  ///  objects, into FoldingSets.
3164048a082847cea72431aa8235f54941ed064913bTed Kremenek  void Profile(FoldingSetNodeID& ID) const;
317db8918a98ff001d0c37abf41bc62364595340035Chris Lattner};
3183a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator==(int64_t V1, const APSInt &V2) { return V2 == V1; }
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator!=(int64_t V1, const APSInt &V2) { return V2 != V1; }
321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator<=(int64_t V1, const APSInt &V2) { return V2 >= V1; }
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator>=(int64_t V1, const APSInt &V2) { return V2 <= V1; }
323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator<(int64_t V1, const APSInt &V2) { return V2 > V1; }
324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator>(int64_t V1, const APSInt &V2) { return V2 < V1; }
3255e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu
326944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattnerinline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
327fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  I.print(OS, I.isSigned());
328fad86b003a839cef40ec8ce8408322f4913368caChris Lattner  return OS;
329fad86b003a839cef40ec8ce8408322f4913368caChris Lattner}
3303a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
331db8918a98ff001d0c37abf41bc62364595340035Chris Lattner} // end namespace llvm
332db8918a98ff001d0c37abf41bc62364595340035Chris Lattner
333db8918a98ff001d0c37abf41bc62364595340035Chris Lattner#endif
334