1 //===-- StringRef.cpp - Lightweight String References ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/StringRef.h" 11 using namespace llvm; 12 13 const size_t StringRef::npos; 14 15 /// GetAsUnsignedInteger - Workhorse method that converts a integer character 16 /// sequence of radix up to 36 to an unsigned long long value. 17 static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix, 18 unsigned long long &Result) { 19 // Autosense radix if not specified. 20 if (Radix == 0) { 21 if (Str[0] != '0') { 22 Radix = 10; 23 } else { 24 if (Str.size() < 2) { 25 Radix = 8; 26 } else { 27 if (Str[1] == 'x') { 28 Str = Str.substr(2); 29 Radix = 16; 30 } else if (Str[1] == 'b') { 31 Str = Str.substr(2); 32 Radix = 2; 33 } else { 34 Radix = 8; 35 } 36 } 37 } 38 } 39 40 // Empty strings (after the radix autosense) are invalid. 41 if (Str.empty()) return true; 42 43 // Parse all the bytes of the string given this radix. Watch for overflow. 44 Result = 0; 45 while (!Str.empty()) { 46 unsigned CharVal; 47 if (Str[0] >= '0' && Str[0] <= '9') 48 CharVal = Str[0]-'0'; 49 else if (Str[0] >= 'a' && Str[0] <= 'z') 50 CharVal = Str[0]-'a'+10; 51 else if (Str[0] >= 'A' && Str[0] <= 'Z') 52 CharVal = Str[0]-'A'+10; 53 else 54 return true; 55 56 // If the parsed value is larger than the integer radix, the string is 57 // invalid. 58 if (CharVal >= Radix) 59 return true; 60 61 // Add in this character. 62 unsigned long long PrevResult = Result; 63 Result = Result*Radix+CharVal; 64 65 // Check for overflow. 66 if (Result < PrevResult) 67 return true; 68 69 Str = Str.substr(1); 70 } 71 72 return false; 73 } 74 75 bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const { 76 return GetAsUnsignedInteger(*this, Radix, Result); 77 } 78 79 80 bool StringRef::getAsInteger(unsigned Radix, long long &Result) const { 81 unsigned long long ULLVal; 82 83 // Handle positive strings first. 84 if (empty() || front() != '-') { 85 if (GetAsUnsignedInteger(*this, Radix, ULLVal) || 86 // Check for value so large it overflows a signed value. 87 (long long)ULLVal < 0) 88 return true; 89 Result = ULLVal; 90 return false; 91 } 92 93 // Get the positive part of the value. 94 if (GetAsUnsignedInteger(substr(1), Radix, ULLVal) || 95 // Reject values so large they'd overflow as negative signed, but allow 96 // "-0". This negates the unsigned so that the negative isn't undefined 97 // on signed overflow. 98 (long long)-ULLVal > 0) 99 return true; 100 101 Result = -ULLVal; 102 return false; 103 } 104 105 bool StringRef::getAsInteger(unsigned Radix, int &Result) const { 106 long long Val; 107 if (getAsInteger(Radix, Val) || 108 (int)Val != Val) 109 return true; 110 Result = Val; 111 return false; 112 } 113 114 bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const { 115 unsigned long long Val; 116 if (getAsInteger(Radix, Val) || 117 (unsigned)Val != Val) 118 return true; 119 Result = Val; 120 return false; 121 } 122