LCOV - code coverage report
Current view: top level - include/llvm/ADT - APSInt.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 96 96 100.0 %
Date: 2018-06-17 00:07:59 Functions: 27 27 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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_ADT_APSINT_H
      16             : #define LLVM_ADT_APSINT_H
      17             : 
      18             : #include "llvm/ADT/APInt.h"
      19             : 
      20             : namespace llvm {
      21             : 
      22   115611892 : class LLVM_NODISCARD APSInt : public APInt {
      23             :   bool IsUnsigned;
      24             : 
      25             : public:
      26             :   /// Default constructor that creates an uninitialized APInt.
      27    13362956 :   explicit APSInt() : IsUnsigned(false) {}
      28             : 
      29             :   /// APSInt ctor - Create an APSInt with the specified width, default to
      30             :   /// unsigned.
      31     9000451 :   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
      32    46205985 :    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
      33             : 
      34             :   explicit APSInt(APInt I, bool isUnsigned = true)
      35    43234304 :    : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
      36             : 
      37             :   /// Construct an APSInt from a string representation.
      38             :   ///
      39             :   /// This constructor interprets the string \p Str using the radix of 10.
      40             :   /// The interpretation stops at the end of the string. The bit width of the
      41             :   /// constructed APSInt is determined automatically.
      42             :   ///
      43             :   /// \param Str the string to be interpreted.
      44             :   explicit APSInt(StringRef Str);
      45             : 
      46             :   APSInt &operator=(APInt RHS) {
      47             :     // Retain our current sign.
      48             :     APInt::operator=(std::move(RHS));
      49             :     return *this;
      50             :   }
      51             : 
      52             :   APSInt &operator=(uint64_t RHS) {
      53             :     // Retain our current sign.
      54     5504569 :     APInt::operator=(RHS);
      55             :     return *this;
      56             :   }
      57             : 
      58             :   // Query sign information.
      59      210668 :   bool isSigned() const { return !IsUnsigned; }
      60             :   bool isUnsigned() const { return IsUnsigned; }
      61    13250947 :   void setIsUnsigned(bool Val) { IsUnsigned = Val; }
      62      537875 :   void setIsSigned(bool Val) { IsUnsigned = !Val; }
      63             : 
      64             :   /// toString - Append this APSInt to the specified SmallString.
      65             :   void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
      66         460 :     APInt::toString(Str, Radix, isSigned());
      67             :   }
      68             :   /// toString - Converts an APInt to a std::string.  This is an inefficient
      69             :   /// method; you should prefer passing in a SmallString instead.
      70             :   std::string toString(unsigned Radix) const {
      71        3645 :     return APInt::toString(Radix, isSigned());
      72             :   }
      73             :   using APInt::toString;
      74             : 
      75             :   /// Get the correctly-extended \c int64_t value.
      76             :   int64_t getExtValue() const {
      77             :     assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
      78       33718 :     return isSigned() ? getSExtValue() : getZExtValue();
      79             :   }
      80             : 
      81             :   APSInt trunc(uint32_t width) const {
      82     2213412 :     return APSInt(APInt::trunc(width), IsUnsigned);
      83             :   }
      84             : 
      85     4205054 :   APSInt extend(uint32_t width) const {
      86     4205054 :     if (IsUnsigned)
      87      789578 :       return APSInt(zext(width), IsUnsigned);
      88             :     else
      89     7620530 :       return APSInt(sext(width), IsUnsigned);
      90             :   }
      91             : 
      92     4917292 :   APSInt extOrTrunc(uint32_t width) const {
      93     4917292 :     if (IsUnsigned)
      94     6369646 :       return APSInt(zextOrTrunc(width), IsUnsigned);
      95             :     else
      96     3464938 :       return APSInt(sextOrTrunc(width), IsUnsigned);
      97             :   }
      98             : 
      99             :   const APSInt &operator%=(const APSInt &RHS) {
     100             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     101             :     if (IsUnsigned)
     102             :       *this = urem(RHS);
     103             :     else
     104             :       *this = srem(RHS);
     105             :     return *this;
     106             :   }
     107             :   const APSInt &operator/=(const APSInt &RHS) {
     108             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     109             :     if (IsUnsigned)
     110             :       *this = udiv(RHS);
     111             :     else
     112             :       *this = sdiv(RHS);
     113             :     return *this;
     114             :   }
     115        5573 :   APSInt operator%(const APSInt &RHS) const {
     116             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     117       17897 :     return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
     118             :   }
     119      270126 :   APSInt operator/(const APSInt &RHS) const {
     120             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     121     1059989 :     return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
     122             :   }
     123             : 
     124       10619 :   APSInt operator>>(unsigned Amt) const {
     125       33769 :     return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
     126             :   }
     127             :   APSInt& operator>>=(unsigned Amt) {
     128             :     if (IsUnsigned)
     129             :       lshrInPlace(Amt);
     130             :     else
     131             :       ashrInPlace(Amt);
     132             :     return *this;
     133             :   }
     134             : 
     135      538534 :   inline bool operator<(const APSInt& RHS) const {
     136             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     137     1480574 :     return IsUnsigned ? ult(RHS) : slt(RHS);
     138             :   }
     139      350274 :   inline bool operator>(const APSInt& RHS) const {
     140             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     141      943247 :     return IsUnsigned ? ugt(RHS) : sgt(RHS);
     142             :   }
     143      952180 :   inline bool operator<=(const APSInt& RHS) const {
     144             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     145     2483358 :     return IsUnsigned ? ule(RHS) : sle(RHS);
     146             :   }
     147      471967 :   inline bool operator>=(const APSInt& RHS) const {
     148             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     149     1414041 :     return IsUnsigned ? uge(RHS) : sge(RHS);
     150             :   }
     151             :   inline bool operator==(const APSInt& RHS) const {
     152             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     153      649734 :     return eq(RHS);
     154             :   }
     155             :   inline bool operator!=(const APSInt& RHS) const {
     156       36766 :     return !((*this) == RHS);
     157             :   }
     158             : 
     159     1292851 :   bool operator==(int64_t RHS) const {
     160     2585702 :     return compareValues(*this, get(RHS)) == 0;
     161             :   }
     162     5228171 :   bool operator!=(int64_t RHS) const {
     163    10456342 :     return compareValues(*this, get(RHS)) != 0;
     164             :   }
     165           7 :   bool operator<=(int64_t RHS) const {
     166          14 :     return compareValues(*this, get(RHS)) <= 0;
     167             :   }
     168          33 :   bool operator>=(int64_t RHS) const {
     169          66 :     return compareValues(*this, get(RHS)) >= 0;
     170             :   }
     171       19259 :   bool operator<(int64_t RHS) const {
     172       38518 :     return compareValues(*this, get(RHS)) < 0;
     173             :   }
     174       22521 :   bool operator>(int64_t RHS) const {
     175       45042 :     return compareValues(*this, get(RHS)) > 0;
     176             :   }
     177             : 
     178             :   // The remaining operators just wrap the logic of APInt, but retain the
     179             :   // signedness information.
     180             : 
     181             :   APSInt operator<<(unsigned Bits) const {
     182       95320 :     return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
     183             :   }
     184             :   APSInt& operator<<=(unsigned Amt) {
     185             :     static_cast<APInt&>(*this) <<= Amt;
     186             :     return *this;
     187             :   }
     188             : 
     189             :   APSInt& operator++() {
     190      269185 :     ++(static_cast<APInt&>(*this));
     191             :     return *this;
     192             :   }
     193             :   APSInt& operator--() {
     194       69237 :     --(static_cast<APInt&>(*this));
     195             :     return *this;
     196             :   }
     197             :   APSInt operator++(int) {
     198             :     return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
     199             :   }
     200             :   APSInt operator--(int) {
     201             :     return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
     202             :   }
     203      366132 :   APSInt operator-() const {
     204      732264 :     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
     205             :   }
     206             :   APSInt& operator+=(const APSInt& RHS) {
     207             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     208         102 :     static_cast<APInt&>(*this) += RHS;
     209             :     return *this;
     210             :   }
     211             :   APSInt& operator-=(const APSInt& RHS) {
     212             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     213          30 :     static_cast<APInt&>(*this) -= RHS;
     214             :     return *this;
     215             :   }
     216             :   APSInt& operator*=(const APSInt& RHS) {
     217             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     218          17 :     static_cast<APInt&>(*this) *= RHS;
     219             :     return *this;
     220             :   }
     221             :   APSInt& operator&=(const APSInt& RHS) {
     222             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     223          18 :     static_cast<APInt&>(*this) &= RHS;
     224             :     return *this;
     225             :   }
     226             :   APSInt& operator|=(const APSInt& RHS) {
     227             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     228             :     static_cast<APInt&>(*this) |= RHS;
     229             :     return *this;
     230             :   }
     231             :   APSInt& operator^=(const APSInt& RHS) {
     232             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     233             :     static_cast<APInt&>(*this) ^= RHS;
     234             :     return *this;
     235             :   }
     236             : 
     237        8043 :   APSInt operator&(const APSInt& RHS) const {
     238             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     239       16086 :     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
     240             :   }
     241             : 
     242       10681 :   APSInt operator|(const APSInt& RHS) const {
     243             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     244       21362 :     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
     245             :   }
     246             : 
     247          83 :   APSInt operator^(const APSInt &RHS) const {
     248             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     249         166 :     return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
     250             :   }
     251             : 
     252             :   APSInt operator*(const APSInt& RHS) const {
     253             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     254      207251 :     return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
     255             :   }
     256      341818 :   APSInt operator+(const APSInt& RHS) const {
     257             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     258      683636 :     return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
     259             :   }
     260      947821 :   APSInt operator-(const APSInt& RHS) const {
     261             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     262     1895642 :     return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
     263             :   }
     264        4853 :   APSInt operator~() const {
     265        9706 :     return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
     266             :   }
     267             : 
     268             :   /// getMaxValue - Return the APSInt representing the maximum integer value
     269             :   ///  with the given bit width and signedness.
     270      206749 :   static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
     271      568100 :     return APSInt(Unsigned ? APInt::getMaxValue(numBits)
     272      206749 :                            : APInt::getSignedMaxValue(numBits), Unsigned);
     273             :   }
     274             : 
     275             :   /// getMinValue - Return the APSInt representing the minimum integer value
     276             :   ///  with the given bit width and signedness.
     277      240321 :   static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
     278      480642 :     return APSInt(Unsigned ? APInt::getMinValue(numBits)
     279      240321 :                            : APInt::getSignedMinValue(numBits), Unsigned);
     280             :   }
     281             : 
     282             :   /// Determine if two APSInts have the same value, zero- or
     283             :   /// sign-extending as needed.
     284             :   static bool isSameValue(const APSInt &I1, const APSInt &I2) {
     285        9213 :     return !compareValues(I1, I2);
     286             :   }
     287             : 
     288             :   /// Compare underlying values of two numbers.
     289     7708540 :   static int compareValues(const APSInt &I1, const APSInt &I2) {
     290     7708540 :     if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
     291     6301876 :       return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
     292             : 
     293             :     // Check for a bit-width mismatch.
     294     1440933 :     if (I1.getBitWidth() > I2.getBitWidth())
     295       12068 :       return compareValues(I1, I2.extend(I1.getBitWidth()));
     296     1434899 :     if (I2.getBitWidth() > I1.getBitWidth())
     297     1857068 :       return compareValues(I1.extend(I2.getBitWidth()), I2);
     298             : 
     299             :     // We have a signedness mismatch. Check for negative values and do an
     300             :     // unsigned compare if both are positive.
     301      506365 :     if (I1.isSigned()) {
     302             :       assert(!I2.isSigned() && "Expected signed mismatch");
     303        1018 :       if (I1.isNegative())
     304             :         return -1;
     305             :     } else {
     306             :       assert(I2.isSigned() && "Expected signed mismatch");
     307     1011712 :       if (I2.isNegative())
     308             :         return 1;
     309             :     }
     310             : 
     311      506173 :     return I1.compare(I2);
     312             :   }
     313             : 
     314    13147724 :   static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
     315        6505 :   static APSInt getUnsigned(uint64_t X) { return APSInt(APInt(64, X), true); }
     316             : 
     317             :   /// Profile - Used to insert APSInt objects, or objects that contain APSInt
     318             :   ///  objects, into FoldingSets.
     319             :   void Profile(FoldingSetNodeID& ID) const;
     320             : };
     321             : 
     322           2 : inline bool operator==(int64_t V1, const APSInt &V2) { return V2 == V1; }
     323       57667 : inline bool operator!=(int64_t V1, const APSInt &V2) { return V2 != V1; }
     324             : inline bool operator<=(int64_t V1, const APSInt &V2) { return V2 >= V1; }
     325             : inline bool operator>=(int64_t V1, const APSInt &V2) { return V2 <= V1; }
     326          23 : inline bool operator<(int64_t V1, const APSInt &V2) { return V2 > V1; }
     327          13 : inline bool operator>(int64_t V1, const APSInt &V2) { return V2 < V1; }
     328             : 
     329             : inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
     330       66438 :   I.print(OS, I.isSigned());
     331             :   return OS;
     332             : }
     333             : 
     334             : } // end namespace llvm
     335             : 
     336             : #endif

Generated by: LCOV version 1.13