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: 2017-09-14 15:23:50 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   123591587 : class LLVM_NODISCARD APSInt : public APInt {
      23             :   bool IsUnsigned;
      24             : 
      25             : public:
      26             :   /// Default constructor that creates an uninitialized APInt.
      27     7892380 :   explicit APSInt() : IsUnsigned(false) {}
      28             : 
      29             :   /// APSInt ctor - Create an APSInt with the specified width, default to
      30             :   /// unsigned.
      31     1969267 :   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
      32    16946397 :    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
      33             : 
      34             :   explicit APSInt(APInt I, bool isUnsigned = true)
      35    28563278 :    : 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       29082 :     APInt::operator=(std::move(RHS));
      49             :     return *this;
      50             :   }
      51             : 
      52             :   APSInt &operator=(uint64_t RHS) {
      53             :     // Retain our current sign.
      54     1214370 :     APInt::operator=(RHS);
      55             :     return *this;
      56             :   }
      57             : 
      58             :   // Query sign information.
      59       79337 :   bool isSigned() const { return !IsUnsigned; }
      60             :   bool isUnsigned() const { return IsUnsigned; }
      61     3077980 :   void setIsUnsigned(bool Val) { IsUnsigned = Val; }
      62      196315 :   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         470 :     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        3048 :     return APInt::toString(Radix, isSigned());
      72             :   }
      73             :   using APInt::toString;
      74             : 
      75             :   /// \brief Get the correctly-extended \c int64_t value.
      76             :   int64_t getExtValue() const {
      77             :     assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
      78       47531 :     return isSigned() ? getSExtValue() : getZExtValue();
      79             :   }
      80             : 
      81             :   APSInt trunc(uint32_t width) const {
      82     1487391 :     return APSInt(APInt::trunc(width), IsUnsigned);
      83             :   }
      84             : 
      85     2197907 :   APSInt extend(uint32_t width) const {
      86     2197907 :     if (IsUnsigned)
      87      151137 :       return APSInt(zext(width), IsUnsigned);
      88             :     else
      89     6442584 :       return APSInt(sext(width), IsUnsigned);
      90             :   }
      91             : 
      92     2378295 :   APSInt extOrTrunc(uint32_t width) const {
      93     2378295 :     if (IsUnsigned)
      94     4786395 :       return APSInt(zextOrTrunc(width), IsUnsigned);
      95             :     else
      96     2348490 :       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         382 :   APSInt operator%(const APSInt &RHS) const {
     116             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     117        1350 :     return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
     118             :   }
     119      109360 :   APSInt operator/(const APSInt &RHS) const {
     120             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     121      432746 :     return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
     122             :   }
     123             : 
     124        9528 :   APSInt operator>>(unsigned Amt) const {
     125       31089 :     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      276273 :   inline bool operator<(const APSInt& RHS) const {
     136             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     137      552546 :     return IsUnsigned ? ult(RHS) : slt(RHS);
     138             :   }
     139      188198 :   inline bool operator>(const APSInt& RHS) const {
     140             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     141      376396 :     return IsUnsigned ? ugt(RHS) : sgt(RHS);
     142             :   }
     143      641513 :   inline bool operator<=(const APSInt& RHS) const {
     144             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     145     1283026 :     return IsUnsigned ? ule(RHS) : sle(RHS);
     146             :   }
     147       38237 :   inline bool operator>=(const APSInt& RHS) const {
     148             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     149       76474 :     return IsUnsigned ? uge(RHS) : sge(RHS);
     150             :   }
     151             :   inline bool operator==(const APSInt& RHS) const {
     152             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     153     1349950 :     return eq(RHS);
     154             :   }
     155             :   inline bool operator!=(const APSInt& RHS) const {
     156      527293 :     return !((*this) == RHS);
     157             :   }
     158             : 
     159      527311 :   bool operator==(int64_t RHS) const {
     160     1054622 :     return compareValues(*this, get(RHS)) == 0;
     161             :   }
     162      792280 :   bool operator!=(int64_t RHS) const {
     163     1584560 :     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       18284 :   bool operator<(int64_t RHS) const {
     172       36568 :     return compareValues(*this, get(RHS)) < 0;
     173             :   }
     174       21489 :   bool operator>(int64_t RHS) const {
     175       42978 :     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       59692 :     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      143008 :     ++(static_cast<APInt&>(*this));
     191             :     return *this;
     192             :   }
     193             :   APSInt& operator--() {
     194       62681 :     --(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      214639 :   APSInt operator-() const {
     204     1287834 :     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
     205             :   }
     206             :   APSInt& operator+=(const APSInt& RHS) {
     207             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     208          96 :     static_cast<APInt&>(*this) += RHS;
     209             :     return *this;
     210             :   }
     211             :   APSInt& operator-=(const APSInt& RHS) {
     212             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     213          20 :     static_cast<APInt&>(*this) -= RHS;
     214             :     return *this;
     215             :   }
     216             :   APSInt& operator*=(const APSInt& RHS) {
     217             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     218           7 :     static_cast<APInt&>(*this) *= RHS;
     219             :     return *this;
     220             :   }
     221             :   APSInt& operator&=(const APSInt& RHS) {
     222             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     223          36 :     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       23549 :   APSInt operator&(const APSInt& RHS) const {
     238             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     239      141294 :     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
     240             :   }
     241             : 
     242        6096 :   APSInt operator|(const APSInt& RHS) const {
     243             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     244       36576 :     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
     245             :   }
     246             : 
     247          59 :   APSInt operator^(const APSInt &RHS) const {
     248             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     249         354 :     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       88392 :     return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
     255             :   }
     256      169551 :   APSInt operator+(const APSInt& RHS) const {
     257             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     258     1017306 :     return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
     259             :   }
     260      480622 :   APSInt operator-(const APSInt& RHS) const {
     261             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     262     2883732 :     return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
     263             :   }
     264        3116 :   APSInt operator~() const {
     265       18696 :     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      106153 :   static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
     271      272902 :     return APSInt(Unsigned ? APInt::getMaxValue(numBits)
     272      212306 :                            : 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      106817 :   static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
     278      213634 :     return APSInt(Unsigned ? APInt::getMinValue(numBits)
     279      213634 :                            : APInt::getSignedMinValue(numBits), Unsigned);
     280             :   }
     281             : 
     282             :   /// \brief 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        2202 :     return !compareValues(I1, I2);
     286             :   }
     287             : 
     288             :   /// \brief Compare underlying values of two numbers.
     289     2090532 :   static int compareValues(const APSInt &I1, const APSInt &I2) {
     290     2090532 :     if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
     291     1219207 :       return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
     292             : 
     293             :     // Check for a bit-width mismatch.
     294      872923 :     if (I1.getBitWidth() > I2.getBitWidth())
     295       10988 :       return compareValues(I1, I2.extend(I1.getBitWidth()));
     296      867429 :     if (I2.getBitWidth() > I1.getBitWidth())
     297     1445666 :       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      144596 :     if (I1.isSigned()) {
     302             :       assert(!I2.isSigned() && "Expected signed mismatch");
     303         918 :       if (I1.isNegative())
     304             :         return -1;
     305             :     } else {
     306             :       assert(I2.isSigned() && "Expected signed mismatch");
     307      288274 :       if (I2.isNegative())
     308             :         return 1;
     309             :     }
     310             : 
     311      138662 :     return I1.compare(I2);
     312             :   }
     313             : 
     314     5467640 :   static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
     315       18183 :   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       24146 : 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             : 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       22852 :   I.print(OS, I.isSigned());
     331             :   return OS;
     332             : }
     333             : 
     334             : } // end namespace llvm
     335             : 
     336             : #endif

Generated by: LCOV version 1.13