llvm.org GIT mirror llvm / 1c5cf24
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240436 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 5 years ago
4 changed file(s) with 48 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
3131
3232 explicit APSInt(APInt I, bool isUnsigned = true)
3333 : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
34
35 /// Construct an APSInt from a string representation.
36 ///
37 /// This constructor interprets the string \p Str using the radix of 10.
38 /// The interpretation stops at the end of the string. The bit width of the
39 /// constructed APSInt is determined automatically.
40 ///
41 /// \param Str the string to be interpreted.
42 explicit APSInt(StringRef Str);
3443
3544 APSInt &operator=(APInt RHS) {
3645 // Retain our current sign.
902902 if (CurPtr[0] != '.') {
903903 if (TokStart[0] == '0' && TokStart[1] == 'x')
904904 return Lex0x();
905 unsigned Len = CurPtr-TokStart;
906 uint32_t numBits = ((Len * 64) / 19) + 2;
907 APInt Tmp(numBits, StringRef(TokStart, Len), 10);
908 if (TokStart[0] == '-') {
909 uint32_t minBits = Tmp.getMinSignedBits();
910 if (minBits > 0 && minBits < numBits)
911 Tmp = Tmp.trunc(minBits);
912 APSIntVal = APSInt(Tmp, false);
913 } else {
914 uint32_t activeBits = Tmp.getActiveBits();
915 if (activeBits > 0 && activeBits < numBits)
916 Tmp = Tmp.trunc(activeBits);
917 APSIntVal = APSInt(Tmp, true);
918 }
905 APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
919906 return lltok::APSInt;
920907 }
921908
1616
1717 using namespace llvm;
1818
19 APSInt::APSInt(StringRef Str) {
20 assert(!Str.empty() && "Invalid string length");
21
22 // (Over-)estimate the required number of bits.
23 unsigned NumBits = ((Str.size() * 64) / 19) + 2;
24 APInt Tmp(NumBits, Str, /*Radix=*/10);
25 if (Str[0] == '-') {
26 unsigned MinBits = Tmp.getMinSignedBits();
27 if (MinBits > 0 && MinBits < NumBits)
28 Tmp = Tmp.trunc(MinBits);
29 *this = APSInt(Tmp, /*IsUnsigned=*/false);
30 return;
31 }
32 unsigned ActiveBits = Tmp.getActiveBits();
33 if (ActiveBits > 0 && ActiveBits < NumBits)
34 Tmp = Tmp.trunc(ActiveBits);
35 *this = APSInt(Tmp, /*IsUnsigned=*/true);
36 }
37
1938 void APSInt::Profile(FoldingSetNodeID& ID) const {
2039 ID.AddInteger((unsigned) (IsUnsigned ? 1 : 0));
2140 APInt::Profile(ID);
142142 EXPECT_TRUE(APSInt::compareValues(U(8), S(-7).trunc(32)) > 0);
143143 }
144144
145 TEST(APSIntTest, FromString) {
146 EXPECT_EQ(APSInt("1").getExtValue(), 1);
147 EXPECT_EQ(APSInt("-1").getExtValue(), -1);
148 EXPECT_EQ(APSInt("0").getExtValue(), 0);
149 EXPECT_EQ(APSInt("56789").getExtValue(), 56789);
150 EXPECT_EQ(APSInt("-1234").getExtValue(), -1234);
145151 }
152
153 #ifdef GTEST_HAS_DEATH_TEST
154 #ifndef NDEBUG
155
156 TEST(APSIntTest, StringDeath) {
157 EXPECT_DEATH(APSInt(""), "Invalid string length");
158 EXPECT_DEATH(APSInt("1a"), "Invalid character in digit string");
159 }
160
161 #endif
162 #endif
163
164 } // end anonymous namespace