LLVM 22.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 // Regardless of how many strings are in the table, the last one should also
82 // be null terminated. This also ensures that computing `strlen` on the
83 // strings can't accidentally run past the end of the table.
84 assert(Table.data()[Table.size() - 1] == '\0' &&
85 "Last byte must be a null byte.");
86 }
87
88 // Returns the raw C string from the table starting with the provided offset.
89 // The returned string is null terminated.
90 constexpr const char *getCString(Offset O) const {
91 assert(O.value() < Table.size() && "Out of bounds offset!");
92 return Table.data() + O.value();
93 }
94
95 // Get a string from the table starting with the provided offset. The returned
96 // `StringRef` is in fact null terminated, and so can be converted safely to a
97 // C-string if necessary for a system API.
98 constexpr StringRef operator[](Offset O) const { return getCString(O); }
99
100 /// Returns the byte size of the table.
101 constexpr size_t size() const { return Table.size(); }
102
104 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
105 const StringRef> {
106 friend StringTable;
107
108 const StringTable *Table;
109 Offset O;
110
111 // A cache of one value to allow `*` to return a reference.
112 mutable StringRef S;
113
114 explicit constexpr Iterator(const StringTable &Table, Offset O)
115 : Table(&Table), O(O) {}
116
117 public:
118 constexpr Iterator(const Iterator &RHS) = default;
119 constexpr Iterator(Iterator &&RHS) = default;
120
122 Table = RHS.Table;
123 O = RHS.O;
124 S = RHS.S;
125 return *this;
126 }
127
128 bool operator==(const Iterator &RHS) const {
129 assert(Table == RHS.Table && "Compared iterators for unrelated tables!");
130 return O == RHS.O;
131 }
132
133 const StringRef &operator*() const {
134 S = (*Table)[O];
135 return S;
136 }
137
139 O = O.value() + (*Table)[O].size() + 1;
140 return *this;
141 }
142
143 Offset offset() const { return O; }
144 };
145
146 constexpr Iterator begin() const { return Iterator(*this, 0); }
147 constexpr Iterator end() const { return Iterator(*this, size() - 1); }
148};
149
150} // namespace llvm
151
152#endif // LLVM_ADT_STRING_TABLE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Value * RHS
Value * LHS
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:154
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:148
bool operator==(const Iterator &RHS) const
Definition: StringTable.h:128
const StringRef & operator*() const
Definition: StringTable.h:133
Iterator & operator=(const Iterator &RHS)
Definition: StringTable.h:121
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:101
constexpr StringRef operator[](Offset O) const
Definition: StringTable.h:98
constexpr Iterator begin() const
Definition: StringTable.h:146
constexpr Iterator end() const
Definition: StringTable.h:147
constexpr const char * getCString(Offset O) const
Definition: StringTable.h:90
constexpr StringTable(const char(&RawTable)[N])
Definition: StringTable.h:72
LLVM Value Representation.
Definition: Value.h:75
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