LCOV - code coverage report
Current view: top level - include/llvm/ADT - APSInt.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 102 103 99.0 %
Date: 2018-10-20 13:21:21 Functions: 27 29 93.1 %
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   292470143 : class LLVM_NODISCARD APSInt : public APInt {
      23             :   bool IsUnsigned;
      24             : 
      25             : public:
      26             :   /// Default constructor that creates an uninitialized APInt.
      27    30151849 :   explicit APSInt() : IsUnsigned(false) {}
      28             : 
      29             :   /// APSInt ctor - Create an APSInt with the specified width, default to
      30             :   /// unsigned.
      31    32619332 :   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
      32   134066224 :    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
      33             : 
      34             :   explicit APSInt(APInt I, bool isUnsigned = true)
      35    80638657 :    : 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    32145943 :     APInt::operator=(RHS);
      55             :     return *this;
      56             :   }
      57             : 
      58             :   // Query sign information.
      59     1779258 :   bool isSigned() const { return !IsUnsigned; }
      60           0 :   bool isUnsigned() const { return IsUnsigned; }
      61    32789710 :   void setIsUnsigned(bool Val) { IsUnsigned = Val; }
      62     1605856 :   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         308 :     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        2080 :     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       50938 :     return isSigned() ? getSExtValue() : getZExtValue();
      79             :   }
      80             : 
      81             :   APSInt trunc(uint32_t width) const {
      82      174120 :     return APSInt(APInt::trunc(width), IsUnsigned);
      83             :   }
      84             : 
      85     6674034 :   APSInt extend(uint32_t width) const {
      86     6674034 :     if (IsUnsigned)
      87      609064 :       return APSInt(zext(width), IsUnsigned);
      88             :     else
      89     6064970 :       return APSInt(sext(width), IsUnsigned);
      90             :   }
      91             : 
      92    22105165 :   APSInt extOrTrunc(uint32_t width) const {
      93    22105165 :     if (IsUnsigned)
      94    13838709 :       return APSInt(zextOrTrunc(width), IsUnsigned);
      95             :     else
      96     8266456 :       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      138781 :   APSInt operator%(const APSInt &RHS) const {
     116             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     117      277562 :     return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
     118             :   }
     119     1027913 :   APSInt operator/(const APSInt &RHS) const {
     120             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     121     2055826 :     return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
     122             :   }
     123             : 
     124       18910 :   APSInt operator>>(unsigned Amt) const {
     125       37820 :     return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
     126             :   }
     127         196 :   APSInt& operator>>=(unsigned Amt) {
     128         196 :     if (IsUnsigned)
     129          84 :       lshrInPlace(Amt);
     130             :     else
     131         112 :       ashrInPlace(Amt);
     132         196 :     return *this;
     133             :   }
     134             : 
     135     1941847 :   inline bool operator<(const APSInt& RHS) const {
     136             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     137     1941847 :     return IsUnsigned ? ult(RHS) : slt(RHS);
     138             :   }
     139     1778794 :   inline bool operator>(const APSInt& RHS) const {
     140             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     141     1778794 :     return IsUnsigned ? ugt(RHS) : sgt(RHS);
     142             :   }
     143     1768942 :   inline bool operator<=(const APSInt& RHS) const {
     144             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     145     1768942 :     return IsUnsigned ? ule(RHS) : sle(RHS);
     146             :   }
     147     1208435 :   inline bool operator>=(const APSInt& RHS) const {
     148             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     149     1208435 :     return IsUnsigned ? uge(RHS) : sge(RHS);
     150             :   }
     151             :   inline bool operator==(const APSInt& RHS) const {
     152             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     153     6184851 :     return eq(RHS);
     154             :   }
     155             :   inline bool operator!=(const APSInt& RHS) const {
     156      180822 :     return !((*this) == RHS);
     157             :   }
     158             : 
     159     4831088 :   bool operator==(int64_t RHS) const {
     160     4831088 :     return compareValues(*this, get(RHS)) == 0;
     161             :   }
     162    21569964 :   bool operator!=(int64_t RHS) const {
     163    21569964 :     return compareValues(*this, get(RHS)) != 0;
     164             :   }
     165           7 :   bool operator<=(int64_t RHS) const {
     166           7 :     return compareValues(*this, get(RHS)) <= 0;
     167             :   }
     168        6397 :   bool operator>=(int64_t RHS) const {
     169        6397 :     return compareValues(*this, get(RHS)) >= 0;
     170             :   }
     171      267692 :   bool operator<(int64_t RHS) const {
     172      267692 :     return compareValues(*this, get(RHS)) < 0;
     173             :   }
     174      273531 :   bool operator>(int64_t RHS) const {
     175      273531 :     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      406940 :     return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
     183             :   }
     184             :   APSInt& operator<<=(unsigned Amt) {
     185         120 :     static_cast<APInt&>(*this) <<= Amt;
     186             :     return *this;
     187             :   }
     188             : 
     189             :   APSInt& operator++() {
     190      904619 :     ++(static_cast<APInt&>(*this));
     191             :     return *this;
     192             :   }
     193             :   APSInt& operator--() {
     194       79635 :     --(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      420775 :   APSInt operator-() const {
     204      420775 :     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
     205             :   }
     206             :   APSInt& operator+=(const APSInt& RHS) {
     207             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     208          51 :     static_cast<APInt&>(*this) += RHS;
     209             :     return *this;
     210             :   }
     211             :   APSInt& operator-=(const APSInt& RHS) {
     212             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     213          15 :     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       51930 :   APSInt operator&(const APSInt& RHS) const {
     238             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     239       51930 :     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
     240             :   }
     241             : 
     242      113039 :   APSInt operator|(const APSInt& RHS) const {
     243             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     244      113039 :     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
     245             :   }
     246             : 
     247        8147 :   APSInt operator^(const APSInt &RHS) const {
     248             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     249        8147 :     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        1084 :     return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
     255             :   }
     256      532055 :   APSInt operator+(const APSInt& RHS) const {
     257             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     258      532055 :     return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
     259             :   }
     260     1305109 :   APSInt operator-(const APSInt& RHS) const {
     261             :     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
     262     1305109 :     return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
     263             :   }
     264       79881 :   APSInt operator~() const {
     265       79881 :     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      641914 :   static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
     271      641914 :     return APSInt(Unsigned ? APInt::getMaxValue(numBits)
     272      641914 :                            : 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      673020 :   static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
     278      673020 :     return APSInt(Unsigned ? APInt::getMinValue(numBits)
     279      673020 :                            : 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       16997 :     return !compareValues(I1, I2);
     286             :   }
     287             : 
     288             :   /// Compare underlying values of two numbers.
     289    29617155 :   static int compareValues(const APSInt &I1, const APSInt &I2) {
     290    29617155 :     if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
     291    26675612 :       return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
     292             : 
     293             :     // Check for a bit-width mismatch.
     294     2941543 :     if (I1.getBitWidth() > I2.getBitWidth())
     295       13632 :       return compareValues(I1, I2.extend(I1.getBitWidth()));
     296     2934727 :     if (I2.getBitWidth() > I1.getBitWidth())
     297     3422940 :       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     1223257 :     if (I1.isSigned()) {
     302             :       assert(!I2.isSigned() && "Expected signed mismatch");
     303         473 :       if (I1.isNegative())
     304             :         return -1;
     305             :     } else {
     306             :       assert(I2.isSigned() && "Expected signed mismatch");
     307     1222794 :       if (I2.isNegative())
     308             :         return 1;
     309             :     }
     310             : 
     311     1223051 :     return I1.compare(I2);
     312             :   }
     313             : 
     314    27152399 :   static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
     315        5852 :   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      425020 : 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      553579 :   I.print(OS, I.isSigned());
     331             :   return OS;
     332             : }
     333             : 
     334             : } // end namespace llvm
     335             : 
     336             : #endif

Generated by: LCOV version 1.13