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

Duncan P. N. Exon Smith dexonsmith at apple.com
Wed Jun 24 09:16:24 PDT 2015


> On 2015 Jun 23, at 11:22, Alex Lorenz <arphaman at gmail.com> wrote:
> 
> 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

I think you can merge these checks:

    #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)

Then you just have a single closing #endif.  Seems a little cleaner
to me.

> +
> +TEST(APSIntTest, StringDeath) {
> +  EXPECT_DEATH(APSInt(""), "Invalid string length");
> +  EXPECT_DEATH(APSInt("1a"), "Invalid character in digit string");
> +}
> +
> +#endif
> +#endif
> +
> +} // end anonymous namespace
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list