[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