summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/StringRef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/StringRef.cpp')
-rw-r--r--contrib/llvm/lib/Support/StringRef.cpp140
1 files changed, 109 insertions, 31 deletions
diff --git a/contrib/llvm/lib/Support/StringRef.cpp b/contrib/llvm/lib/Support/StringRef.cpp
index 8a9da5e..d81250e 100644
--- a/contrib/llvm/lib/Support/StringRef.cpp
+++ b/contrib/llvm/lib/Support/StringRef.cpp
@@ -69,6 +69,11 @@ bool StringRef::endswith_lower(StringRef Suffix) const {
ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
}
+size_t StringRef::find_lower(char C, size_t From) const {
+ char L = ascii_tolower(C);
+ return find_if([L](char D) { return ascii_tolower(D) == L; }, From);
+}
+
/// compare_numeric - Compare strings, handle embedded numbers.
int StringRef::compare_numeric(StringRef RHS) const {
for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) {
@@ -143,16 +148,20 @@ size_t StringRef::find(StringRef Str, size_t From) const {
if (From > Length)
return npos;
+ const char *Start = Data + From;
+ size_t Size = Length - From;
+
const char *Needle = Str.data();
size_t N = Str.size();
if (N == 0)
return From;
-
- size_t Size = Length - From;
if (Size < N)
return npos;
+ if (N == 1) {
+ const char *Ptr = (const char *)::memchr(Start, Needle[0], Size);
+ return Ptr == nullptr ? npos : Ptr - Data;
+ }
- const char *Start = Data + From;
const char *Stop = Start + (Size - N + 1);
// For short haystacks or unsupported needles fall back to the naive algorithm
@@ -172,16 +181,40 @@ size_t StringRef::find(StringRef Str, size_t From) const {
BadCharSkip[(uint8_t)Str[i]] = N-1-i;
do {
- if (std::memcmp(Start, Needle, N) == 0)
- return Start - Data;
+ uint8_t Last = Start[N - 1];
+ if (LLVM_UNLIKELY(Last == (uint8_t)Needle[N - 1]))
+ if (std::memcmp(Start, Needle, N - 1) == 0)
+ return Start - Data;
// Otherwise skip the appropriate number of bytes.
- Start += BadCharSkip[(uint8_t)Start[N-1]];
+ Start += BadCharSkip[Last];
} while (Start < Stop);
return npos;
}
+size_t StringRef::find_lower(StringRef Str, size_t From) const {
+ StringRef This = substr(From);
+ while (This.size() >= Str.size()) {
+ if (This.startswith_lower(Str))
+ return From;
+ This = This.drop_front();
+ ++From;
+ }
+ return npos;
+}
+
+size_t StringRef::rfind_lower(char C, size_t From) const {
+ From = std::min(From, Length);
+ size_t i = From;
+ while (i != 0) {
+ --i;
+ if (ascii_tolower(Data[i]) == ascii_tolower(C))
+ return i;
+ }
+ return npos;
+}
+
/// rfind - Search for the last string \arg Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
@@ -198,6 +231,18 @@ size_t StringRef::rfind(StringRef Str) const {
return npos;
}
+size_t StringRef::rfind_lower(StringRef Str) const {
+ size_t N = Str.size();
+ if (N > Length)
+ return npos;
+ for (size_t i = Length - N + 1, e = 0; i != e;) {
+ --i;
+ if (substr(i, N).equals_lower(Str))
+ return i;
+ }
+ return npos;
+}
+
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
///
@@ -351,6 +396,9 @@ size_t StringRef::count(StringRef Str) const {
}
static unsigned GetAutoSenseRadix(StringRef &Str) {
+ if (Str.empty())
+ return 10;
+
if (Str.startswith("0x") || Str.startswith("0X")) {
Str = Str.substr(2);
return 16;
@@ -366,17 +414,16 @@ static unsigned GetAutoSenseRadix(StringRef &Str) {
return 8;
}
- if (Str.startswith("0"))
+ if (Str[0] == '0' && Str.size() > 1 && ascii_isdigit(Str[1])) {
+ Str = Str.substr(1);
return 8;
-
+ }
+
return 10;
}
-
-/// GetAsUnsignedInteger - Workhorse method that converts a integer character
-/// sequence of radix up to 36 to an unsigned long long value.
-bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
- unsigned long long &Result) {
+bool llvm::consumeUnsignedInteger(StringRef &Str, unsigned Radix,
+ unsigned long long &Result) {
// Autosense radix if not specified.
if (Radix == 0)
Radix = GetAutoSenseRadix(Str);
@@ -385,44 +432,51 @@ bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
if (Str.empty()) return true;
// Parse all the bytes of the string given this radix. Watch for overflow.
+ StringRef Str2 = Str;
Result = 0;
- while (!Str.empty()) {
+ while (!Str2.empty()) {
unsigned CharVal;
- if (Str[0] >= '0' && Str[0] <= '9')
- CharVal = Str[0]-'0';
- else if (Str[0] >= 'a' && Str[0] <= 'z')
- CharVal = Str[0]-'a'+10;
- else if (Str[0] >= 'A' && Str[0] <= 'Z')
- CharVal = Str[0]-'A'+10;
+ if (Str2[0] >= '0' && Str2[0] <= '9')
+ CharVal = Str2[0] - '0';
+ else if (Str2[0] >= 'a' && Str2[0] <= 'z')
+ CharVal = Str2[0] - 'a' + 10;
+ else if (Str2[0] >= 'A' && Str2[0] <= 'Z')
+ CharVal = Str2[0] - 'A' + 10;
else
- return true;
+ break;
- // If the parsed value is larger than the integer radix, the string is
- // invalid.
+ // If the parsed value is larger than the integer radix, we cannot
+ // consume any more characters.
if (CharVal >= Radix)
- return true;
+ break;
// Add in this character.
unsigned long long PrevResult = Result;
- Result = Result*Radix+CharVal;
+ Result = Result * Radix + CharVal;
// Check for overflow by shifting back and seeing if bits were lost.
- if (Result/Radix < PrevResult)
+ if (Result / Radix < PrevResult)
return true;
- Str = Str.substr(1);
+ Str2 = Str2.substr(1);
}
+ // We consider the operation a failure if no characters were consumed
+ // successfully.
+ if (Str.size() == Str2.size())
+ return true;
+
+ Str = Str2;
return false;
}
-bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
- long long &Result) {
+bool llvm::consumeSignedInteger(StringRef &Str, unsigned Radix,
+ long long &Result) {
unsigned long long ULLVal;
// Handle positive strings first.
if (Str.empty() || Str.front() != '-') {
- if (getAsUnsignedInteger(Str, Radix, ULLVal) ||
+ if (consumeUnsignedInteger(Str, Radix, ULLVal) ||
// Check for value so large it overflows a signed value.
(long long)ULLVal < 0)
return true;
@@ -431,17 +485,41 @@ bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
}
// Get the positive part of the value.
- if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) ||
+ StringRef Str2 = Str.drop_front(1);
+ if (consumeUnsignedInteger(Str2, Radix, ULLVal) ||
// Reject values so large they'd overflow as negative signed, but allow
// "-0". This negates the unsigned so that the negative isn't undefined
// on signed overflow.
(long long)-ULLVal > 0)
return true;
+ Str = Str2;
Result = -ULLVal;
return false;
}
+/// GetAsUnsignedInteger - Workhorse method that converts a integer character
+/// sequence of radix up to 36 to an unsigned long long value.
+bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
+ unsigned long long &Result) {
+ if (consumeUnsignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsUnsignedInteger, we require the whole string to be consumed or
+ // else we consider it a failure.
+ return !Str.empty();
+}
+
+bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
+ long long &Result) {
+ if (consumeSignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsSignedInteger, we require the whole string to be consumed or else
+ // we consider it a failure.
+ return !Str.empty();
+}
+
bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
StringRef Str = *this;
OpenPOWER on IntegriCloud