LLVM 20.0.0git
StringTable.h
Go to the documentation of this file.
1//===- StringTable.h - Table of strings tracked by offset ----------C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_ADT_STRING_TABLE_H
10#define LLVM_ADT_STRING_TABLE_H
11
12#include "llvm/ADT/StringRef.h"
13#include "llvm/ADT/iterator.h"
14#include <iterator>
15#include <limits>
16
17namespace llvm {
18
19/// A table of densely packed, null-terminated strings indexed by offset.
20///
21/// This table abstracts a densely concatenated list of null-terminated strings,
22/// each of which can be referenced using an offset into the table.
23///
24/// This requires and ensures that the string at offset 0 is also the empty
25/// string. This helps allow zero-initialized offsets form empty strings and
26/// avoids non-zero initialization when using a string literal pointer would
27/// allow a null pointer.
28///
29/// The primary use case is having a single global string literal for the table
30/// contents, and offsets into it in other global data structures to avoid
31/// dynamic relocations of individual string literal pointers in those global
32/// data structures.
34 StringRef Table;
35
36public:
37 // An offset into one of these packed string tables, used to select a string
38 // within the table.
39 //
40 // Typically these are created by TableGen or other code generator from
41 // computed offsets, and it just wraps that integer into a type until it is
42 // used with the relevant table.
43 //
44 // We also ensure that the empty string is at offset zero and default
45 // constructing this class gives you an offset of zero. This makes default
46 // constructing this type work similarly (after indexing the table) to default
47 // constructing a `StringRef`.
48 class Offset {
49 // Note that we ensure the empty string is at offset zero.
50 unsigned Value = 0;
51
52 public:
53 constexpr Offset() = default;
54 constexpr Offset(unsigned Value) : Value(Value) {}
55
56 friend constexpr bool operator==(const Offset &LHS, const Offset &RHS) {
57 return LHS.Value == RHS.Value;
58 }
59
60 friend constexpr bool operator!=(const Offset &LHS, const Offset &RHS) {
61 return LHS.Value != RHS.Value;
62 }
63
64 constexpr unsigned value() const { return Value; }
65 };
66
67 // We directly handle string literals with a templated converting constructor
68 // because we *don't* want to do `strlen` on them -- we fully expect null
69 // bytes in this input. This is somewhat the opposite of how `StringLiteral`
70 // works.
71 template <size_t N>
72 constexpr StringTable(const char (&RawTable)[N]) : Table(RawTable, N) {
73 static_assert(N <= std::numeric_limits<unsigned>::max(),
74 "We only support table sizes that can be indexed by an "
75 "`unsigned` offset.");
76
77 // Note that we can only use `empty`, `data`, and `size` in these asserts to
78 // support `constexpr`.
79 assert(!Table.empty() && "Requires at least a valid empty string.");
80 assert(Table.data()[0] == '\0' && "Offset zero must be the empty string.");
81 // Ensure that `strlen` from any offset cannot overflow the end of the table
82 // by insisting on a null byte at the end. We also insist on the last string
83 // within the table being *separately* null terminated. This structure is
84 // used to enable predictable iteration over all the strings when needed.
85 assert(Table.data()[Table.size() - 1] == '\0' &&
86 "Last byte must be a null byte.");
87 assert(Table.data()[Table.size() - 2] == '\0' &&
88 "Next-to-last byte must be a null byte.");
89 }
90
91 // Get a string from the table starting with the provided offset. The returned
92 // `StringRef` is in fact null terminated, and so can be converted safely to a
93 // C-string if necessary for a system API.
94 constexpr StringRef operator[](Offset O) const {
95 assert(O.value() < Table.size() && "Out of bounds offset!");
96 return Table.data() + O.value();
97 }
98
99 /// Returns the byte size of the table.
100 constexpr size_t size() const { return Table.size(); }
101
103 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
104 const StringRef> {
105 friend StringTable;
106
107 const StringTable *Table;
108 Offset O;
109
110 // A cache of one value to allow `*` to return a reference.
111 mutable StringRef S;
112
113 explicit constexpr Iterator(const StringTable &Table, Offset O)
114 : Table(&Table), O(O) {}
115
116 public:
117 constexpr Iterator(const Iterator &RHS) = default;
118 constexpr Iterator(Iterator &&RHS) = default;
119
120 bool operator==(const Iterator &RHS) const {
121 assert(Table == RHS.Table && "Compared iterators for unrelated tables!");
122 return O == RHS.O;
123 }
124
125 const StringRef &operator*() const {
126 S = (*Table)[O];
127 return S;
128 }
129
131 O = O.value() + (*Table)[O].size() + 1;
132 return *this;
133 }
134 };
135
136 constexpr Iterator begin() const { return Iterator(*this, 0); }
137 constexpr Iterator end() const { return Iterator(*this, size() - 1); }
138};
139
140} // namespace llvm
141
142#endif // LLVM_ADT_STRING_TABLE_H
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Value * LHS
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:144
bool operator==(const Iterator &RHS) const
Definition: StringTable.h:120
const StringRef & operator*() const
Definition: StringTable.h:125
constexpr Iterator(Iterator &&RHS)=default
constexpr Iterator(const Iterator &RHS)=default
constexpr Offset(unsigned Value)
Definition: StringTable.h:54
constexpr unsigned value() const
Definition: StringTable.h:64
friend constexpr bool operator==(const Offset &LHS, const Offset &RHS)
Definition: StringTable.h:56
friend constexpr bool operator!=(const Offset &LHS, const Offset &RHS)
Definition: StringTable.h:60
constexpr Offset()=default
A table of densely packed, null-terminated strings indexed by offset.
Definition: StringTable.h:33
constexpr size_t size() const
Returns the byte size of the table.
Definition: StringTable.h:100
constexpr StringRef operator[](Offset O) const
Definition: StringTable.h:94
constexpr Iterator begin() const
Definition: StringTable.h:136
constexpr Iterator end() const
Definition: StringTable.h:137
constexpr StringTable(const char(&RawTable)[N])
Definition: StringTable.h:72
LLVM Value Representation.
Definition: Value.h:74
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:80
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
#define N