[llvm] dd00421 - Add StringRef::consumeInteger(APInt)
Thomas Preud'homme via llvm-commits
llvm-commits at lists.llvm.org
Tue May 23 06:01:44 PDT 2023
Author: Thomas Preud'homme
Date: 2023-05-23T14:01:38+01:00
New Revision: dd00421c60716973f5d919967fd4d6ef84025979
URL: https://github.com/llvm/llvm-project/commit/dd00421c60716973f5d919967fd4d6ef84025979
DIFF: https://github.com/llvm/llvm-project/commit/dd00421c60716973f5d919967fd4d6ef84025979.diff
LOG: Add StringRef::consumeInteger(APInt)
This will be required to allow arbitrary precision support to
FileCheck's numeric variables and expressions. Note: as per
getAsInteger(), this does not support negative value. If there is
interest for that it can be added in a separate patch.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D150878
Added:
Modified:
llvm/include/llvm/ADT/StringRef.h
llvm/lib/Support/StringRef.cpp
llvm/unittests/ADT/StringRefTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h
index d0a94b15bafdb..191d3e1281d18 100644
--- a/llvm/include/llvm/ADT/StringRef.h
+++ b/llvm/include/llvm/ADT/StringRef.h
@@ -523,6 +523,17 @@ namespace llvm {
/// string is well-formed in the given radix.
bool getAsInteger(unsigned Radix, APInt &Result) const;
+ /// Parse the current string as an integer of the specified \p Radix. If
+ /// \p Radix is specified as zero, this does radix autosensing using
+ /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
+ ///
+ /// If the string does not begin with a number of the specified radix,
+ /// this returns true to signify the error. The string is considered
+ /// erroneous if empty.
+ /// The portion of the string representing the discovered numeric value
+ /// is removed from the beginning of the string.
+ bool consumeInteger(unsigned Radix, APInt &Result);
+
/// Parse the current string as an IEEE double-precision floating
/// point value. The string must be a well-formed double.
///
diff --git a/llvm/lib/Support/StringRef.cpp b/llvm/lib/Support/StringRef.cpp
index 6207f626bbfb5..3cce83a982c4c 100644
--- a/llvm/lib/Support/StringRef.cpp
+++ b/llvm/lib/Support/StringRef.cpp
@@ -509,7 +509,7 @@ bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
return !Str.empty();
}
-bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
+bool StringRef::consumeInteger(unsigned Radix, APInt &Result) {
StringRef Str = *this;
// Autosense radix if not specified.
@@ -529,6 +529,7 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
// If it was nothing but zeroes....
if (Str.empty()) {
Result = APInt(64, 0);
+ *this = Str;
return false;
}
@@ -561,12 +562,12 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
else if (Str[0] >= 'A' && Str[0] <= 'Z')
CharVal = Str[0]-'A'+10;
else
- return true;
+ break;
// If the parsed value is larger than the integer radix, the string is
// invalid.
if (CharVal >= Radix)
- return true;
+ break;
// Add in this character.
if (IsPowerOf2Radix) {
@@ -581,9 +582,25 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
Str = Str.substr(1);
}
+ // We consider the operation a failure if no characters were consumed
+ // successfully.
+ if (size() == Str.size())
+ return true;
+
+ *this = Str;
return false;
}
+bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
+ StringRef Str = *this;
+ if (Str.consumeInteger(Radix, Result))
+ return true;
+
+ // For getAsInteger, we require the whole string to be consumed or else we
+ // consider it a failure.
+ return !Str.empty();
+}
+
bool StringRef::getAsDouble(double &Result, bool AllowInexact) const {
APFloat F(0.0);
auto StatusOrErr = F.convertFromString(*this, APFloat::rmNearestTiesToEven);
diff --git a/llvm/unittests/ADT/StringRefTest.cpp b/llvm/unittests/ADT/StringRefTest.cpp
index cad1974dd1263..a208527b6c803 100644
--- a/llvm/unittests/ADT/StringRefTest.cpp
+++ b/llvm/unittests/ADT/StringRefTest.cpp
@@ -818,6 +818,7 @@ TEST(StringRefTest, consumeIntegerUnsigned) {
uint16_t U16;
uint32_t U32;
uint64_t U64;
+ APInt U;
for (size_t i = 0; i < std::size(ConsumeUnsigned); ++i) {
StringRef Str = ConsumeUnsigned[i].Str;
@@ -858,6 +859,12 @@ TEST(StringRefTest, consumeIntegerUnsigned) {
ASSERT_FALSE(U64Success);
EXPECT_EQ(U64, ConsumeUnsigned[i].Expected);
EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
+
+ Str = ConsumeUnsigned[i].Str;
+ U64Success = Str.consumeInteger(0, U);
+ ASSERT_FALSE(U64Success);
+ EXPECT_EQ(U.getZExtValue(), ConsumeUnsigned[i].Expected);
+ EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
}
}
More information about the llvm-commits
mailing list