/src/keystone/llvm/lib/Support/StringRef.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "llvm/ADT/APInt.h" |
12 | | #include "llvm/ADT/Hashing.h" |
13 | | #include "llvm/ADT/edit_distance.h" |
14 | | #include <bitset> |
15 | | |
16 | | using namespace llvm_ks; |
17 | | |
18 | | // MSVC emits references to this into the translation units which reference it. |
19 | | #ifndef _MSC_VER |
20 | | const size_t StringRef::npos; |
21 | | #endif |
22 | | |
23 | 107M | static char ascii_tolower(char x) { |
24 | 107M | if (x >= 'A' && x <= 'Z') |
25 | 24.2M | return x - 'A' + 'a'; |
26 | 83.2M | return x; |
27 | 107M | } |
28 | | |
29 | 1.24M | static char ascii_toupper(char x) { |
30 | 1.24M | if (x >= 'a' && x <= 'z') |
31 | 66.2k | return x - 'a' + 'A'; |
32 | 1.17M | return x; |
33 | 1.24M | } |
34 | | |
35 | 0 | static bool ascii_isdigit(char x) { |
36 | 0 | return x >= '0' && x <= '9'; |
37 | 0 | } |
38 | | |
39 | | // strncasecmp() is not available on non-POSIX systems, so define an |
40 | | // alternative function here. |
41 | 1.60M | static int ascii_strncasecmp(const char *LHS, const char *RHS, size_t Length) { |
42 | 1.76M | for (size_t I = 0; I < Length; ++I) { |
43 | 1.67M | unsigned char LHC = ascii_tolower(LHS[I]); |
44 | 1.67M | unsigned char RHC = ascii_tolower(RHS[I]); |
45 | 1.67M | if (LHC != RHC) |
46 | 1.51M | return LHC < RHC ? -1 : 1; |
47 | 1.67M | } |
48 | 84.7k | return 0; |
49 | 1.60M | } |
50 | | |
51 | | /// compare_lower - Compare strings, ignoring case. |
52 | 1.60M | int StringRef::compare_lower(StringRef RHS) const { |
53 | 1.60M | if (int Res = ascii_strncasecmp(Data, RHS.Data, std::min(Length, RHS.Length))) |
54 | 1.51M | return Res; |
55 | 84.5k | if (Length == RHS.Length) |
56 | 73.3k | return 0; |
57 | 11.2k | return Length < RHS.Length ? -1 : 1; |
58 | 84.5k | } |
59 | | |
60 | | /// Check if this string starts with the given \p Prefix, ignoring case. |
61 | 4.98k | bool StringRef::startswith_lower(StringRef Prefix) const { |
62 | 4.98k | return Length >= Prefix.Length && |
63 | 4.98k | ascii_strncasecmp(Data, Prefix.Data, Prefix.Length) == 0; |
64 | 4.98k | } |
65 | | |
66 | | /// Check if this string ends with the given \p Suffix, ignoring case. |
67 | 0 | bool StringRef::endswith_lower(StringRef Suffix) const { |
68 | 0 | return Length >= Suffix.Length && |
69 | 0 | ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; |
70 | 0 | } |
71 | | |
72 | | /// compare_numeric - Compare strings, handle embedded numbers. |
73 | 0 | int StringRef::compare_numeric(StringRef RHS) const { |
74 | 0 | for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) { |
75 | | // Check for sequences of digits. |
76 | 0 | if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) { |
77 | | // The longer sequence of numbers is considered larger. |
78 | | // This doesn't really handle prefixed zeros well. |
79 | 0 | size_t J; |
80 | 0 | for (J = I + 1; J != E + 1; ++J) { |
81 | 0 | bool ld = J < Length && ascii_isdigit(Data[J]); |
82 | 0 | bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]); |
83 | 0 | if (ld != rd) |
84 | 0 | return rd ? -1 : 1; |
85 | 0 | if (!rd) |
86 | 0 | break; |
87 | 0 | } |
88 | | // The two number sequences have the same length (J-I), just memcmp them. |
89 | 0 | if (int Res = compareMemory(Data + I, RHS.Data + I, J - I)) |
90 | 0 | return Res < 0 ? -1 : 1; |
91 | | // Identical number sequences, continue search after the numbers. |
92 | 0 | I = J - 1; |
93 | 0 | continue; |
94 | 0 | } |
95 | 0 | if (Data[I] != RHS.Data[I]) |
96 | 0 | return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; |
97 | 0 | } |
98 | 0 | if (Length == RHS.Length) |
99 | 0 | return 0; |
100 | 0 | return Length < RHS.Length ? -1 : 1; |
101 | 0 | } |
102 | | |
103 | | // Compute the edit distance between the two given strings. |
104 | | unsigned StringRef::edit_distance(llvm_ks::StringRef Other, |
105 | | bool AllowReplacements, |
106 | 0 | unsigned MaxEditDistance) const { |
107 | 0 | return llvm_ks::ComputeEditDistance( |
108 | 0 | makeArrayRef(data(), size()), |
109 | 0 | makeArrayRef(Other.data(), Other.size()), |
110 | 0 | AllowReplacements, MaxEditDistance); |
111 | 0 | } |
112 | | |
113 | | //===----------------------------------------------------------------------===// |
114 | | // String Operations |
115 | | //===----------------------------------------------------------------------===// |
116 | | |
117 | 15.4M | std::string StringRef::lower() const { |
118 | 15.4M | std::string Result(size(), char()); |
119 | 119M | for (size_type i = 0, e = size(); i != e; ++i) { |
120 | 104M | Result[i] = ascii_tolower(Data[i]); |
121 | 104M | } |
122 | 15.4M | return Result; |
123 | 15.4M | } |
124 | | |
125 | 84.2k | std::string StringRef::upper() const { |
126 | 84.2k | std::string Result(size(), char()); |
127 | 1.32M | for (size_type i = 0, e = size(); i != e; ++i) { |
128 | 1.24M | Result[i] = ascii_toupper(Data[i]); |
129 | 1.24M | } |
130 | 84.2k | return Result; |
131 | 84.2k | } |
132 | | |
133 | | //===----------------------------------------------------------------------===// |
134 | | // String Searching |
135 | | //===----------------------------------------------------------------------===// |
136 | | |
137 | | |
138 | | /// find - Search for the first string \arg Str in the string. |
139 | | /// |
140 | | /// \return - The index of the first occurrence of \arg Str, or npos if not |
141 | | /// found. |
142 | 1.47M | size_t StringRef::find(StringRef Str, size_t From) const { |
143 | 1.47M | if (From > Length) |
144 | 0 | return npos; |
145 | | |
146 | 1.47M | const char *Needle = Str.data(); |
147 | 1.47M | size_t N = Str.size(); |
148 | 1.47M | if (N == 0) |
149 | 0 | return From; |
150 | | |
151 | 1.47M | size_t Size = Length - From; |
152 | 1.47M | if (Size < N) |
153 | 0 | return npos; |
154 | | |
155 | 1.47M | const char *Start = Data + From; |
156 | 1.47M | const char *Stop = Start + (Size - N + 1); |
157 | | |
158 | | // For short haystacks or unsupported needles fall back to the naive algorithm |
159 | 1.47M | if (Size < 16 || N > 255) { |
160 | 1.66M | do { |
161 | 1.66M | if (std::memcmp(Start, Needle, N) == 0) |
162 | 1.12k | return Start - Data; |
163 | 1.66M | ++Start; |
164 | 1.66M | } while (Start < Stop); |
165 | 1.47M | return npos; |
166 | 1.47M | } |
167 | | |
168 | | // Build the bad char heuristic table, with uint8_t to reduce cache thrashing. |
169 | 2.03k | uint8_t BadCharSkip[256]; |
170 | 2.03k | std::memset(BadCharSkip, N, 256); |
171 | 4.06k | for (unsigned i = 0; i != N-1; ++i) |
172 | 2.03k | BadCharSkip[(uint8_t)Str[i]] = N-1-i; |
173 | | |
174 | 60.3k | do { |
175 | 60.3k | if (std::memcmp(Start, Needle, N) == 0) |
176 | 944 | return Start - Data; |
177 | | |
178 | | // Otherwise skip the appropriate number of bytes. |
179 | 59.4k | Start += BadCharSkip[(uint8_t)Start[N-1]]; |
180 | 59.4k | } while (Start < Stop); |
181 | | |
182 | 1.08k | return npos; |
183 | 2.03k | } |
184 | | |
185 | | /// rfind - Search for the last string \arg Str in the string. |
186 | | /// |
187 | | /// \return - The index of the last occurrence of \arg Str, or npos if not |
188 | | /// found. |
189 | 0 | size_t StringRef::rfind(StringRef Str) const { |
190 | 0 | size_t N = Str.size(); |
191 | 0 | if (N > Length) |
192 | 0 | return npos; |
193 | 0 | for (size_t i = Length - N + 1, e = 0; i != e;) { |
194 | 0 | --i; |
195 | 0 | if (substr(i, N).equals(Str)) |
196 | 0 | return i; |
197 | 0 | } |
198 | 0 | return npos; |
199 | 0 | } |
200 | | |
201 | | /// find_first_of - Find the first character in the string that is in \arg |
202 | | /// Chars, or npos if not found. |
203 | | /// |
204 | | /// Note: O(size() + Chars.size()) |
205 | | StringRef::size_type StringRef::find_first_of(StringRef Chars, |
206 | 1.57k | size_t From) const { |
207 | 1.57k | std::bitset<1 << CHAR_BIT> CharBits; |
208 | 6.29k | for (size_type i = 0; i != Chars.size(); ++i) |
209 | 4.72k | CharBits.set((unsigned char)Chars[i]); |
210 | | |
211 | 28.3k | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
212 | 26.7k | if (CharBits.test((unsigned char)Data[i])) |
213 | 0 | return i; |
214 | 1.57k | return npos; |
215 | 1.57k | } |
216 | | |
217 | | /// find_first_not_of - Find the first character in the string that is not |
218 | | /// \arg C or npos if not found. |
219 | 0 | StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { |
220 | 0 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
221 | 0 | if (Data[i] != C) |
222 | 0 | return i; |
223 | 0 | return npos; |
224 | 0 | } |
225 | | |
226 | | /// find_first_not_of - Find the first character in the string that is not |
227 | | /// in the string \arg Chars, or npos if not found. |
228 | | /// |
229 | | /// Note: O(size() + Chars.size()) |
230 | | StringRef::size_type StringRef::find_first_not_of(StringRef Chars, |
231 | 911k | size_t From) const { |
232 | 911k | std::bitset<1 << CHAR_BIT> CharBits; |
233 | 6.38M | for (size_type i = 0; i != Chars.size(); ++i) |
234 | 5.46M | CharBits.set((unsigned char)Chars[i]); |
235 | | |
236 | 982k | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
237 | 945k | if (!CharBits.test((unsigned char)Data[i])) |
238 | 874k | return i; |
239 | 37.2k | return npos; |
240 | 911k | } |
241 | | |
242 | | /// find_last_of - Find the last character in the string that is in \arg C, |
243 | | /// or npos if not found. |
244 | | /// |
245 | | /// Note: O(size() + Chars.size()) |
246 | | StringRef::size_type StringRef::find_last_of(StringRef Chars, |
247 | 1.50M | size_t From) const { |
248 | 1.50M | std::bitset<1 << CHAR_BIT> CharBits; |
249 | 4.51M | for (size_type i = 0; i != Chars.size(); ++i) |
250 | 3.00M | CharBits.set((unsigned char)Chars[i]); |
251 | | |
252 | 60.3M | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
253 | 59.3M | if (CharBits.test((unsigned char)Data[i])) |
254 | 497k | return i; |
255 | 1.00M | return npos; |
256 | 1.50M | } |
257 | | |
258 | | /// find_last_not_of - Find the last character in the string that is not |
259 | | /// \arg C, or npos if not found. |
260 | 0 | StringRef::size_type StringRef::find_last_not_of(char C, size_t From) const { |
261 | 0 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
262 | 0 | if (Data[i] != C) |
263 | 0 | return i; |
264 | 0 | return npos; |
265 | 0 | } |
266 | | |
267 | | /// find_last_not_of - Find the last character in the string that is not in |
268 | | /// \arg Chars, or npos if not found. |
269 | | /// |
270 | | /// Note: O(size() + Chars.size()) |
271 | | StringRef::size_type StringRef::find_last_not_of(StringRef Chars, |
272 | 911k | size_t From) const { |
273 | 911k | std::bitset<1 << CHAR_BIT> CharBits; |
274 | 6.38M | for (size_type i = 0, e = Chars.size(); i != e; ++i) |
275 | 5.46M | CharBits.set((unsigned char)Chars[i]); |
276 | | |
277 | 1.01M | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
278 | 977k | if (!CharBits.test((unsigned char)Data[i])) |
279 | 874k | return i; |
280 | 37.2k | return npos; |
281 | 911k | } |
282 | | |
283 | | void StringRef::split(SmallVectorImpl<StringRef> &A, |
284 | | StringRef Separator, int MaxSplit, |
285 | 0 | bool KeepEmpty) const { |
286 | 0 | StringRef S = *this; |
287 | | |
288 | | // Count down from MaxSplit. When MaxSplit is -1, this will just split |
289 | | // "forever". This doesn't support splitting more than 2^31 times |
290 | | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer |
291 | | // but that seems unlikely to be useful. |
292 | 0 | while (MaxSplit-- != 0) { |
293 | 0 | size_t Idx = S.find(Separator); |
294 | 0 | if (Idx == npos) |
295 | 0 | break; |
296 | | |
297 | | // Push this split. |
298 | 0 | if (KeepEmpty || Idx > 0) |
299 | 0 | A.push_back(S.slice(0, Idx)); |
300 | | |
301 | | // Jump forward. |
302 | 0 | S = S.slice(Idx + Separator.size(), npos); |
303 | 0 | } |
304 | | |
305 | | // Push the tail. |
306 | 0 | if (KeepEmpty || !S.empty()) |
307 | 0 | A.push_back(S); |
308 | 0 | } |
309 | | |
310 | | void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator, |
311 | 1.75M | int MaxSplit, bool KeepEmpty) const { |
312 | 1.75M | StringRef S = *this; |
313 | | |
314 | | // Count down from MaxSplit. When MaxSplit is -1, this will just split |
315 | | // "forever". This doesn't support splitting more than 2^31 times |
316 | | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer |
317 | | // but that seems unlikely to be useful. |
318 | 2.46M | while (MaxSplit-- != 0) { |
319 | 2.33M | size_t Idx = S.find(Separator); |
320 | 2.33M | if (Idx == npos) |
321 | 1.62M | break; |
322 | | |
323 | | // Push this split. |
324 | 714k | if (KeepEmpty || Idx > 0) |
325 | 713k | A.push_back(S.slice(0, Idx)); |
326 | | |
327 | | // Jump forward. |
328 | 714k | S = S.slice(Idx + 1, npos); |
329 | 714k | } |
330 | | |
331 | | // Push the tail. |
332 | 1.75M | if (KeepEmpty || !S.empty()) |
333 | 1.69M | A.push_back(S); |
334 | 1.75M | } |
335 | | |
336 | | //===----------------------------------------------------------------------===// |
337 | | // Helpful Algorithms |
338 | | //===----------------------------------------------------------------------===// |
339 | | |
340 | | /// count - Return the number of non-overlapped occurrences of \arg Str in |
341 | | /// the string. |
342 | 0 | size_t StringRef::count(StringRef Str) const { |
343 | 0 | size_t Count = 0; |
344 | 0 | size_t N = Str.size(); |
345 | 0 | if (N > Length) |
346 | 0 | return 0; |
347 | 0 | for (size_t i = 0, e = Length - N + 1; i != e; ++i) |
348 | 0 | if (substr(i, N).equals(Str)) |
349 | 0 | ++Count; |
350 | 0 | return Count; |
351 | 0 | } |
352 | | |
353 | 45.9k | static unsigned GetAutoSenseRadix(StringRef &Str) { |
354 | 45.9k | if (Str.startswith("0x") || Str.startswith("0X")) { |
355 | 45.9k | Str = Str.substr(2); |
356 | 45.9k | return 16; |
357 | 45.9k | } |
358 | | |
359 | 0 | if (Str.startswith("0b")) { |
360 | 0 | Str = Str.substr(2); |
361 | 0 | return 2; |
362 | 0 | } |
363 | | |
364 | 0 | if (Str.startswith("0o")) { |
365 | 0 | Str = Str.substr(2); |
366 | 0 | return 8; |
367 | 0 | } |
368 | | |
369 | 0 | if (Str.startswith("0")) |
370 | 0 | return 8; |
371 | | |
372 | 0 | return 10; |
373 | 0 | } |
374 | | |
375 | | |
376 | | /// GetAsUnsignedInteger - Workhorse method that converts a integer character |
377 | | /// sequence of radix up to 36 to an unsigned long long value. |
378 | | bool llvm_ks::getAsUnsignedInteger(StringRef Str, unsigned Radix, |
379 | 8.60k | unsigned long long &Result) { |
380 | | // Autosense radix if not specified. |
381 | 8.60k | if (Radix == 0) |
382 | 0 | Radix = GetAutoSenseRadix(Str); |
383 | | |
384 | | // Empty strings (after the radix autosense) are invalid. |
385 | 8.60k | if (Str.empty()) return true; |
386 | | |
387 | | // Parse all the bytes of the string given this radix. Watch for overflow. |
388 | 8.29k | Result = 0; |
389 | 43.0k | while (!Str.empty()) { |
390 | 40.6k | unsigned CharVal; |
391 | 40.6k | if (Str[0] >= '0' && Str[0] <= '9') |
392 | 34.7k | CharVal = Str[0]-'0'; |
393 | 5.87k | else if (Str[0] >= 'a' && Str[0] <= 'z') |
394 | 3.08k | CharVal = Str[0]-'a'+10; |
395 | 2.79k | else if (Str[0] >= 'A' && Str[0] <= 'Z') |
396 | 2.29k | CharVal = Str[0]-'A'+10; |
397 | 492 | else |
398 | 492 | return true; |
399 | | |
400 | | // If the parsed value is larger than the integer radix, the string is |
401 | | // invalid. |
402 | 40.1k | if (CharVal >= Radix) |
403 | 5.38k | return true; |
404 | | |
405 | | // Add in this character. |
406 | 34.7k | unsigned long long PrevResult = Result; |
407 | 34.7k | Result = Result*Radix+CharVal; |
408 | | |
409 | | // Check for overflow by shifting back and seeing if bits were lost. |
410 | 34.7k | if (Result/Radix < PrevResult) |
411 | 55 | return true; |
412 | | |
413 | 34.7k | Str = Str.substr(1); |
414 | 34.7k | } |
415 | | |
416 | 2.36k | return false; |
417 | 8.29k | } |
418 | | |
419 | | bool llvm_ks::getAsSignedInteger(StringRef Str, unsigned Radix, |
420 | 5.34k | long long &Result) { |
421 | 5.34k | unsigned long long ULLVal; |
422 | | |
423 | | // Handle positive strings first. |
424 | 5.34k | if (Str.empty() || Str.front() != '-') { |
425 | 5.34k | if (getAsUnsignedInteger(Str, Radix, ULLVal) || |
426 | | // Check for value so large it overflows a signed value. |
427 | 5.34k | (long long)ULLVal < 0) |
428 | 3.71k | return true; |
429 | 1.63k | Result = ULLVal; |
430 | 1.63k | return false; |
431 | 5.34k | } |
432 | | |
433 | | // Get the positive part of the value. |
434 | 0 | if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) || |
435 | | // Reject values so large they'd overflow as negative signed, but allow |
436 | | // "-0". This negates the unsigned so that the negative isn't undefined |
437 | | // on signed overflow. |
438 | 0 | (long long)-ULLVal > 0) |
439 | 0 | return true; |
440 | | |
441 | 0 | Result = -ULLVal; |
442 | 0 | return false; |
443 | 0 | } |
444 | | |
445 | 6.51M | bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const { |
446 | 6.51M | StringRef Str = *this; |
447 | | |
448 | | // Autosense radix if not specified. |
449 | 6.51M | if (Radix == 0) |
450 | 45.9k | Radix = GetAutoSenseRadix(Str); |
451 | | |
452 | 6.51M | assert(Radix > 1 && Radix <= 36); |
453 | | |
454 | | // Empty strings (after the radix autosense) are invalid. |
455 | 6.51M | if (Str.empty()) return true; |
456 | | |
457 | | // Skip leading zeroes. This can be a significant improvement if |
458 | | // it means we don't need > 64 bits. |
459 | 8.99M | while (!Str.empty() && Str.front() == '0') |
460 | 2.48M | Str = Str.substr(1); |
461 | | |
462 | | // If it was nothing but zeroes.... |
463 | 6.51M | if (Str.empty()) { |
464 | 1.11M | Result = APInt(64, 0); |
465 | 1.11M | return false; |
466 | 1.11M | } |
467 | | |
468 | | // (Over-)estimate the required number of bits. |
469 | 5.40M | unsigned Log2Radix = 0; |
470 | 26.5M | while ((1U << Log2Radix) < Radix) Log2Radix++; |
471 | 5.40M | bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix); |
472 | | |
473 | 5.40M | unsigned BitWidth = Log2Radix * Str.size(); |
474 | 5.40M | if (BitWidth < Result.getBitWidth()) |
475 | 5.33M | BitWidth = Result.getBitWidth(); // don't shrink the result |
476 | 64.2k | else if (BitWidth > Result.getBitWidth()) |
477 | 52.8k | Result = Result.zext(BitWidth); |
478 | | |
479 | 5.40M | APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix |
480 | 5.40M | if (!IsPowerOf2Radix) { |
481 | | // These must have the same bit-width as Result. |
482 | 254 | RadixAP = APInt(BitWidth, Radix); |
483 | 254 | CharAP = APInt(BitWidth, 0); |
484 | 254 | } |
485 | | |
486 | | // Parse all the bytes of the string given this radix. |
487 | 5.40M | Result = 0; |
488 | 21.5M | while (!Str.empty()) { |
489 | 16.2M | unsigned CharVal; |
490 | 16.2M | if (Str[0] >= '0' && Str[0] <= '9') |
491 | 15.7M | CharVal = Str[0]-'0'; |
492 | 553k | else if (Str[0] >= 'a' && Str[0] <= 'z') |
493 | 504k | CharVal = Str[0]-'a'+10; |
494 | 48.5k | else if (Str[0] >= 'A' && Str[0] <= 'Z') |
495 | 48.5k | CharVal = Str[0]-'A'+10; |
496 | 0 | else |
497 | 0 | return true; |
498 | | |
499 | | // If the parsed value is larger than the integer radix, the string is |
500 | | // invalid. |
501 | 16.2M | if (CharVal >= Radix) |
502 | 152k | return true; |
503 | | |
504 | | // Add in this character. |
505 | 16.1M | if (IsPowerOf2Radix) { |
506 | 16.0M | Result <<= Log2Radix; |
507 | 16.0M | Result |= CharVal; |
508 | 16.0M | } else { |
509 | 18.2k | Result *= RadixAP; |
510 | 18.2k | CharAP = CharVal; |
511 | 18.2k | Result += CharAP; |
512 | 18.2k | } |
513 | | |
514 | 16.1M | Str = Str.substr(1); |
515 | 16.1M | } |
516 | | |
517 | 5.24M | return false; |
518 | 5.40M | } |
519 | | |
520 | | |
521 | | // Implementation of StringRef hashing. |
522 | 113k | hash_code llvm_ks::hash_value(StringRef S) { |
523 | 113k | return hash_combine_range(S.begin(), S.end()); |
524 | 113k | } |