From 689ad6ef3fd2e89394f1e8860dfebfe56b73c3da Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 13 Aug 2009 02:33:34 +0000 Subject: [PATCH] Convert APint::{fromString,APInt,getBitsNeeded} to use StringRef. - 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 | 26 ++++++++++++------------- lib/AsmParser/LLLexer.cpp | 4 ++-- lib/Support/APInt.cpp | 39 +++++++++++++++++++++---------------- unittests/ADT/APIntTest.cpp | 12 ++++++------ 4 files changed, 43 insertions(+), 38 deletions(-) diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 56cd3ccf84e..5b69bc24674 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -27,6 +27,7 @@ namespace llvm { class Deserializer; class FoldingSetNodeID; class raw_ostream; + class StringRef; template 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 diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index a6e63448b2e..c5e64244645 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -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) diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index daf2244149a..e352b630ce4 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -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"); diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 648faf13ad8..4a6b176a2b4 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -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)); } } -- 2.34.1