llvm.org GIT mirror llvm / 689ad6e
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 Daniel Dunbar 11 years ago
4 changed file(s) with 43 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
2626 class Deserializer;
2727 class FoldingSetNodeID;
2828 class raw_ostream;
29 class StringRef;
2930
3031 template
3132 class SmallVectorImpl;
151152
152153 /// This is used by the constructors that take string arguments.
153154 /// @brief Convert a char array into an APInt
154 void fromString(unsigned numBits, const char *strStart, unsigned slen,
155 uint8_t radix);
155 void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
156156
157157 /// This is used by the toString method to divide by the radix. It simply
158158 /// provides a more convenient form of divide for internal use since KnuthDiv
228228 /// @brief Construct an APInt of numBits width, initialized as bigVal[].
229229 APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
230230
231 /// This constructor interprets the slen characters starting at StrStart as
232 /// a string in the given radix. The interpretation stops when the first
233 /// character that is not suitable for the radix is encountered. Acceptable
234 /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
235 /// the string to require more bits than numBits.
231 /// This constructor interprets the string \arg str in the given radix. The
232 /// interpretation stops when the first character that is not suitable for the
233 /// radix is encountered, or the end of the string. Acceptable radix values
234 /// are 2, 8, 10 and 16. It is an error for the value implied by the string to
235 /// require more bits than numBits.
236 ///
236237 /// @param numBits the bit width of the constructed APInt
237 /// @param strStart the start of the string to be interpreted
238 /// @param slen the maximum number of characters to interpret
239 /// @param radix the radix to use for the conversion
238 /// @param str the string to be interpreted
239 /// @param radix the radix to use for the conversion
240240 /// @brief Construct an APInt from a string representation.
241 APInt(unsigned numBits, const char strStart[], unsigned slen, uint8_t radix);
241 APInt(unsigned numBits, const StringRef &str, uint8_t radix);
242242
243243 /// Simply makes *this a copy of that.
244244 /// @brief Copy Constructor.
10621062 }
10631063
10641064 /// This method determines how many bits are required to hold the APInt
1065 /// equivalent of the string given by \p str of length \p slen.
1065 /// equivalent of the string given by \arg str.
10661066 /// @brief Get bits required for string value.
1067 static unsigned getBitsNeeded(const char* str, unsigned slen, uint8_t radix);
1067 static unsigned getBitsNeeded(const StringRef& str, uint8_t radix);
10681068
10691069 /// countLeadingZeros - This function is an APInt version of the
10701070 /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
658658 TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) {
659659 int len = CurPtr-TokStart-3;
660660 uint32_t bits = len * 4;
661 APInt Tmp(bits, TokStart+3, len, 16);
661 APInt Tmp(bits, StringRef(TokStart+3, len), 16);
662662 uint32_t activeBits = Tmp.getActiveBits();
663663 if (activeBits > 0 && activeBits < bits)
664664 Tmp.trunc(activeBits);
784784 return Lex0x();
785785 unsigned Len = CurPtr-TokStart;
786786 uint32_t numBits = ((Len * 64) / 19) + 2;
787 APInt Tmp(numBits, TokStart, Len, 10);
787 APInt Tmp(numBits, StringRef(TokStart, Len), 10);
788788 if (TokStart[0] == '-') {
789789 uint32_t minBits = Tmp.getMinSignedBits();
790790 if (minBits > 0 && minBits < numBits)
1313
1414 #define DEBUG_TYPE "apint"
1515 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/StringRef.h"
1617 #include "llvm/ADT/FoldingSet.h"
1718 #include "llvm/ADT/SmallString.h"
1819 #include "llvm/Support/Debug.h"
7475 clearUnusedBits();
7576 }
7677
77 APInt::APInt(unsigned numbits, const char StrStart[], unsigned slen,
78 uint8_t radix)
78 APInt::APInt(unsigned numbits, const StringRef& Str, uint8_t radix)
7979 : BitWidth(numbits), VAL(0) {
8080 assert(BitWidth && "bitwidth too small");
81 fromString(numbits, StrStart, slen, radix);
81 fromString(numbits, Str, radix);
8282 }
8383
8484 APInt& APInt::AssignSlowCase(const APInt& RHS) {
586586 return *this;
587587 }
588588
589 unsigned APInt::getBitsNeeded(const char* str, unsigned slen, uint8_t radix) {
590 assert(str != 0 && "Invalid value string");
591 assert(slen > 0 && "Invalid string length");
589 unsigned APInt::getBitsNeeded(const StringRef& str, uint8_t radix) {
590 assert(!str.empty() && "Invalid string length");
591
592 size_t slen = str.size();
592593
593594 // Each computation below needs to know if its negative
594 unsigned isNegative = str[0] == '-';
595 unsigned isNegative = str.front() == '-';
595596 if (isNegative) {
596597 slen--;
597 str++;
598 assert(slen && "string is only a minus!");
598599 }
599600 // For radixes of power-of-two values, the bits required is accurately and
600601 // easily computed
617618 unsigned sufficient = slen*64/18;
618619
619620 // Convert to the actual binary value.
620 APInt tmp(sufficient, str, slen, radix);
621 APInt tmp(sufficient, str.substr(isNegative), radix);
621622
622623 // Compute how many bits are required.
623624 return isNegative + tmp.logBase2() + 1;
20002001 divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
20012002 }
20022003
2003 void APInt::fromString(unsigned numbits, const char *str, unsigned slen,
2004 uint8_t radix) {
2004 void APInt::fromString(unsigned numbits, const StringRef& str, uint8_t radix) {
20052005 // Check our assumptions here
20062006 assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
20072007 "Radix should be 2, 8, 10, or 16!");
2008 assert(str && "String is null?");
2009 bool isNeg = str[0] == '-';
2010 if (isNeg)
2011 str++, slen--;
2008 assert(!str.empty() && "Invalid string length");
2009 StringRef::iterator p = str.begin();
2010 size_t slen = str.size();
2011 bool isNeg = *p == '-';
2012 if (isNeg) {
2013 p++;
2014 slen--;
2015 assert(slen && "string is only a minus!");
2016 }
20122017 assert((slen <= numbits || radix != 2) && "Insufficient bit width");
20132018 assert(((slen-1)*3 <= numbits || radix != 8) && "Insufficient bit width");
20142019 assert(((slen-1)*4 <= numbits || radix != 16) && "Insufficient bit width");
20272032 APInt apradix(getBitWidth(), radix);
20282033
20292034 // Enter digit traversal loop
2030 for (unsigned i = 0; i < slen; i++) {
2035 for (StringRef::iterator e = str.end(); p != e; ++p) {
20312036 // Get a digit
20322037 unsigned digit = 0;
2033 char cdigit = str[i];
2038 char cdigit = *p;
20342039 if (radix == 16) {
20352040 if (!isxdigit(cdigit))
20362041 llvm_unreachable("Invalid hex digit in string");
163163 }
164164
165165 TEST(APIntTest, fromString) {
166 EXPECT_EQ(APInt(1, 0), APInt(1, "0", 1, 10));
167 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 10));
168 EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 2, 10));
169 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 2));
170 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 8));
171 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 16));
166 EXPECT_EQ(APInt(1, 0), APInt(1, "0", 10));
167 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 10));
168 EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 10));
169 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 2));
170 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 8));
171 EXPECT_EQ(APInt(1, 1), APInt(1, "1", 16));
172172 }
173173
174174 }