Convert APint::{fromString,APInt,getBitsNeeded} to use StringRef.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 13 Aug 2009 02:33:34 +0000 (02:33 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 13 Aug 2009 02:33:34 +0000 (02:33 +0000)
 - Patch by Erick Tryzelaar, with some edits (and a bug fix) from me.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78885 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APInt.h
lib/AsmParser/LLLexer.cpp
lib/Support/APInt.cpp
unittests/ADT/APIntTest.cpp

index 56cd3ccf84e3ebd3b8d0058f6f5f13bf83ff4fdf..5b69bc246747ed6e333113f205920ed44127519d 100644 (file)
@@ -27,6 +27,7 @@ namespace llvm {
   class Deserializer;
   class FoldingSetNodeID;
   class raw_ostream;
+  class StringRef;
 
   template<typename T>
   class SmallVectorImpl;
@@ -152,8 +153,7 @@ class APInt {
 
   /// This is used by the constructors that take string arguments.
   /// @brief Convert a char array into an APInt
-  void fromString(unsigned numBits, const char *strStart, unsigned slen,
-                  uint8_t radix);
+  void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
 
   /// This is used by the toString method to divide by the radix. It simply
   /// provides a more convenient form of divide for internal use since KnuthDiv
@@ -229,17 +229,17 @@ public:
   /// @brief Construct an APInt of numBits width, initialized as bigVal[].
   APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
 
-  /// This constructor interprets the slen characters starting at StrStart as
-  /// a string in the given radix. The interpretation stops when the first
-  /// character that is not suitable for the radix is encountered. Acceptable
-  /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
-  /// the string to require more bits than numBits.
+  /// This constructor interprets the string \arg str in the given radix. The
+  /// interpretation stops when the first character that is not suitable for the
+  /// radix is encountered, or the end of the string. Acceptable radix values
+  /// are 2, 8, 10 and 16. It is an error for the value implied by the string to
+  /// require more bits than numBits.
+  ///
   /// @param numBits the bit width of the constructed APInt
-  /// @param strStart the start of the string to be interpreted
-  /// @param slen the maximum number of characters to interpret
-  /// @param radix the radix to use for the conversion
+  /// @param str the string to be interpreted
+  /// @param radix the radix to use for the conversion 
   /// @brief Construct an APInt from a string representation.
-  APInt(unsigned numBits, const char strStart[], unsigned slen, uint8_t radix);
+  APInt(unsigned numBits, const StringRef &str, uint8_t radix);
 
   /// Simply makes *this a copy of that.
   /// @brief Copy Constructor.
@@ -1063,9 +1063,9 @@ public:
   }
 
   /// This method determines how many bits are required to hold the APInt
-  /// equivalent of the string given by \p str of length \p slen.
+  /// equivalent of the string given by \arg str.
   /// @brief Get bits required for string value.
-  static unsigned getBitsNeeded(const char* str, unsigned slen, uint8_t radix);
+  static unsigned getBitsNeeded(const StringRef& str, uint8_t radix);
 
   /// countLeadingZeros - This function is an APInt version of the
   /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
index a6e63448b2e83a64752cc266e229994df6a95cb0..c5e642446454747b01b393eb09b856394dfafacf 100644 (file)
@@ -659,7 +659,7 @@ lltok::Kind LLLexer::LexIdentifier() {
       TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) {
     int len = CurPtr-TokStart-3;
     uint32_t bits = len * 4;
-    APInt Tmp(bits, TokStart+3, len, 16);
+    APInt Tmp(bits, StringRef(TokStart+3, len), 16);
     uint32_t activeBits = Tmp.getActiveBits();
     if (activeBits > 0 && activeBits < bits)
       Tmp.trunc(activeBits);
@@ -785,7 +785,7 @@ lltok::Kind LLLexer::LexDigitOrNegative() {
       return Lex0x();
     unsigned Len = CurPtr-TokStart;
     uint32_t numBits = ((Len * 64) / 19) + 2;
-    APInt Tmp(numBits, TokStart, Len, 10);
+    APInt Tmp(numBits, StringRef(TokStart, Len), 10);
     if (TokStart[0] == '-') {
       uint32_t minBits = Tmp.getMinSignedBits();
       if (minBits > 0 && minBits < numBits)
index daf2244149a87527c9a6ae4853e91a4df6614ab4..e352b630ce46bfd7fb63d481371646229b657dc9 100644 (file)
@@ -14,6 +14,7 @@
 
 #define DEBUG_TYPE "apint"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Debug.h"
@@ -75,11 +76,10 @@ APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
   clearUnusedBits();
 }
 
-APInt::APInt(unsigned numbits, const char StrStart[], unsigned slen,
-             uint8_t radix) 
+APInt::APInt(unsigned numbits, const StringRef& Str, uint8_t radix) 
   : BitWidth(numbits), VAL(0) {
   assert(BitWidth && "bitwidth too small");
-  fromString(numbits, StrStart, slen, radix);
+  fromString(numbits, Str, radix);
 }
 
 APInt& APInt::AssignSlowCase(const APInt& RHS) {
@@ -587,15 +587,16 @@ APInt& APInt::flip(unsigned bitPosition) {
   return *this;
 }
 
-unsigned APInt::getBitsNeeded(const char* str, unsigned slen, uint8_t radix) {
-  assert(str != 0 && "Invalid value string");
-  assert(slen > 0 && "Invalid string length");
+unsigned APInt::getBitsNeeded(const StringRef& str, uint8_t radix) {
+  assert(!str.empty() && "Invalid string length");
+
+  size_t slen = str.size();
 
   // Each computation below needs to know if its negative
-  unsigned isNegative = str[0] == '-';
+  unsigned isNegative = str.front() == '-';
   if (isNegative) {
     slen--;
-    str++;
+    assert(slen && "string is only a minus!");
   }
   // For radixes of power-of-two values, the bits required is accurately and
   // easily computed
@@ -618,7 +619,7 @@ unsigned APInt::getBitsNeeded(const char* str, unsigned slen, uint8_t radix) {
   unsigned sufficient = slen*64/18;
 
   // Convert to the actual binary value.
-  APInt tmp(sufficient, str, slen, radix);
+  APInt tmp(sufficient, str.substr(isNegative), radix);
 
   // Compute how many bits are required.
   return isNegative + tmp.logBase2() + 1;
@@ -2001,15 +2002,19 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
   divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
 }
 
-void APInt::fromString(unsigned numbits, const char *str, unsigned slen,
-                       uint8_t radix) {
+void APInt::fromString(unsigned numbits, const StringRef& str, uint8_t radix) {
   // Check our assumptions here
   assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
          "Radix should be 2, 8, 10, or 16!");
-  assert(str && "String is null?");
-  bool isNeg = str[0] == '-';
-  if (isNeg)
-    str++, slen--;
+  assert(!str.empty() && "Invalid string length");
+  StringRef::iterator p = str.begin();
+  size_t slen = str.size();
+  bool isNeg = *p == '-';
+  if (isNeg) {
+    p++;
+    slen--;
+    assert(slen && "string is only a minus!");
+  }
   assert((slen <= numbits || radix != 2) && "Insufficient bit width");
   assert(((slen-1)*3 <= numbits || radix != 8) && "Insufficient bit width");
   assert(((slen-1)*4 <= numbits || radix != 16) && "Insufficient bit width");
@@ -2028,10 +2033,10 @@ void APInt::fromString(unsigned numbits, const char *str, unsigned slen,
   APInt apradix(getBitWidth(), radix);
 
   // Enter digit traversal loop
-  for (unsigned i = 0; i < slen; i++) {
+  for (StringRef::iterator e = str.end(); p != e; ++p) {
     // Get a digit
     unsigned digit = 0;
-    char cdigit = str[i];
+    char cdigit = *p;
     if (radix == 16) {
       if (!isxdigit(cdigit))
         llvm_unreachable("Invalid hex digit in string");
index 648faf13ad81a2cbe1ea09695a77e84dcad3f6fa..4a6b176a2b44006d086b029ad9ec16db064e8c48 100644 (file)
@@ -164,12 +164,12 @@ TEST(APIntTest, i1) {
 }
 
 TEST(APIntTest, fromString) {
-  EXPECT_EQ(APInt(1, 0), APInt(1, "0", 1, 10));
-  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 10));
-  EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 2, 10));
-  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 2));
-  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 8));
-  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 16));
+  EXPECT_EQ(APInt(1, 0), APInt(1, "0", 10));
+  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 10));
+  EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 10));
+  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 2));
+  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 8));
+  EXPECT_EQ(APInt(1, 1), APInt(1, "1", 16));
 }
 
 }