[llvm] r240436 - ADT: Add a string APSInt constructor.

Alex Lorenz arphaman at gmail.com
Tue Jun 23 11:22:10 PDT 2015


Author: arphaman
Date: Tue Jun 23 13:22:10 2015
New Revision: 240436

URL: http://llvm.org/viewvc/llvm-project?rev=240436&view=rev
Log:
ADT: Add a string APSInt constructor.

This commit moves the APSInt initialization code that's used by
the LLLexer class into a new APSInt constructor that constructs
APSInts from strings.

This change is useful for MIR Serialization, as it would allow
the MILexer class to use the same APSInt initialization as 
LLexer when parsing immediate machine operands.

Modified:
    llvm/trunk/include/llvm/ADT/APSInt.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/Support/APSInt.cpp
    llvm/trunk/unittests/ADT/APSIntTest.cpp

Modified: llvm/trunk/include/llvm/ADT/APSInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APSInt.h?rev=240436&r1=240435&r2=240436&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APSInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APSInt.h Tue Jun 23 13:22:10 2015
@@ -33,6 +33,15 @@ public:
   explicit APSInt(APInt I, bool isUnsigned = true)
    : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
 
+  /// Construct an APSInt from a string representation.
+  ///
+  /// This constructor interprets the string \p Str using the radix of 10.
+  /// The interpretation stops at the end of the string. The bit width of the
+  /// constructed APSInt is determined automatically.
+  ///
+  /// \param Str the string to be interpreted.
+  explicit APSInt(StringRef Str);
+
   APSInt &operator=(APInt RHS) {
     // Retain our current sign.
     APInt::operator=(std::move(RHS));

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=240436&r1=240435&r2=240436&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Jun 23 13:22:10 2015
@@ -903,20 +903,7 @@ lltok::Kind LLLexer::LexDigitOrNegative(
   if (CurPtr[0] != '.') {
     if (TokStart[0] == '0' && TokStart[1] == 'x')
       return Lex0x();
-    unsigned Len = CurPtr-TokStart;
-    uint32_t numBits = ((Len * 64) / 19) + 2;
-    APInt Tmp(numBits, StringRef(TokStart, Len), 10);
-    if (TokStart[0] == '-') {
-      uint32_t minBits = Tmp.getMinSignedBits();
-      if (minBits > 0 && minBits < numBits)
-        Tmp = Tmp.trunc(minBits);
-      APSIntVal = APSInt(Tmp, false);
-    } else {
-      uint32_t activeBits = Tmp.getActiveBits();
-      if (activeBits > 0 && activeBits < numBits)
-        Tmp = Tmp.trunc(activeBits);
-      APSIntVal = APSInt(Tmp, true);
-    }
+    APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
     return lltok::APSInt;
   }
 

Modified: llvm/trunk/lib/Support/APSInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APSInt.cpp?rev=240436&r1=240435&r2=240436&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APSInt.cpp (original)
+++ llvm/trunk/lib/Support/APSInt.cpp Tue Jun 23 13:22:10 2015
@@ -17,6 +17,25 @@
 
 using namespace llvm;
 
+APSInt::APSInt(StringRef Str) {
+  assert(!Str.empty() && "Invalid string length");
+
+  // (Over-)estimate the required number of bits.
+  unsigned NumBits = ((Str.size() * 64) / 19) + 2;
+  APInt Tmp(NumBits, Str, /*Radix=*/10);
+  if (Str[0] == '-') {
+    unsigned MinBits = Tmp.getMinSignedBits();
+    if (MinBits > 0 && MinBits < NumBits)
+      Tmp = Tmp.trunc(MinBits);
+    *this = APSInt(Tmp, /*IsUnsigned=*/false);
+    return;
+  }
+  unsigned ActiveBits = Tmp.getActiveBits();
+  if (ActiveBits > 0 && ActiveBits < NumBits)
+    Tmp = Tmp.trunc(ActiveBits);
+  *this = APSInt(Tmp, /*IsUnsigned=*/true);
+}
+
 void APSInt::Profile(FoldingSetNodeID& ID) const {
   ID.AddInteger((unsigned) (IsUnsigned ? 1 : 0));
   APInt::Profile(ID);

Modified: llvm/trunk/unittests/ADT/APSIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APSIntTest.cpp?rev=240436&r1=240435&r2=240436&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APSIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APSIntTest.cpp Tue Jun 23 13:22:10 2015
@@ -143,4 +143,23 @@ TEST(APSIntTest, compareValues) {
   EXPECT_TRUE(APSInt::compareValues(U(8), S(-7).trunc(32)) > 0);
 }
 
+TEST(APSIntTest, FromString) {
+  EXPECT_EQ(APSInt("1").getExtValue(), 1);
+  EXPECT_EQ(APSInt("-1").getExtValue(), -1);
+  EXPECT_EQ(APSInt("0").getExtValue(), 0);
+  EXPECT_EQ(APSInt("56789").getExtValue(), 56789);
+  EXPECT_EQ(APSInt("-1234").getExtValue(), -1234);
 }
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+TEST(APSIntTest, StringDeath) {
+  EXPECT_DEATH(APSInt(""), "Invalid string length");
+  EXPECT_DEATH(APSInt("1a"), "Invalid character in digit string");
+}
+
+#endif
+#endif
+
+} // end anonymous namespace





More information about the llvm-commits mailing list