| Daniel Dunbar | 4498168 | 2009-09-16 22:38:48 +0000 | [diff] [blame] | 1 | //===-- StringRef.cpp - Lightweight String References ---------------------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Daniel Dunbar | 4498168 | 2009-09-16 22:38:48 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 |  | 
|  | 9 | #include "llvm/ADT/StringRef.h" | 
| Zachary Turner | 8bd42a1 | 2017-02-14 19:06:37 +0000 | [diff] [blame] | 10 | #include "llvm/ADT/APFloat.h" | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 11 | #include "llvm/ADT/APInt.h" | 
| Chandler Carruth | ca99ad3 | 2012-03-04 10:55:27 +0000 | [diff] [blame] | 12 | #include "llvm/ADT/Hashing.h" | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 13 | #include "llvm/ADT/StringExtras.h" | 
| Kaelyn Uhrain | 7a9ccf4 | 2012-02-15 22:13:07 +0000 | [diff] [blame] | 14 | #include "llvm/ADT/edit_distance.h" | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 15 | #include <bitset> | 
| Douglas Gregor | 09470e6 | 2010-01-07 00:51:54 +0000 | [diff] [blame] | 16 |  | 
| Daniel Dunbar | 4498168 | 2009-09-16 22:38:48 +0000 | [diff] [blame] | 17 | using namespace llvm; | 
|  | 18 |  | 
| Daniel Dunbar | c827d9e | 2009-09-22 03:34:40 +0000 | [diff] [blame] | 19 | // MSVC emits references to this into the translation units which reference it. | 
|  | 20 | #ifndef _MSC_VER | 
| Daniel Dunbar | 4498168 | 2009-09-16 22:38:48 +0000 | [diff] [blame] | 21 | const size_t StringRef::npos; | 
| Daniel Dunbar | c827d9e | 2009-09-22 03:34:40 +0000 | [diff] [blame] | 22 | #endif | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 23 |  | 
| Rui Ueyama | 00e24e4 | 2013-10-30 18:32:26 +0000 | [diff] [blame] | 24 | // strncasecmp() is not available on non-POSIX systems, so define an | 
|  | 25 | // alternative function here. | 
|  | 26 | static int ascii_strncasecmp(const char *LHS, const char *RHS, size_t Length) { | 
|  | 27 | for (size_t I = 0; I < Length; ++I) { | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 28 | unsigned char LHC = toLower(LHS[I]); | 
|  | 29 | unsigned char RHC = toLower(RHS[I]); | 
| Benjamin Kramer | 68e4945 | 2009-11-12 20:36:59 +0000 | [diff] [blame] | 30 | if (LHC != RHC) | 
|  | 31 | return LHC < RHC ? -1 : 1; | 
|  | 32 | } | 
| Rui Ueyama | 00e24e4 | 2013-10-30 18:32:26 +0000 | [diff] [blame] | 33 | return 0; | 
|  | 34 | } | 
| Benjamin Kramer | 68e4945 | 2009-11-12 20:36:59 +0000 | [diff] [blame] | 35 |  | 
| Rui Ueyama | 00e24e4 | 2013-10-30 18:32:26 +0000 | [diff] [blame] | 36 | /// compare_lower - Compare strings, ignoring case. | 
|  | 37 | int StringRef::compare_lower(StringRef RHS) const { | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 38 | if (int Res = ascii_strncasecmp(Data, RHS.Data, std::min(Length, RHS.Length))) | 
| Rui Ueyama | 00e24e4 | 2013-10-30 18:32:26 +0000 | [diff] [blame] | 39 | return Res; | 
| Benjamin Kramer | 68e4945 | 2009-11-12 20:36:59 +0000 | [diff] [blame] | 40 | if (Length == RHS.Length) | 
| Benjamin Kramer | b04d4af | 2010-08-26 14:21:08 +0000 | [diff] [blame] | 41 | return 0; | 
| Benjamin Kramer | 68e4945 | 2009-11-12 20:36:59 +0000 | [diff] [blame] | 42 | return Length < RHS.Length ? -1 : 1; | 
|  | 43 | } | 
|  | 44 |  | 
| Rui Ueyama | 00e24e4 | 2013-10-30 18:32:26 +0000 | [diff] [blame] | 45 | /// Check if this string starts with the given \p Prefix, ignoring case. | 
|  | 46 | bool StringRef::startswith_lower(StringRef Prefix) const { | 
|  | 47 | return Length >= Prefix.Length && | 
|  | 48 | ascii_strncasecmp(Data, Prefix.Data, Prefix.Length) == 0; | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | /// Check if this string ends with the given \p Suffix, ignoring case. | 
|  | 52 | bool StringRef::endswith_lower(StringRef Suffix) const { | 
|  | 53 | return Length >= Suffix.Length && | 
|  | 54 | ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; | 
|  | 55 | } | 
|  | 56 |  | 
| Zachary Turner | 17412b0 | 2016-11-12 17:17:12 +0000 | [diff] [blame] | 57 | size_t StringRef::find_lower(char C, size_t From) const { | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 58 | char L = toLower(C); | 
|  | 59 | return find_if([L](char D) { return toLower(D) == L; }, From); | 
| Zachary Turner | 17412b0 | 2016-11-12 17:17:12 +0000 | [diff] [blame] | 60 | } | 
|  | 61 |  | 
| Jakob Stoklund Olesen | d1d7ed6 | 2010-05-26 21:47:28 +0000 | [diff] [blame] | 62 | /// compare_numeric - Compare strings, handle embedded numbers. | 
|  | 63 | int StringRef::compare_numeric(StringRef RHS) const { | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 64 | for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) { | 
| Jakob Stoklund Olesen | c874e2d | 2011-09-30 17:03:55 +0000 | [diff] [blame] | 65 | // Check for sequences of digits. | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 66 | if (isDigit(Data[I]) && isDigit(RHS.Data[I])) { | 
| Jakob Stoklund Olesen | c874e2d | 2011-09-30 17:03:55 +0000 | [diff] [blame] | 67 | // The longer sequence of numbers is considered larger. | 
|  | 68 | // This doesn't really handle prefixed zeros well. | 
|  | 69 | size_t J; | 
|  | 70 | for (J = I + 1; J != E + 1; ++J) { | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 71 | bool ld = J < Length && isDigit(Data[J]); | 
|  | 72 | bool rd = J < RHS.Length && isDigit(RHS.Data[J]); | 
| Jakob Stoklund Olesen | d1d7ed6 | 2010-05-26 21:47:28 +0000 | [diff] [blame] | 73 | if (ld != rd) | 
|  | 74 | return rd ? -1 : 1; | 
|  | 75 | if (!rd) | 
|  | 76 | break; | 
|  | 77 | } | 
| Jakob Stoklund Olesen | c874e2d | 2011-09-30 17:03:55 +0000 | [diff] [blame] | 78 | // The two number sequences have the same length (J-I), just memcmp them. | 
|  | 79 | if (int Res = compareMemory(Data + I, RHS.Data + I, J - I)) | 
|  | 80 | return Res < 0 ? -1 : 1; | 
|  | 81 | // Identical number sequences, continue search after the numbers. | 
|  | 82 | I = J - 1; | 
|  | 83 | continue; | 
| Jakob Stoklund Olesen | d1d7ed6 | 2010-05-26 21:47:28 +0000 | [diff] [blame] | 84 | } | 
| Jakob Stoklund Olesen | c874e2d | 2011-09-30 17:03:55 +0000 | [diff] [blame] | 85 | if (Data[I] != RHS.Data[I]) | 
|  | 86 | return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; | 
| Jakob Stoklund Olesen | d1d7ed6 | 2010-05-26 21:47:28 +0000 | [diff] [blame] | 87 | } | 
|  | 88 | if (Length == RHS.Length) | 
| Benjamin Kramer | b04d4af | 2010-08-26 14:21:08 +0000 | [diff] [blame] | 89 | return 0; | 
| Jakob Stoklund Olesen | d1d7ed6 | 2010-05-26 21:47:28 +0000 | [diff] [blame] | 90 | return Length < RHS.Length ? -1 : 1; | 
|  | 91 | } | 
|  | 92 |  | 
| Douglas Gregor | 5639af4 | 2009-12-31 04:24:34 +0000 | [diff] [blame] | 93 | // Compute the edit distance between the two given strings. | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 94 | unsigned StringRef::edit_distance(llvm::StringRef Other, | 
| Douglas Gregor | 21afc3b | 2010-10-19 22:13:48 +0000 | [diff] [blame] | 95 | bool AllowReplacements, | 
| Dmitri Gribenko | 292c920 | 2013-08-24 01:50:41 +0000 | [diff] [blame] | 96 | unsigned MaxEditDistance) const { | 
| Kaelyn Uhrain | 7a9ccf4 | 2012-02-15 22:13:07 +0000 | [diff] [blame] | 97 | return llvm::ComputeEditDistance( | 
| Craig Topper | e1d1294 | 2014-08-27 05:25:25 +0000 | [diff] [blame] | 98 | makeArrayRef(data(), size()), | 
|  | 99 | makeArrayRef(Other.data(), Other.size()), | 
| Kaelyn Uhrain | 7a9ccf4 | 2012-02-15 22:13:07 +0000 | [diff] [blame] | 100 | AllowReplacements, MaxEditDistance); | 
| Douglas Gregor | 165882c | 2009-12-30 17:23:44 +0000 | [diff] [blame] | 101 | } | 
|  | 102 |  | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 103 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 3fa528d | 2011-11-06 18:04:43 +0000 | [diff] [blame] | 104 | // String Operations | 
|  | 105 | //===----------------------------------------------------------------------===// | 
|  | 106 |  | 
|  | 107 | std::string StringRef::lower() const { | 
|  | 108 | std::string Result(size(), char()); | 
|  | 109 | for (size_type i = 0, e = size(); i != e; ++i) { | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 110 | Result[i] = toLower(Data[i]); | 
| Daniel Dunbar | 3fa528d | 2011-11-06 18:04:43 +0000 | [diff] [blame] | 111 | } | 
|  | 112 | return Result; | 
|  | 113 | } | 
|  | 114 |  | 
|  | 115 | std::string StringRef::upper() const { | 
|  | 116 | std::string Result(size(), char()); | 
|  | 117 | for (size_type i = 0, e = size(); i != e; ++i) { | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 118 | Result[i] = toUpper(Data[i]); | 
| Daniel Dunbar | 3fa528d | 2011-11-06 18:04:43 +0000 | [diff] [blame] | 119 | } | 
|  | 120 | return Result; | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 124 | // String Searching | 
|  | 125 | //===----------------------------------------------------------------------===// | 
|  | 126 |  | 
|  | 127 |  | 
|  | 128 | /// find - Search for the first string \arg Str in the string. | 
|  | 129 | /// | 
| Chris Lattner | 0ab5e2c | 2011-04-15 05:18:47 +0000 | [diff] [blame] | 130 | /// \return - The index of the first occurrence of \arg Str, or npos if not | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 131 | /// found. | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 132 | size_t StringRef::find(StringRef Str, size_t From) const { | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 133 | if (From > Length) | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 134 | return npos; | 
| Benjamin Kramer | 4d681d7 | 2011-10-15 10:08:31 +0000 | [diff] [blame] | 135 |  | 
| Chandler Carruth | ecbe619 | 2016-12-11 07:46:21 +0000 | [diff] [blame] | 136 | const char *Start = Data + From; | 
|  | 137 | size_t Size = Length - From; | 
|  | 138 |  | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 139 | const char *Needle = Str.data(); | 
|  | 140 | size_t N = Str.size(); | 
|  | 141 | if (N == 0) | 
|  | 142 | return From; | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 143 | if (Size < N) | 
|  | 144 | return npos; | 
| Chandler Carruth | ecbe619 | 2016-12-11 07:46:21 +0000 | [diff] [blame] | 145 | if (N == 1) { | 
|  | 146 | const char *Ptr = (const char *)::memchr(Start, Needle[0], Size); | 
|  | 147 | return Ptr == nullptr ? npos : Ptr - Data; | 
|  | 148 | } | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 149 |  | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 150 | const char *Stop = Start + (Size - N + 1); | 
|  | 151 |  | 
| Benjamin Kramer | 4d681d7 | 2011-10-15 10:08:31 +0000 | [diff] [blame] | 152 | // For short haystacks or unsupported needles fall back to the naive algorithm | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 153 | if (Size < 16 || N > 255) { | 
|  | 154 | do { | 
|  | 155 | if (std::memcmp(Start, Needle, N) == 0) | 
|  | 156 | return Start - Data; | 
|  | 157 | ++Start; | 
|  | 158 | } while (Start < Stop); | 
| Benjamin Kramer | 4d681d7 | 2011-10-15 10:08:31 +0000 | [diff] [blame] | 159 | return npos; | 
|  | 160 | } | 
|  | 161 |  | 
|  | 162 | // Build the bad char heuristic table, with uint8_t to reduce cache thrashing. | 
|  | 163 | uint8_t BadCharSkip[256]; | 
|  | 164 | std::memset(BadCharSkip, N, 256); | 
|  | 165 | for (unsigned i = 0; i != N-1; ++i) | 
|  | 166 | BadCharSkip[(uint8_t)Str[i]] = N-1-i; | 
|  | 167 |  | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 168 | do { | 
| Chandler Carruth | ecbe619 | 2016-12-11 07:46:21 +0000 | [diff] [blame] | 169 | uint8_t Last = Start[N - 1]; | 
|  | 170 | if (LLVM_UNLIKELY(Last == (uint8_t)Needle[N - 1])) | 
|  | 171 | if (std::memcmp(Start, Needle, N - 1) == 0) | 
|  | 172 | return Start - Data; | 
| Benjamin Kramer | 4d681d7 | 2011-10-15 10:08:31 +0000 | [diff] [blame] | 173 |  | 
|  | 174 | // Otherwise skip the appropriate number of bytes. | 
| Chandler Carruth | ecbe619 | 2016-12-11 07:46:21 +0000 | [diff] [blame] | 175 | Start += BadCharSkip[Last]; | 
| Chandler Carruth | 233edd2 | 2015-09-10 11:17:49 +0000 | [diff] [blame] | 176 | } while (Start < Stop); | 
| Benjamin Kramer | 4d681d7 | 2011-10-15 10:08:31 +0000 | [diff] [blame] | 177 |  | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 178 | return npos; | 
|  | 179 | } | 
|  | 180 |  | 
| Zachary Turner | 17412b0 | 2016-11-12 17:17:12 +0000 | [diff] [blame] | 181 | size_t StringRef::find_lower(StringRef Str, size_t From) const { | 
|  | 182 | StringRef This = substr(From); | 
|  | 183 | while (This.size() >= Str.size()) { | 
|  | 184 | if (This.startswith_lower(Str)) | 
|  | 185 | return From; | 
|  | 186 | This = This.drop_front(); | 
|  | 187 | ++From; | 
|  | 188 | } | 
|  | 189 | return npos; | 
|  | 190 | } | 
|  | 191 |  | 
|  | 192 | size_t StringRef::rfind_lower(char C, size_t From) const { | 
|  | 193 | From = std::min(From, Length); | 
|  | 194 | size_t i = From; | 
|  | 195 | while (i != 0) { | 
|  | 196 | --i; | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 197 | if (toLower(Data[i]) == toLower(C)) | 
| Zachary Turner | 17412b0 | 2016-11-12 17:17:12 +0000 | [diff] [blame] | 198 | return i; | 
|  | 199 | } | 
|  | 200 | return npos; | 
|  | 201 | } | 
|  | 202 |  | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 203 | /// rfind - Search for the last string \arg Str in the string. | 
|  | 204 | /// | 
| Chris Lattner | 0ab5e2c | 2011-04-15 05:18:47 +0000 | [diff] [blame] | 205 | /// \return - The index of the last occurrence of \arg Str, or npos if not | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 206 | /// found. | 
| Daniel Dunbar | ad36e8a | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 207 | size_t StringRef::rfind(StringRef Str) const { | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 208 | size_t N = Str.size(); | 
|  | 209 | if (N > Length) | 
|  | 210 | return npos; | 
|  | 211 | for (size_t i = Length - N + 1, e = 0; i != e;) { | 
|  | 212 | --i; | 
|  | 213 | if (substr(i, N).equals(Str)) | 
|  | 214 | return i; | 
|  | 215 | } | 
|  | 216 | return npos; | 
|  | 217 | } | 
|  | 218 |  | 
| Zachary Turner | 17412b0 | 2016-11-12 17:17:12 +0000 | [diff] [blame] | 219 | size_t StringRef::rfind_lower(StringRef Str) const { | 
|  | 220 | size_t N = Str.size(); | 
|  | 221 | if (N > Length) | 
|  | 222 | return npos; | 
|  | 223 | for (size_t i = Length - N + 1, e = 0; i != e;) { | 
|  | 224 | --i; | 
|  | 225 | if (substr(i, N).equals_lower(Str)) | 
|  | 226 | return i; | 
|  | 227 | } | 
|  | 228 | return npos; | 
|  | 229 | } | 
|  | 230 |  | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 231 | /// find_first_of - Find the first character in the string that is in \arg | 
|  | 232 | /// Chars, or npos if not found. | 
|  | 233 | /// | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 234 | /// Note: O(size() + Chars.size()) | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 235 | StringRef::size_type StringRef::find_first_of(StringRef Chars, | 
|  | 236 | size_t From) const { | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 237 | std::bitset<1 << CHAR_BIT> CharBits; | 
|  | 238 | for (size_type i = 0; i != Chars.size(); ++i) | 
|  | 239 | CharBits.set((unsigned char)Chars[i]); | 
|  | 240 |  | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 241 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 242 | if (CharBits.test((unsigned char)Data[i])) | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 243 | return i; | 
|  | 244 | return npos; | 
|  | 245 | } | 
|  | 246 |  | 
|  | 247 | /// find_first_not_of - Find the first character in the string that is not | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 248 | /// \arg C or npos if not found. | 
|  | 249 | StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 250 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 251 | if (Data[i] != C) | 
|  | 252 | return i; | 
|  | 253 | return npos; | 
|  | 254 | } | 
|  | 255 |  | 
|  | 256 | /// find_first_not_of - Find the first character in the string that is not | 
|  | 257 | /// in the string \arg Chars, or npos if not found. | 
|  | 258 | /// | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 259 | /// Note: O(size() + Chars.size()) | 
| Daniel Dunbar | 9806e4a | 2009-11-11 00:28:53 +0000 | [diff] [blame] | 260 | StringRef::size_type StringRef::find_first_not_of(StringRef Chars, | 
|  | 261 | size_t From) const { | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 262 | std::bitset<1 << CHAR_BIT> CharBits; | 
|  | 263 | for (size_type i = 0; i != Chars.size(); ++i) | 
|  | 264 | CharBits.set((unsigned char)Chars[i]); | 
|  | 265 |  | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 266 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) | 
| Benjamin Kramer | 08fd2cf | 2010-08-23 18:16:08 +0000 | [diff] [blame] | 267 | if (!CharBits.test((unsigned char)Data[i])) | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 268 | return i; | 
|  | 269 | return npos; | 
|  | 270 | } | 
|  | 271 |  | 
| Michael J. Spencer | e1d3603d | 2010-11-30 23:27:35 +0000 | [diff] [blame] | 272 | /// find_last_of - Find the last character in the string that is in \arg C, | 
|  | 273 | /// or npos if not found. | 
|  | 274 | /// | 
|  | 275 | /// Note: O(size() + Chars.size()) | 
|  | 276 | StringRef::size_type StringRef::find_last_of(StringRef Chars, | 
|  | 277 | size_t From) const { | 
|  | 278 | std::bitset<1 << CHAR_BIT> CharBits; | 
|  | 279 | for (size_type i = 0; i != Chars.size(); ++i) | 
|  | 280 | CharBits.set((unsigned char)Chars[i]); | 
|  | 281 |  | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 282 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) | 
| Michael J. Spencer | e1d3603d | 2010-11-30 23:27:35 +0000 | [diff] [blame] | 283 | if (CharBits.test((unsigned char)Data[i])) | 
|  | 284 | return i; | 
|  | 285 | return npos; | 
|  | 286 | } | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 287 |  | 
| Michael J. Spencer | 9330381 | 2012-05-11 22:08:50 +0000 | [diff] [blame] | 288 | /// find_last_not_of - Find the last character in the string that is not | 
|  | 289 | /// \arg C, or npos if not found. | 
|  | 290 | StringRef::size_type StringRef::find_last_not_of(char C, size_t From) const { | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 291 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) | 
| Michael J. Spencer | 9330381 | 2012-05-11 22:08:50 +0000 | [diff] [blame] | 292 | if (Data[i] != C) | 
|  | 293 | return i; | 
|  | 294 | return npos; | 
|  | 295 | } | 
|  | 296 |  | 
|  | 297 | /// find_last_not_of - Find the last character in the string that is not in | 
|  | 298 | /// \arg Chars, or npos if not found. | 
|  | 299 | /// | 
|  | 300 | /// Note: O(size() + Chars.size()) | 
|  | 301 | StringRef::size_type StringRef::find_last_not_of(StringRef Chars, | 
|  | 302 | size_t From) const { | 
|  | 303 | std::bitset<1 << CHAR_BIT> CharBits; | 
|  | 304 | for (size_type i = 0, e = Chars.size(); i != e; ++i) | 
|  | 305 | CharBits.set((unsigned char)Chars[i]); | 
|  | 306 |  | 
| Craig Topper | 3ced27c | 2014-08-21 04:31:10 +0000 | [diff] [blame] | 307 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) | 
| Michael J. Spencer | 9330381 | 2012-05-11 22:08:50 +0000 | [diff] [blame] | 308 | if (!CharBits.test((unsigned char)Data[i])) | 
|  | 309 | return i; | 
|  | 310 | return npos; | 
|  | 311 | } | 
|  | 312 |  | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 313 | void StringRef::split(SmallVectorImpl<StringRef> &A, | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 314 | StringRef Separator, int MaxSplit, | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 315 | bool KeepEmpty) const { | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 316 | StringRef S = *this; | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 317 |  | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 318 | // Count down from MaxSplit. When MaxSplit is -1, this will just split | 
|  | 319 | // "forever". This doesn't support splitting more than 2^31 times | 
|  | 320 | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer | 
|  | 321 | // but that seems unlikely to be useful. | 
|  | 322 | while (MaxSplit-- != 0) { | 
|  | 323 | size_t Idx = S.find(Separator); | 
|  | 324 | if (Idx == npos) | 
|  | 325 | break; | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 326 |  | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 327 | // Push this split. | 
|  | 328 | if (KeepEmpty || Idx > 0) | 
|  | 329 | A.push_back(S.slice(0, Idx)); | 
|  | 330 |  | 
|  | 331 | // Jump forward. | 
|  | 332 | S = S.slice(Idx + Separator.size(), npos); | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 333 | } | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 334 |  | 
|  | 335 | // Push the tail. | 
|  | 336 | if (KeepEmpty || !S.empty()) | 
|  | 337 | A.push_back(S); | 
| Duncan Sands | 8570b29 | 2012-02-21 12:00:25 +0000 | [diff] [blame] | 338 | } | 
|  | 339 |  | 
| Chandler Carruth | 4771217 | 2015-09-10 06:07:03 +0000 | [diff] [blame] | 340 | void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator, | 
|  | 341 | int MaxSplit, bool KeepEmpty) const { | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 342 | StringRef S = *this; | 
| Chandler Carruth | 4771217 | 2015-09-10 06:07:03 +0000 | [diff] [blame] | 343 |  | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 344 | // Count down from MaxSplit. When MaxSplit is -1, this will just split | 
|  | 345 | // "forever". This doesn't support splitting more than 2^31 times | 
|  | 346 | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer | 
|  | 347 | // but that seems unlikely to be useful. | 
|  | 348 | while (MaxSplit-- != 0) { | 
|  | 349 | size_t Idx = S.find(Separator); | 
|  | 350 | if (Idx == npos) | 
|  | 351 | break; | 
| Chandler Carruth | 4771217 | 2015-09-10 06:07:03 +0000 | [diff] [blame] | 352 |  | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 353 | // Push this split. | 
|  | 354 | if (KeepEmpty || Idx > 0) | 
|  | 355 | A.push_back(S.slice(0, Idx)); | 
|  | 356 |  | 
|  | 357 | // Jump forward. | 
|  | 358 | S = S.slice(Idx + 1, npos); | 
| Chandler Carruth | 4771217 | 2015-09-10 06:07:03 +0000 | [diff] [blame] | 359 | } | 
| Chandler Carruth | 4425c91 | 2015-09-10 07:51:37 +0000 | [diff] [blame] | 360 |  | 
|  | 361 | // Push the tail. | 
|  | 362 | if (KeepEmpty || !S.empty()) | 
|  | 363 | A.push_back(S); | 
| Chandler Carruth | 4771217 | 2015-09-10 06:07:03 +0000 | [diff] [blame] | 364 | } | 
|  | 365 |  | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 366 | //===----------------------------------------------------------------------===// | 
|  | 367 | // Helpful Algorithms | 
|  | 368 | //===----------------------------------------------------------------------===// | 
|  | 369 |  | 
|  | 370 | /// count - Return the number of non-overlapped occurrences of \arg Str in | 
|  | 371 | /// the string. | 
| Daniel Dunbar | ad36e8a | 2009-11-06 10:58:06 +0000 | [diff] [blame] | 372 | size_t StringRef::count(StringRef Str) const { | 
| Chris Lattner | 372a8ae | 2009-09-20 01:22:16 +0000 | [diff] [blame] | 373 | size_t Count = 0; | 
|  | 374 | size_t N = Str.size(); | 
|  | 375 | if (N > Length) | 
|  | 376 | return 0; | 
|  | 377 | for (size_t i = 0, e = Length - N + 1; i != e; ++i) | 
|  | 378 | if (substr(i, N).equals(Str)) | 
|  | 379 | ++Count; | 
|  | 380 | return Count; | 
|  | 381 | } | 
|  | 382 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 383 | static unsigned GetAutoSenseRadix(StringRef &Str) { | 
| Zachary Turner | d5d5763 | 2016-09-22 15:55:05 +0000 | [diff] [blame] | 384 | if (Str.empty()) | 
|  | 385 | return 10; | 
|  | 386 |  | 
| Colin LeMahieu | 0143146 | 2016-03-18 18:22:07 +0000 | [diff] [blame] | 387 | if (Str.startswith("0x") || Str.startswith("0X")) { | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 388 | Str = Str.substr(2); | 
|  | 389 | return 16; | 
| Chris Lattner | 0a1bafe | 2012-04-21 22:03:05 +0000 | [diff] [blame] | 390 | } | 
| Fangrui Song | f78650a | 2018-07-30 19:41:25 +0000 | [diff] [blame] | 391 |  | 
| Colin LeMahieu | 0143146 | 2016-03-18 18:22:07 +0000 | [diff] [blame] | 392 | if (Str.startswith("0b") || Str.startswith("0B")) { | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 393 | Str = Str.substr(2); | 
|  | 394 | return 2; | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 395 | } | 
| Chris Lattner | 0a1bafe | 2012-04-21 22:03:05 +0000 | [diff] [blame] | 396 |  | 
|  | 397 | if (Str.startswith("0o")) { | 
|  | 398 | Str = Str.substr(2); | 
|  | 399 | return 8; | 
|  | 400 | } | 
|  | 401 |  | 
| Francis Visoiu Mistrih | 26d6fc1 | 2017-11-28 14:22:27 +0000 | [diff] [blame] | 402 | if (Str[0] == '0' && Str.size() > 1 && isDigit(Str[1])) { | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 403 | Str = Str.substr(1); | 
| Chris Lattner | 0a1bafe | 2012-04-21 22:03:05 +0000 | [diff] [blame] | 404 | return 8; | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 405 | } | 
|  | 406 |  | 
| Chris Lattner | 0a1bafe | 2012-04-21 22:03:05 +0000 | [diff] [blame] | 407 | return 10; | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 408 | } | 
|  | 409 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 410 | bool llvm::consumeUnsignedInteger(StringRef &Str, unsigned Radix, | 
|  | 411 | unsigned long long &Result) { | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 412 | // Autosense radix if not specified. | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 413 | if (Radix == 0) | 
|  | 414 | Radix = GetAutoSenseRadix(Str); | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 415 |  | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 416 | // Empty strings (after the radix autosense) are invalid. | 
|  | 417 | if (Str.empty()) return true; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 418 |  | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 419 | // Parse all the bytes of the string given this radix.  Watch for overflow. | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 420 | StringRef Str2 = Str; | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 421 | Result = 0; | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 422 | while (!Str2.empty()) { | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 423 | unsigned CharVal; | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 424 | if (Str2[0] >= '0' && Str2[0] <= '9') | 
|  | 425 | CharVal = Str2[0] - '0'; | 
|  | 426 | else if (Str2[0] >= 'a' && Str2[0] <= 'z') | 
|  | 427 | CharVal = Str2[0] - 'a' + 10; | 
|  | 428 | else if (Str2[0] >= 'A' && Str2[0] <= 'Z') | 
|  | 429 | CharVal = Str2[0] - 'A' + 10; | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 430 | else | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 431 | break; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 432 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 433 | // If the parsed value is larger than the integer radix, we cannot | 
|  | 434 | // consume any more characters. | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 435 | if (CharVal >= Radix) | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 436 | break; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 437 |  | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 438 | // Add in this character. | 
|  | 439 | unsigned long long PrevResult = Result; | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 440 | Result = Result * Radix + CharVal; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 441 |  | 
| Nick Kledzik | 35c79da | 2012-10-02 20:01:48 +0000 | [diff] [blame] | 442 | // Check for overflow by shifting back and seeing if bits were lost. | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 443 | if (Result / Radix < PrevResult) | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 444 | return true; | 
|  | 445 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 446 | Str2 = Str2.substr(1); | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 447 | } | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 448 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 449 | // We consider the operation a failure if no characters were consumed | 
|  | 450 | // successfully. | 
|  | 451 | if (Str.size() == Str2.size()) | 
|  | 452 | return true; | 
|  | 453 |  | 
|  | 454 | Str = Str2; | 
| Chris Lattner | 68ee700 | 2009-09-19 19:47:14 +0000 | [diff] [blame] | 455 | return false; | 
|  | 456 | } | 
|  | 457 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 458 | bool llvm::consumeSignedInteger(StringRef &Str, unsigned Radix, | 
|  | 459 | long long &Result) { | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 460 | unsigned long long ULLVal; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 461 |  | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 462 | // Handle positive strings first. | 
| Michael J. Spencer | cfa95f6 | 2012-03-10 23:02:54 +0000 | [diff] [blame] | 463 | if (Str.empty() || Str.front() != '-') { | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 464 | if (consumeUnsignedInteger(Str, Radix, ULLVal) || | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 465 | // Check for value so large it overflows a signed value. | 
|  | 466 | (long long)ULLVal < 0) | 
|  | 467 | return true; | 
|  | 468 | Result = ULLVal; | 
|  | 469 | return false; | 
|  | 470 | } | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 471 |  | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 472 | // Get the positive part of the value. | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 473 | StringRef Str2 = Str.drop_front(1); | 
|  | 474 | if (consumeUnsignedInteger(Str2, Radix, ULLVal) || | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 475 | // Reject values so large they'd overflow as negative signed, but allow | 
|  | 476 | // "-0".  This negates the unsigned so that the negative isn't undefined | 
|  | 477 | // on signed overflow. | 
|  | 478 | (long long)-ULLVal > 0) | 
|  | 479 | return true; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 480 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 481 | Str = Str2; | 
| Chris Lattner | 84c1527 | 2009-09-19 23:58:48 +0000 | [diff] [blame] | 482 | Result = -ULLVal; | 
|  | 483 | return false; | 
|  | 484 | } | 
|  | 485 |  | 
| Zachary Turner | 65fd2fc | 2016-09-22 15:05:19 +0000 | [diff] [blame] | 486 | /// GetAsUnsignedInteger - Workhorse method that converts a integer character | 
|  | 487 | /// sequence of radix up to 36 to an unsigned long long value. | 
|  | 488 | bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix, | 
|  | 489 | unsigned long long &Result) { | 
|  | 490 | if (consumeUnsignedInteger(Str, Radix, Result)) | 
|  | 491 | return true; | 
|  | 492 |  | 
|  | 493 | // For getAsUnsignedInteger, we require the whole string to be consumed or | 
|  | 494 | // else we consider it a failure. | 
|  | 495 | return !Str.empty(); | 
|  | 496 | } | 
|  | 497 |  | 
|  | 498 | bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix, | 
|  | 499 | long long &Result) { | 
|  | 500 | if (consumeSignedInteger(Str, Radix, Result)) | 
|  | 501 | return true; | 
|  | 502 |  | 
|  | 503 | // For getAsSignedInteger, we require the whole string to be consumed or else | 
|  | 504 | // we consider it a failure. | 
|  | 505 | return !Str.empty(); | 
|  | 506 | } | 
|  | 507 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 508 | bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const { | 
|  | 509 | StringRef Str = *this; | 
|  | 510 |  | 
|  | 511 | // Autosense radix if not specified. | 
|  | 512 | if (Radix == 0) | 
|  | 513 | Radix = GetAutoSenseRadix(Str); | 
|  | 514 |  | 
|  | 515 | assert(Radix > 1 && Radix <= 36); | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 516 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 517 | // Empty strings (after the radix autosense) are invalid. | 
|  | 518 | if (Str.empty()) return true; | 
|  | 519 |  | 
|  | 520 | // Skip leading zeroes.  This can be a significant improvement if | 
|  | 521 | // it means we don't need > 64 bits. | 
|  | 522 | while (!Str.empty() && Str.front() == '0') | 
|  | 523 | Str = Str.substr(1); | 
|  | 524 |  | 
|  | 525 | // If it was nothing but zeroes.... | 
|  | 526 | if (Str.empty()) { | 
|  | 527 | Result = APInt(64, 0); | 
|  | 528 | return false; | 
|  | 529 | } | 
|  | 530 |  | 
|  | 531 | // (Over-)estimate the required number of bits. | 
|  | 532 | unsigned Log2Radix = 0; | 
|  | 533 | while ((1U << Log2Radix) < Radix) Log2Radix++; | 
|  | 534 | bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix); | 
|  | 535 |  | 
|  | 536 | unsigned BitWidth = Log2Radix * Str.size(); | 
|  | 537 | if (BitWidth < Result.getBitWidth()) | 
|  | 538 | BitWidth = Result.getBitWidth(); // don't shrink the result | 
| Chris Lattner | 5e14666 | 2012-04-23 00:27:54 +0000 | [diff] [blame] | 539 | else if (BitWidth > Result.getBitWidth()) | 
| Jay Foad | 583abbc | 2010-12-07 08:25:19 +0000 | [diff] [blame] | 540 | Result = Result.zext(BitWidth); | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 541 |  | 
|  | 542 | APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix | 
|  | 543 | if (!IsPowerOf2Radix) { | 
|  | 544 | // These must have the same bit-width as Result. | 
|  | 545 | RadixAP = APInt(BitWidth, Radix); | 
|  | 546 | CharAP = APInt(BitWidth, 0); | 
|  | 547 | } | 
|  | 548 |  | 
|  | 549 | // Parse all the bytes of the string given this radix. | 
|  | 550 | Result = 0; | 
|  | 551 | while (!Str.empty()) { | 
|  | 552 | unsigned CharVal; | 
|  | 553 | if (Str[0] >= '0' && Str[0] <= '9') | 
|  | 554 | CharVal = Str[0]-'0'; | 
|  | 555 | else if (Str[0] >= 'a' && Str[0] <= 'z') | 
|  | 556 | CharVal = Str[0]-'a'+10; | 
|  | 557 | else if (Str[0] >= 'A' && Str[0] <= 'Z') | 
|  | 558 | CharVal = Str[0]-'A'+10; | 
|  | 559 | else | 
|  | 560 | return true; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 561 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 562 | // If the parsed value is larger than the integer radix, the string is | 
|  | 563 | // invalid. | 
|  | 564 | if (CharVal >= Radix) | 
|  | 565 | return true; | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 566 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 567 | // Add in this character. | 
|  | 568 | if (IsPowerOf2Radix) { | 
|  | 569 | Result <<= Log2Radix; | 
|  | 570 | Result |= CharVal; | 
|  | 571 | } else { | 
|  | 572 | Result *= RadixAP; | 
|  | 573 | CharAP = CharVal; | 
|  | 574 | Result += CharAP; | 
|  | 575 | } | 
|  | 576 |  | 
|  | 577 | Str = Str.substr(1); | 
|  | 578 | } | 
| Michael J. Spencer | f13f442 | 2010-11-26 04:16:08 +0000 | [diff] [blame] | 579 |  | 
| John McCall | 512b650 | 2010-02-28 09:55:58 +0000 | [diff] [blame] | 580 | return false; | 
|  | 581 | } | 
| Chandler Carruth | ca99ad3 | 2012-03-04 10:55:27 +0000 | [diff] [blame] | 582 |  | 
| Zachary Turner | 8bd42a1 | 2017-02-14 19:06:37 +0000 | [diff] [blame] | 583 | bool StringRef::getAsDouble(double &Result, bool AllowInexact) const { | 
|  | 584 | APFloat F(0.0); | 
|  | 585 | APFloat::opStatus Status = | 
|  | 586 | F.convertFromString(*this, APFloat::rmNearestTiesToEven); | 
|  | 587 | if (Status != APFloat::opOK) { | 
| Serguei Katkov | 768d6dd | 2017-12-19 04:27:39 +0000 | [diff] [blame] | 588 | if (!AllowInexact || !(Status & APFloat::opInexact)) | 
| Zachary Turner | 8bd42a1 | 2017-02-14 19:06:37 +0000 | [diff] [blame] | 589 | return true; | 
|  | 590 | } | 
|  | 591 |  | 
|  | 592 | Result = F.convertToDouble(); | 
|  | 593 | return false; | 
|  | 594 | } | 
| Chandler Carruth | ca99ad3 | 2012-03-04 10:55:27 +0000 | [diff] [blame] | 595 |  | 
|  | 596 | // Implementation of StringRef hashing. | 
|  | 597 | hash_code llvm::hash_value(StringRef S) { | 
|  | 598 | return hash_combine_range(S.begin(), S.end()); | 
|  | 599 | } |