Coverage Report

Created: 2025-12-12 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hermes/external/llvh/include/llvh/ADT/StringRef.h
Line
Count
Source
1
//===- StringRef.h - Constant String Reference Wrapper ----------*- C++ -*-===//
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
#ifndef LLVM_ADT_STRINGREF_H
10
#define LLVM_ADT_STRINGREF_H
11
12
#include "llvh/ADT/STLExtras.h"
13
#include "llvh/ADT/iterator_range.h"
14
#include "llvh/Support/Compiler.h"
15
#include <algorithm>
16
#include <cassert>
17
#include <cstddef>
18
#include <cstring>
19
#include <limits>
20
#include <string>
21
#include <type_traits>
22
#include <utility>
23
24
#pragma GCC diagnostic push
25
26
#ifdef HERMES_COMPILER_SUPPORTS_WSHORTEN_64_TO_32
27
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
28
#endif
29
30
namespace llvh {
31
32
  class APInt;
33
  class hash_code;
34
  template <typename T> class SmallVectorImpl;
35
  class StringRef;
36
37
  /// Helper functions for StringRef::getAsInteger.
38
  bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
39
                            unsigned long long &Result);
40
41
  bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
42
43
  bool consumeUnsignedInteger(StringRef &Str, unsigned Radix,
44
                              unsigned long long &Result);
45
  bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result);
46
47
  /// StringRef - Represent a constant reference to a string, i.e. a character
48
  /// array and a length, which need not be null terminated.
49
  ///
50
  /// This class does not own the string data, it is expected to be used in
51
  /// situations where the character data resides in some other buffer, whose
52
  /// lifetime extends past that of the StringRef. For this reason, it is not in
53
  /// general safe to store a StringRef.
54
  class StringRef {
55
  public:
56
    static const size_t npos = ~size_t(0);
57
58
    using iterator = const char *;
59
    using const_iterator = const char *;
60
    using size_type = size_t;
61
62
  private:
63
    /// The start of the string, in an external buffer.
64
    const char *Data = nullptr;
65
66
    /// The length of the string.
67
    size_t Length = 0;
68
69
    // Workaround memcmp issue with null pointers (undefined behavior)
70
    // by providing a specialized version
71
    LLVM_ATTRIBUTE_ALWAYS_INLINE
72
16.2M
    static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
73
16.2M
      if (Length == 0) { return 0; }
74
15.4M
      return ::memcmp(Lhs,Rhs,Length);
75
16.2M
    }
76
77
  public:
78
    /// @name Constructors
79
    /// @{
80
81
    /// Construct an empty string ref.
82
3.55k
    /*implicit*/ StringRef() = default;
83
84
    /// Disable conversion from nullptr.  This prevents things like
85
    /// if (S == nullptr)
86
    StringRef(std::nullptr_t) = delete;
87
88
    /// Construct a string ref from a cstring.
89
    LLVM_ATTRIBUTE_ALWAYS_INLINE
90
    /*implicit*/ StringRef(const char *Str)
91
3.61M
        : Data(Str), Length(Str ? ::strlen(Str) : 0) {}
92
93
    /// Construct a string ref from a pointer and length.
94
    LLVM_ATTRIBUTE_ALWAYS_INLINE
95
    /*implicit*/ constexpr StringRef(const char *data, size_t length)
96
329M
        : Data(data), Length(length) {}
97
98
    /// Construct a string ref from an std::string.
99
    LLVM_ATTRIBUTE_ALWAYS_INLINE
100
    /*implicit*/ StringRef(const std::string &Str)
101
45.5k
      : Data(Str.data()), Length(Str.length()) {}
102
103
0
    static StringRef withNullAsEmpty(const char *data) {
104
0
      return StringRef(data ? data : "");
105
0
    }
106
107
    /// @}
108
    /// @name Iterators
109
    /// @{
110
111
9.36M
    iterator begin() const { return Data; }
112
113
9.28M
    iterator end() const { return Data + Length; }
114
115
438
    const unsigned char *bytes_begin() const {
116
438
      return reinterpret_cast<const unsigned char *>(begin());
117
438
    }
118
438
    const unsigned char *bytes_end() const {
119
438
      return reinterpret_cast<const unsigned char *>(end());
120
438
    }
121
42
    iterator_range<const unsigned char *> bytes() const {
122
42
      return make_range(bytes_begin(), bytes_end());
123
42
    }
124
125
    /// @}
126
    /// @name String Operations
127
    /// @{
128
129
    /// data - Get a pointer to the start of the string (which may not be null
130
    /// terminated).
131
    LLVM_NODISCARD
132
    LLVM_ATTRIBUTE_ALWAYS_INLINE
133
200M
    const char *data() const { return Data; }
134
135
    /// empty - Check if the string is empty.
136
    LLVM_NODISCARD
137
    LLVM_ATTRIBUTE_ALWAYS_INLINE
138
834
    bool empty() const { return Length == 0; }
139
140
    /// size - Get the string size.
141
    LLVM_NODISCARD
142
    LLVM_ATTRIBUTE_ALWAYS_INLINE
143
410k
    size_t size() const { return Length; }
144
145
    /// front - Get the first character in the string.
146
    LLVM_NODISCARD
147
0
    char front() const {
148
0
      assert(!empty());
149
0
      return Data[0];
150
0
    }
151
152
    /// back - Get the last character in the string.
153
    LLVM_NODISCARD
154
0
    char back() const {
155
0
      assert(!empty());
156
0
      return Data[Length-1];
157
0
    }
158
159
    // copy - Allocate copy in Allocator and return StringRef to it.
160
    template <typename Allocator>
161
    LLVM_NODISCARD StringRef copy(Allocator &A) const {
162
      // Don't request a length 0 copy from the allocator.
163
      if (empty())
164
        return StringRef();
165
      char *S = A.template Allocate<char>(Length);
166
      std::copy(begin(), end(), S);
167
      return StringRef(S, Length);
168
    }
169
170
    /// equals - Check for string equality, this is more efficient than
171
    /// compare() when the relative ordering of inequal strings isn't needed.
172
    LLVM_NODISCARD
173
    LLVM_ATTRIBUTE_ALWAYS_INLINE
174
192M
    bool equals(StringRef RHS) const {
175
192M
      return (Length == RHS.Length &&
176
16.1M
              compareMemory(Data, RHS.Data, RHS.Length) == 0);
177
192M
    }
178
179
    /// equals_lower - Check for string equality, ignoring case.
180
    LLVM_NODISCARD
181
0
    bool equals_lower(StringRef RHS) const {
182
0
      return Length == RHS.Length && compare_lower(RHS) == 0;
183
0
    }
184
185
    /// compare - Compare two strings; the result is -1, 0, or 1 if this string
186
    /// is lexicographically less than, equal to, or greater than the \p RHS.
187
    LLVM_NODISCARD
188
    LLVM_ATTRIBUTE_ALWAYS_INLINE
189
90.8k
    int compare(StringRef RHS) const {
190
      // Check the prefix for a mismatch.
191
90.8k
      if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length)))
192
85.2k
        return Res < 0 ? -1 : 1;
193
194
      // Otherwise the prefixes match, so we only need to check the lengths.
195
5.60k
      if (Length == RHS.Length)
196
0
        return 0;
197
5.60k
      return Length < RHS.Length ? -1 : 1;
198
5.60k
    }
199
200
    /// compare_lower - Compare two strings, ignoring case.
201
    LLVM_NODISCARD
202
    int compare_lower(StringRef RHS) const;
203
204
    /// compare_numeric - Compare two strings, treating sequences of digits as
205
    /// numbers.
206
    LLVM_NODISCARD
207
    int compare_numeric(StringRef RHS) const;
208
209
    /// Determine the edit distance between this string and another
210
    /// string.
211
    ///
212
    /// \param Other the string to compare this string against.
213
    ///
214
    /// \param AllowReplacements whether to allow character
215
    /// replacements (change one character into another) as a single
216
    /// operation, rather than as two operations (an insertion and a
217
    /// removal).
218
    ///
219
    /// \param MaxEditDistance If non-zero, the maximum edit distance that
220
    /// this routine is allowed to compute. If the edit distance will exceed
221
    /// that maximum, returns \c MaxEditDistance+1.
222
    ///
223
    /// \returns the minimum number of character insertions, removals,
224
    /// or (if \p AllowReplacements is \c true) replacements needed to
225
    /// transform one of the given strings into the other. If zero,
226
    /// the strings are identical.
227
    LLVM_NODISCARD
228
    unsigned edit_distance(StringRef Other, bool AllowReplacements = true,
229
                           unsigned MaxEditDistance = 0) const;
230
231
    /// str - Get the contents as an std::string.
232
    LLVM_NODISCARD
233
6.01k
    std::string str() const {
234
6.01k
      if (!Data) return std::string();
235
5.90k
      return std::string(Data, Length);
236
6.01k
    }
237
238
    /// @}
239
    /// @name Operator Overloads
240
    /// @{
241
242
    LLVM_NODISCARD
243
42.2M
    char operator[](size_t Index) const {
244
42.2M
      assert(Index < Length && "Invalid index!");
245
42.2M
      return Data[Index];
246
42.2M
    }
247
248
    /// Disallow accidental assignment from a temporary std::string.
249
    ///
250
    /// The declaration here is extra complicated so that `stringRef = {}`
251
    /// and `stringRef = "abc"` continue to select the move assignment operator.
252
    template <typename T>
253
    typename std::enable_if<std::is_same<T, std::string>::value,
254
                            StringRef>::type &
255
    operator=(T &&Str) = delete;
256
257
    /// @}
258
    /// @name Type Conversions
259
    /// @{
260
261
5.52k
    operator std::string() const {
262
5.52k
      return str();
263
5.52k
    }
264
265
    /// @}
266
    /// @name String Predicates
267
    /// @{
268
269
    /// Check if this string starts with the given \p Prefix.
270
    LLVM_NODISCARD
271
    LLVM_ATTRIBUTE_ALWAYS_INLINE
272
247
    bool startswith(StringRef Prefix) const {
273
247
      return Length >= Prefix.Length &&
274
247
             compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
275
247
    }
276
277
    /// Check if this string starts with the given \p Prefix, ignoring case.
278
    LLVM_NODISCARD
279
    bool startswith_lower(StringRef Prefix) const;
280
281
    /// Check if this string ends with the given \p Suffix.
282
    LLVM_NODISCARD
283
    LLVM_ATTRIBUTE_ALWAYS_INLINE
284
0
    bool endswith(StringRef Suffix) const {
285
0
      return Length >= Suffix.Length &&
286
0
        compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
287
0
    }
288
289
    /// Check if this string ends with the given \p Suffix, ignoring case.
290
    LLVM_NODISCARD
291
    bool endswith_lower(StringRef Suffix) const;
292
293
    /// @}
294
    /// @name String Searching
295
    /// @{
296
297
    /// Search for the first character \p C in the string.
298
    ///
299
    /// \returns The index of the first occurrence of \p C, or npos if not
300
    /// found.
301
    LLVM_NODISCARD
302
    LLVM_ATTRIBUTE_ALWAYS_INLINE
303
0
    size_t find(char C, size_t From = 0) const {
304
0
      size_t FindBegin = std::min(From, Length);
305
0
      if (FindBegin < Length) { // Avoid calling memchr with nullptr.
306
        // Just forward to memchr, which is faster than a hand-rolled loop.
307
0
        if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin))
308
0
          return static_cast<const char *>(P) - Data;
309
0
      }
310
0
      return npos;
311
0
    }
312
313
    /// Search for the first character \p C in the string, ignoring case.
314
    ///
315
    /// \returns The index of the first occurrence of \p C, or npos if not
316
    /// found.
317
    LLVM_NODISCARD
318
    size_t find_lower(char C, size_t From = 0) const;
319
320
    /// Search for the first character satisfying the predicate \p F
321
    ///
322
    /// \returns The index of the first character satisfying \p F starting from
323
    /// \p From, or npos if not found.
324
    LLVM_NODISCARD
325
    LLVM_ATTRIBUTE_ALWAYS_INLINE
326
0
    size_t find_if(function_ref<bool(char)> F, size_t From = 0) const {
327
0
      StringRef S = drop_front(From);
328
0
      while (!S.empty()) {
329
0
        if (F(S.front()))
330
0
          return size() - S.size();
331
0
        S = S.drop_front();
332
0
      }
333
0
      return npos;
334
0
    }
335
336
    /// Search for the first character not satisfying the predicate \p F
337
    ///
338
    /// \returns The index of the first character not satisfying \p F starting
339
    /// from \p From, or npos if not found.
340
    LLVM_NODISCARD
341
    LLVM_ATTRIBUTE_ALWAYS_INLINE
342
0
    size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const {
343
0
      return find_if([F](char c) { return !F(c); }, From);
344
0
    }
345
346
    /// Search for the first string \p Str in the string.
347
    ///
348
    /// \returns The index of the first occurrence of \p Str, or npos if not
349
    /// found.
350
    LLVM_NODISCARD
351
    size_t find(StringRef Str, size_t From = 0) const;
352
353
    /// Search for the first string \p Str in the string, ignoring case.
354
    ///
355
    /// \returns The index of the first occurrence of \p Str, or npos if not
356
    /// found.
357
    LLVM_NODISCARD
358
    size_t find_lower(StringRef Str, size_t From = 0) const;
359
360
    /// Search for the last character \p C in the string.
361
    ///
362
    /// \returns The index of the last occurrence of \p C, or npos if not
363
    /// found.
364
    LLVM_NODISCARD
365
0
    size_t rfind(char C, size_t From = npos) const {
366
0
      From = std::min(From, Length);
367
0
      size_t i = From;
368
0
      while (i != 0) {
369
0
        --i;
370
0
        if (Data[i] == C)
371
0
          return i;
372
0
      }
373
0
      return npos;
374
0
    }
375
376
    /// Search for the last character \p C in the string, ignoring case.
377
    ///
378
    /// \returns The index of the last occurrence of \p C, or npos if not
379
    /// found.
380
    LLVM_NODISCARD
381
    size_t rfind_lower(char C, size_t From = npos) const;
382
383
    /// Search for the last string \p Str in the string.
384
    ///
385
    /// \returns The index of the last occurrence of \p Str, or npos if not
386
    /// found.
387
    LLVM_NODISCARD
388
    size_t rfind(StringRef Str) const;
389
390
    /// Search for the last string \p Str in the string, ignoring case.
391
    ///
392
    /// \returns The index of the last occurrence of \p Str, or npos if not
393
    /// found.
394
    LLVM_NODISCARD
395
    size_t rfind_lower(StringRef Str) const;
396
397
    /// Find the first character in the string that is \p C, or npos if not
398
    /// found. Same as find.
399
    LLVM_NODISCARD
400
0
    size_t find_first_of(char C, size_t From = 0) const {
401
0
      return find(C, From);
402
0
    }
403
404
    /// Find the first character in the string that is in \p Chars, or npos if
405
    /// not found.
406
    ///
407
    /// Complexity: O(size() + Chars.size())
408
    LLVM_NODISCARD
409
    size_t find_first_of(StringRef Chars, size_t From = 0) const;
410
411
    /// Find the first character in the string that is not \p C or npos if not
412
    /// found.
413
    LLVM_NODISCARD
414
    size_t find_first_not_of(char C, size_t From = 0) const;
415
416
    /// Find the first character in the string that is not in the string
417
    /// \p Chars, or npos if not found.
418
    ///
419
    /// Complexity: O(size() + Chars.size())
420
    LLVM_NODISCARD
421
    size_t find_first_not_of(StringRef Chars, size_t From = 0) const;
422
423
    /// Find the last character in the string that is \p C, or npos if not
424
    /// found.
425
    LLVM_NODISCARD
426
0
    size_t find_last_of(char C, size_t From = npos) const {
427
0
      return rfind(C, From);
428
0
    }
429
430
    /// Find the last character in the string that is in \p C, or npos if not
431
    /// found.
432
    ///
433
    /// Complexity: O(size() + Chars.size())
434
    LLVM_NODISCARD
435
    size_t find_last_of(StringRef Chars, size_t From = npos) const;
436
437
    /// Find the last character in the string that is not \p C, or npos if not
438
    /// found.
439
    LLVM_NODISCARD
440
    size_t find_last_not_of(char C, size_t From = npos) const;
441
442
    /// Find the last character in the string that is not in \p Chars, or
443
    /// npos if not found.
444
    ///
445
    /// Complexity: O(size() + Chars.size())
446
    LLVM_NODISCARD
447
    size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
448
449
    /// Return true if the given string is a substring of *this, and false
450
    /// otherwise.
451
    LLVM_NODISCARD
452
    LLVM_ATTRIBUTE_ALWAYS_INLINE
453
0
    bool contains(StringRef Other) const { return find(Other) != npos; }
454
455
    /// Return true if the given character is contained in *this, and false
456
    /// otherwise.
457
    LLVM_NODISCARD
458
    LLVM_ATTRIBUTE_ALWAYS_INLINE
459
0
    bool contains(char C) const { return find_first_of(C) != npos; }
460
461
    /// Return true if the given string is a substring of *this, and false
462
    /// otherwise.
463
    LLVM_NODISCARD
464
    LLVM_ATTRIBUTE_ALWAYS_INLINE
465
0
    bool contains_lower(StringRef Other) const {
466
0
      return find_lower(Other) != npos;
467
0
    }
468
469
    /// Return true if the given character is contained in *this, and false
470
    /// otherwise.
471
    LLVM_NODISCARD
472
    LLVM_ATTRIBUTE_ALWAYS_INLINE
473
0
    bool contains_lower(char C) const { return find_lower(C) != npos; }
474
475
    /// @}
476
    /// @name Helpful Algorithms
477
    /// @{
478
479
    /// Return the number of occurrences of \p C in the string.
480
    LLVM_NODISCARD
481
0
    size_t count(char C) const {
482
0
      size_t Count = 0;
483
0
      for (size_t i = 0, e = Length; i != e; ++i)
484
0
        if (Data[i] == C)
485
0
          ++Count;
486
0
      return Count;
487
0
    }
488
489
    /// Return the number of non-overlapped occurrences of \p Str in
490
    /// the string.
491
    size_t count(StringRef Str) const;
492
493
    /// Parse the current string as an integer of the specified radix.  If
494
    /// \p Radix is specified as zero, this does radix autosensing using
495
    /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
496
    ///
497
    /// If the string is invalid or if only a subset of the string is valid,
498
    /// this returns true to signify the error.  The string is considered
499
    /// erroneous if empty or if it overflows T.
500
    template <typename T>
501
    typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
502
0
    getAsInteger(unsigned Radix, T &Result) const {
503
0
      long long LLVal;
504
0
      if (getAsSignedInteger(*this, Radix, LLVal) ||
505
0
            static_cast<T>(LLVal) != LLVal)
506
0
        return true;
507
0
      Result = LLVal;
508
0
      return false;
509
0
    }
510
511
    template <typename T>
512
    typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
513
0
    getAsInteger(unsigned Radix, T &Result) const {
514
0
      unsigned long long ULLVal;
515
      // The additional cast to unsigned long long is required to avoid the
516
      // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
517
      // 'unsigned __int64' when instantiating getAsInteger with T = bool.
518
0
      if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
519
0
          static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
520
0
        return true;
521
0
      Result = ULLVal;
522
0
      return false;
523
0
    }
Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerImEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_
Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerIjEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_
Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerIyEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_
524
525
    /// Parse the current string as an integer of the specified radix.  If
526
    /// \p Radix is specified as zero, this does radix autosensing using
527
    /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
528
    ///
529
    /// If the string does not begin with a number of the specified radix,
530
    /// this returns true to signify the error. The string is considered
531
    /// erroneous if empty or if it overflows T.
532
    /// The portion of the string representing the discovered numeric value
533
    /// is removed from the beginning of the string.
534
    template <typename T>
535
    typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
536
    consumeInteger(unsigned Radix, T &Result) {
537
      long long LLVal;
538
      if (consumeSignedInteger(*this, Radix, LLVal) ||
539
          static_cast<long long>(static_cast<T>(LLVal)) != LLVal)
540
        return true;
541
      Result = LLVal;
542
      return false;
543
    }
544
545
    template <typename T>
546
    typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
547
0
    consumeInteger(unsigned Radix, T &Result) {
548
0
      unsigned long long ULLVal;
549
0
      if (consumeUnsignedInteger(*this, Radix, ULLVal) ||
550
0
          static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
551
0
        return true;
552
0
      Result = ULLVal;
553
0
      return false;
554
0
    }
555
556
    /// Parse the current string as an integer of the specified \p Radix, or of
557
    /// an autosensed radix if the \p Radix given is 0.  The current value in
558
    /// \p Result is discarded, and the storage is changed to be wide enough to
559
    /// store the parsed integer.
560
    ///
561
    /// \returns true if the string does not solely consist of a valid
562
    /// non-empty number in the appropriate base.
563
    ///
564
    /// APInt::fromString is superficially similar but assumes the
565
    /// string is well-formed in the given radix.
566
    bool getAsInteger(unsigned Radix, APInt &Result) const;
567
568
    /// Parse the current string as an IEEE double-precision floating
569
    /// point value.  The string must be a well-formed double.
570
    ///
571
    /// If \p AllowInexact is false, the function will fail if the string
572
    /// cannot be represented exactly.  Otherwise, the function only fails
573
    /// in case of an overflow or underflow.
574
    bool getAsDouble(double &Result, bool AllowInexact = true) const;
575
576
    /// @}
577
    /// @name String Operations
578
    /// @{
579
580
    // Convert the given ASCII string to lowercase.
581
    LLVM_NODISCARD
582
    std::string lower() const;
583
584
    /// Convert the given ASCII string to uppercase.
585
    LLVM_NODISCARD
586
    std::string upper() const;
587
588
    /// @}
589
    /// @name Substring Operations
590
    /// @{
591
592
    /// Return a reference to the substring from [Start, Start + N).
593
    ///
594
    /// \param Start The index of the starting character in the substring; if
595
    /// the index is npos or greater than the length of the string then the
596
    /// empty substring will be returned.
597
    ///
598
    /// \param N The number of characters to included in the substring. If N
599
    /// exceeds the number of characters remaining in the string, the string
600
    /// suffix (starting with \p Start) will be returned.
601
    LLVM_NODISCARD
602
    LLVM_ATTRIBUTE_ALWAYS_INLINE
603
46
    StringRef substr(size_t Start, size_t N = npos) const {
604
46
      Start = std::min(Start, Length);
605
46
      return StringRef(Data + Start, std::min(N, Length - Start));
606
46
    }
607
608
    /// Return a StringRef equal to 'this' but with only the first \p N
609
    /// elements remaining.  If \p N is greater than the length of the
610
    /// string, the entire string is returned.
611
    LLVM_NODISCARD
612
    LLVM_ATTRIBUTE_ALWAYS_INLINE
613
0
    StringRef take_front(size_t N = 1) const {
614
0
      if (N >= size())
615
0
        return *this;
616
0
      return drop_back(size() - N);
617
0
    }
618
619
    /// Return a StringRef equal to 'this' but with only the last \p N
620
    /// elements remaining.  If \p N is greater than the length of the
621
    /// string, the entire string is returned.
622
    LLVM_NODISCARD
623
    LLVM_ATTRIBUTE_ALWAYS_INLINE
624
0
    StringRef take_back(size_t N = 1) const {
625
0
      if (N >= size())
626
0
        return *this;
627
0
      return drop_front(size() - N);
628
0
    }
629
630
    /// Return the longest prefix of 'this' such that every character
631
    /// in the prefix satisfies the given predicate.
632
    LLVM_NODISCARD
633
    LLVM_ATTRIBUTE_ALWAYS_INLINE
634
0
    StringRef take_while(function_ref<bool(char)> F) const {
635
0
      return substr(0, find_if_not(F));
636
0
    }
637
638
    /// Return the longest prefix of 'this' such that no character in
639
    /// the prefix satisfies the given predicate.
640
    LLVM_NODISCARD
641
    LLVM_ATTRIBUTE_ALWAYS_INLINE
642
0
    StringRef take_until(function_ref<bool(char)> F) const {
643
0
      return substr(0, find_if(F));
644
0
    }
645
646
    /// Return a StringRef equal to 'this' but with the first \p N elements
647
    /// dropped.
648
    LLVM_NODISCARD
649
    LLVM_ATTRIBUTE_ALWAYS_INLINE
650
46
    StringRef drop_front(size_t N = 1) const {
651
46
      assert(size() >= N && "Dropping more elements than exist");
652
46
      return substr(N);
653
46
    }
654
655
    /// Return a StringRef equal to 'this' but with the last \p N elements
656
    /// dropped.
657
    LLVM_NODISCARD
658
    LLVM_ATTRIBUTE_ALWAYS_INLINE
659
0
    StringRef drop_back(size_t N = 1) const {
660
0
      assert(size() >= N && "Dropping more elements than exist");
661
0
      return substr(0, size()-N);
662
0
    }
663
664
    /// Return a StringRef equal to 'this', but with all characters satisfying
665
    /// the given predicate dropped from the beginning of the string.
666
    LLVM_NODISCARD
667
    LLVM_ATTRIBUTE_ALWAYS_INLINE
668
0
    StringRef drop_while(function_ref<bool(char)> F) const {
669
0
      return substr(find_if_not(F));
670
0
    }
671
672
    /// Return a StringRef equal to 'this', but with all characters not
673
    /// satisfying the given predicate dropped from the beginning of the string.
674
    LLVM_NODISCARD
675
    LLVM_ATTRIBUTE_ALWAYS_INLINE
676
0
    StringRef drop_until(function_ref<bool(char)> F) const {
677
0
      return substr(find_if(F));
678
0
    }
679
680
    /// Returns true if this StringRef has the given prefix and removes that
681
    /// prefix.
682
    LLVM_ATTRIBUTE_ALWAYS_INLINE
683
247
    bool consume_front(StringRef Prefix) {
684
247
      if (!startswith(Prefix))
685
201
        return false;
686
687
46
      *this = drop_front(Prefix.size());
688
46
      return true;
689
247
    }
690
691
    /// Returns true if this StringRef has the given suffix and removes that
692
    /// suffix.
693
    LLVM_ATTRIBUTE_ALWAYS_INLINE
694
0
    bool consume_back(StringRef Suffix) {
695
0
      if (!endswith(Suffix))
696
0
        return false;
697
698
0
      *this = drop_back(Suffix.size());
699
0
      return true;
700
0
    }
701
702
    /// Return a reference to the substring from [Start, End).
703
    ///
704
    /// \param Start The index of the starting character in the substring; if
705
    /// the index is npos or greater than the length of the string then the
706
    /// empty substring will be returned.
707
    ///
708
    /// \param End The index following the last character to include in the
709
    /// substring. If this is npos or exceeds the number of characters
710
    /// remaining in the string, the string suffix (starting with \p Start)
711
    /// will be returned. If this is less than \p Start, an empty string will
712
    /// be returned.
713
    LLVM_NODISCARD
714
    LLVM_ATTRIBUTE_ALWAYS_INLINE
715
0
    StringRef slice(size_t Start, size_t End) const {
716
0
      Start = std::min(Start, Length);
717
0
      End = std::min(std::max(Start, End), Length);
718
0
      return StringRef(Data + Start, End - Start);
719
0
    }
720
721
    /// Split into two substrings around the first occurrence of a separator
722
    /// character.
723
    ///
724
    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
725
    /// such that (*this == LHS + Separator + RHS) is true and RHS is
726
    /// maximal. If \p Separator is not in the string, then the result is a
727
    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
728
    ///
729
    /// \param Separator The character to split on.
730
    /// \returns The split substrings.
731
    LLVM_NODISCARD
732
0
    std::pair<StringRef, StringRef> split(char Separator) const {
733
0
      return split(StringRef(&Separator, 1));
734
0
    }
735
736
    /// Split into two substrings around the first occurrence of a separator
737
    /// string.
738
    ///
739
    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
740
    /// such that (*this == LHS + Separator + RHS) is true and RHS is
741
    /// maximal. If \p Separator is not in the string, then the result is a
742
    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
743
    ///
744
    /// \param Separator - The string to split on.
745
    /// \return - The split substrings.
746
    LLVM_NODISCARD
747
0
    std::pair<StringRef, StringRef> split(StringRef Separator) const {
748
0
      size_t Idx = find(Separator);
749
0
      if (Idx == npos)
750
0
        return std::make_pair(*this, StringRef());
751
0
      return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
752
0
    }
753
754
    /// Split into two substrings around the last occurrence of a separator
755
    /// string.
756
    ///
757
    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
758
    /// such that (*this == LHS + Separator + RHS) is true and RHS is
759
    /// minimal. If \p Separator is not in the string, then the result is a
760
    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
761
    ///
762
    /// \param Separator - The string to split on.
763
    /// \return - The split substrings.
764
    LLVM_NODISCARD
765
0
    std::pair<StringRef, StringRef> rsplit(StringRef Separator) const {
766
0
      size_t Idx = rfind(Separator);
767
0
      if (Idx == npos)
768
0
        return std::make_pair(*this, StringRef());
769
0
      return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
770
0
    }
771
772
    /// Split into substrings around the occurrences of a separator string.
773
    ///
774
    /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
775
    /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
776
    /// elements are added to A.
777
    /// If \p KeepEmpty is false, empty strings are not added to \p A. They
778
    /// still count when considering \p MaxSplit
779
    /// An useful invariant is that
780
    /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
781
    ///
782
    /// \param A - Where to put the substrings.
783
    /// \param Separator - The string to split on.
784
    /// \param MaxSplit - The maximum number of times the string is split.
785
    /// \param KeepEmpty - True if empty substring should be added.
786
    void split(SmallVectorImpl<StringRef> &A,
787
               StringRef Separator, int MaxSplit = -1,
788
               bool KeepEmpty = true) const;
789
790
    /// Split into substrings around the occurrences of a separator character.
791
    ///
792
    /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
793
    /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
794
    /// elements are added to A.
795
    /// If \p KeepEmpty is false, empty strings are not added to \p A. They
796
    /// still count when considering \p MaxSplit
797
    /// An useful invariant is that
798
    /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
799
    ///
800
    /// \param A - Where to put the substrings.
801
    /// \param Separator - The string to split on.
802
    /// \param MaxSplit - The maximum number of times the string is split.
803
    /// \param KeepEmpty - True if empty substring should be added.
804
    void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
805
               bool KeepEmpty = true) const;
806
807
    /// Split into two substrings around the last occurrence of a separator
808
    /// character.
809
    ///
810
    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
811
    /// such that (*this == LHS + Separator + RHS) is true and RHS is
812
    /// minimal. If \p Separator is not in the string, then the result is a
813
    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
814
    ///
815
    /// \param Separator - The character to split on.
816
    /// \return - The split substrings.
817
    LLVM_NODISCARD
818
0
    std::pair<StringRef, StringRef> rsplit(char Separator) const {
819
0
      return rsplit(StringRef(&Separator, 1));
820
0
    }
821
822
    /// Return string with consecutive \p Char characters starting from the
823
    /// the left removed.
824
    LLVM_NODISCARD
825
0
    StringRef ltrim(char Char) const {
826
0
      return drop_front(std::min(Length, find_first_not_of(Char)));
827
0
    }
828
829
    /// Return string with consecutive characters in \p Chars starting from
830
    /// the left removed.
831
    LLVM_NODISCARD
832
0
    StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
833
0
      return drop_front(std::min(Length, find_first_not_of(Chars)));
834
0
    }
835
836
    /// Return string with consecutive \p Char characters starting from the
837
    /// right removed.
838
    LLVM_NODISCARD
839
0
    StringRef rtrim(char Char) const {
840
0
      return drop_back(Length - std::min(Length, find_last_not_of(Char) + 1));
841
0
    }
842
843
    /// Return string with consecutive characters in \p Chars starting from
844
    /// the right removed.
845
    LLVM_NODISCARD
846
0
    StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
847
0
      return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
848
0
    }
849
850
    /// Return string with consecutive \p Char characters starting from the
851
    /// left and right removed.
852
    LLVM_NODISCARD
853
0
    StringRef trim(char Char) const {
854
0
      return ltrim(Char).rtrim(Char);
855
0
    }
856
857
    /// Return string with consecutive characters in \p Chars starting from
858
    /// the left and right removed.
859
    LLVM_NODISCARD
860
0
    StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
861
0
      return ltrim(Chars).rtrim(Chars);
862
0
    }
863
864
    /// @}
865
  };
866
867
  /// A wrapper around a string literal that serves as a proxy for constructing
868
  /// global tables of StringRefs with the length computed at compile time.
869
  /// In order to avoid the invocation of a global constructor, StringLiteral
870
  /// should *only* be used in a constexpr context, as such:
871
  ///
872
  /// constexpr StringLiteral S("test");
873
  ///
874
  class StringLiteral : public StringRef {
875
  private:
876
0
    constexpr StringLiteral(const char *Str, size_t N) : StringRef(Str, N) {
877
0
    }
878
879
  public:
880
    template <size_t N>
881
    constexpr StringLiteral(const char (&Str)[N])
882
#if defined(__clang__) && __has_attribute(enable_if)
883
#pragma clang diagnostic push
884
#pragma clang diagnostic ignored "-Wgcc-compat"
885
        __attribute((enable_if(__builtin_strlen(Str) == N - 1,
886
                               "invalid string literal")))
887
#pragma clang diagnostic pop
888
#endif
889
206M
        : StringRef(Str, N - 1) {
890
206M
    }
_ZN4llvh13StringLiteralC2ILm4EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm4ELi1EEERAT__Kc
Line
Count
Source
889
18.7M
        : StringRef(Str, N - 1) {
890
18.7M
    }
_ZN4llvh13StringLiteralC2ILm3EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm3ELi1EEERAT__Kc
Line
Count
Source
889
14.0M
        : StringRef(Str, N - 1) {
890
14.0M
    }
_ZN4llvh13StringLiteralC2ILm6EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm6ELi1EEERAT__Kc
Line
Count
Source
889
42.1M
        : StringRef(Str, N - 1) {
890
42.1M
    }
_ZN4llvh13StringLiteralC2ILm7EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm7ELi1EEERAT__Kc
Line
Count
Source
889
37.4M
        : StringRef(Str, N - 1) {
890
37.4M
    }
_ZN4llvh13StringLiteralC2ILm8EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm8ELi1EEERAT__Kc
Line
Count
Source
889
23.4M
        : StringRef(Str, N - 1) {
890
23.4M
    }
_ZN4llvh13StringLiteralC2ILm9EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm9ELi1EEERAT__Kc
Line
Count
Source
889
14.0M
        : StringRef(Str, N - 1) {
890
14.0M
    }
_ZN4llvh13StringLiteralC2ILm5EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm5ELi1EEERAT__Kc
Line
Count
Source
889
37.4M
        : StringRef(Str, N - 1) {
890
37.4M
    }
_ZN4llvh13StringLiteralC2ILm11EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm11ELi1EEERAT__Kc
Line
Count
Source
889
9.36M
        : StringRef(Str, N - 1) {
890
9.36M
    }
_ZN4llvh13StringLiteralC2ILm18EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm18ELi1EEERAT__Kc
Line
Count
Source
889
23
        : StringRef(Str, N - 1) {
890
23
    }
_ZN4llvh13StringLiteralC2ILm10EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm10ELi1EEERAT__Kc
Line
Count
Source
889
9.36M
        : StringRef(Str, N - 1) {
890
9.36M
    }
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm15EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm15ELi1EEERAT__Kc
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm12EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm12ELi1EEERAT__Kc
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm13EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm13ELi1EEERAT__Kc
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm14EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm14ELi1EEERAT__Kc
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm1EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm1ELi1EEERAT__Kc
891
892
    // Explicit construction for strings like "foo\0bar".
893
    template <size_t N>
894
    static constexpr StringLiteral withInnerNUL(const char (&Str)[N]) {
895
      return StringLiteral(Str, N - 1);
896
    }
897
  };
898
899
  /// @name StringRef Comparison Operators
900
  /// @{
901
902
  LLVM_ATTRIBUTE_ALWAYS_INLINE
903
192M
  inline bool operator==(StringRef LHS, StringRef RHS) {
904
192M
    return LHS.equals(RHS);
905
192M
  }
906
907
  LLVM_ATTRIBUTE_ALWAYS_INLINE
908
0
  inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); }
909
910
90.8k
  inline bool operator<(StringRef LHS, StringRef RHS) {
911
90.8k
    return LHS.compare(RHS) == -1;
912
90.8k
  }
913
914
0
  inline bool operator<=(StringRef LHS, StringRef RHS) {
915
0
    return LHS.compare(RHS) != 1;
916
0
  }
917
918
0
  inline bool operator>(StringRef LHS, StringRef RHS) {
919
0
    return LHS.compare(RHS) == 1;
920
0
  }
921
922
0
  inline bool operator>=(StringRef LHS, StringRef RHS) {
923
0
    return LHS.compare(RHS) != -1;
924
0
  }
925
926
0
  inline std::string &operator+=(std::string &buffer, StringRef string) {
927
0
    return buffer.append(string.data(), string.size());
928
0
  }
929
930
  /// @}
931
932
  /// Compute a hash_code for a StringRef.
933
  LLVM_NODISCARD
934
  hash_code hash_value(StringRef S);
935
936
  // StringRefs can be treated like a POD type.
937
  template <typename T> struct isPodLike;
938
  template <> struct isPodLike<StringRef> { static const bool value = true; };
939
940
} // end namespace llvh
941
942
#pragma GCC diagnostic pop
943
#endif // LLVM_ADT_STRINGREF_H