[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