llvm.org GIT mirror llvm / 1e7ad39
Add an override to StringRef::getAsInteger which parses into an APInt. It gets its own implementation totally divorced from the (presumably performance-sensitive) routines which parse into a uint64_t. Add APInt::operator|=(uint64_t), which is situationally much better than using a full APInt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97381 91177308-0d34-0410-b5e6-96231b3b80d8 John McCall 10 years ago
3 changed file(s) with 132 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
149149 return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
150150 }
151151
152 /// Converts a string into a number. The string must be non-empty
153 /// and well-formed as a number of the given base. The bit-width
154 /// must be sufficient to hold the result.
155 ///
152156 /// This is used by the constructors that take string arguments.
157 ///
158 /// StringRef::getAsInteger is superficially similar but (1) does
159 /// not assume that the string is well-formed and (2) grows the
160 /// result to hold the input.
161 ///
162 /// @param radix 2, 8, 10, or 16
153163 /// @brief Convert a char array into an APInt
154164 void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
155165
570580 /// @brief Bitwise OR assignment operator.
571581 APInt& operator|=(const APInt& RHS);
572582
583 /// Performs a bitwise OR operation on this APInt and RHS. RHS is
584 /// logically zero-extended or truncated to match the bit-width of
585 /// the LHS.
586 ///
587 /// @brief Bitwise OR assignment operator.
588 APInt& operator|=(uint64_t RHS) {
589 if (isSingleWord()) {
590 VAL |= RHS;
591 clearUnusedBits();
592 } else {
593 pVal[0] |= RHS;
594 }
595 return *this;
596 }
597
573598 /// Performs a bitwise XOR operation on this APInt and RHS. The result is
574599 /// assigned to *this.
575600 /// @returns *this after XORing with RHS.
1717 namespace llvm {
1818 template
1919 class SmallVectorImpl;
20 class APInt;
2021
2122 /// StringRef - Represent a constant reference to a string, i.e. a character
2223 /// array and a length, which need not be null terminated.
272273
273274 // TODO: Provide overloads for int/unsigned that check for overflow.
274275
276 /// getAsInteger - Parse the current string as an integer of the
277 /// specified radix, or of an autosensed radix if the radix given
278 /// is 0. The current value in Result is discarded, and the
279 /// storage is changed to be wide enough to store the parsed
280 /// integer.
281 ///
282 /// Returns true if the string does not solely consist of a valid
283 /// non-empty number in the appropriate base.
284 ///
285 /// APInt::fromString is superficially similar but assumes the
286 /// string is well-formed in the given radix.
287 bool getAsInteger(unsigned Radix, APInt &Result) const;
288
275289 /// @}
276290 /// @name Substring Operations
277291 /// @{
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/ADT/StringRef.h"
10 #include "llvm/ADT/APInt.h"
1011
1112 using namespace llvm;
1213
171172 return Count;
172173 }
173174
175 static unsigned GetAutoSenseRadix(StringRef &Str) {
176 if (Str.startswith("0x")) {
177 Str = Str.substr(2);
178 return 16;
179 } else if (Str.startswith("0b")) {
180 Str = Str.substr(2);
181 return 2;
182 } else if (Str.startswith("0")) {
183 return 8;
184 } else {
185 return 10;
186 }
187 }
188
189
174190 /// GetAsUnsignedInteger - Workhorse method that converts a integer character
175191 /// sequence of radix up to 36 to an unsigned long long value.
176192 static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
177193 unsigned long long &Result) {
178194 // Autosense radix if not specified.
179 if (Radix == 0) {
180 if (Str.startswith("0x")) {
181 Str = Str.substr(2);
182 Radix = 16;
183 } else if (Str.startswith("0b")) {
184 Str = Str.substr(2);
185 Radix = 2;
186 } else if (Str.startswith("0"))
187 Radix = 8;
188 else
189 Radix = 10;
190 }
195 if (Radix == 0)
196 Radix = GetAutoSenseRadix(Str);
191197
192198 // Empty strings (after the radix autosense) are invalid.
193199 if (Str.empty()) return true;
271277 Result = Val;
272278 return false;
273279 }
280
281 bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
282 StringRef Str = *this;
283
284 // Autosense radix if not specified.
285 if (Radix == 0)
286 Radix = GetAutoSenseRadix(Str);
287
288 assert(Radix > 1 && Radix <= 36);
289
290 // Empty strings (after the radix autosense) are invalid.
291 if (Str.empty()) return true;
292
293 // Skip leading zeroes. This can be a significant improvement if
294 // it means we don't need > 64 bits.
295 while (!Str.empty() && Str.front() == '0')
296 Str = Str.substr(1);
297
298 // If it was nothing but zeroes....
299 if (Str.empty()) {
300 Result = APInt(64, 0);
301 return false;
302 }
303
304 // (Over-)estimate the required number of bits.
305 unsigned Log2Radix = 0;
306 while ((1U << Log2Radix) < Radix) Log2Radix++;
307 bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix);
308
309 unsigned BitWidth = Log2Radix * Str.size();
310 if (BitWidth < Result.getBitWidth())
311 BitWidth = Result.getBitWidth(); // don't shrink the result
312 else
313 Result.zext(BitWidth);
314
315 APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix
316 if (!IsPowerOf2Radix) {
317 // These must have the same bit-width as Result.
318 RadixAP = APInt(BitWidth, Radix);
319 CharAP = APInt(BitWidth, 0);
320 }
321
322 // Parse all the bytes of the string given this radix.
323 Result = 0;
324 while (!Str.empty()) {
325 unsigned CharVal;
326 if (Str[0] >= '0' && Str[0] <= '9')
327 CharVal = Str[0]-'0';
328 else if (Str[0] >= 'a' && Str[0] <= 'z')
329 CharVal = Str[0]-'a'+10;
330 else if (Str[0] >= 'A' && Str[0] <= 'Z')
331 CharVal = Str[0]-'A'+10;
332 else
333 return true;
334
335 // If the parsed value is larger than the integer radix, the string is
336 // invalid.
337 if (CharVal >= Radix)
338 return true;
339
340 // Add in this character.
341 if (IsPowerOf2Radix) {
342 Result <<= Log2Radix;
343 Result |= CharVal;
344 } else {
345 Result *= RadixAP;
346 CharAP = CharVal;
347 Result += CharAP;
348 }
349
350 Str = Str.substr(1);
351 }
352
353 return false;
354 }