[llvm] Add a super simple wrapper for a merged string table. (PR #119488)
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 11 17:37:22 PST 2024
================
@@ -0,0 +1,83 @@
+//===- StringTable.h - Table of strings tracked by offset ----------C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRING_TABLE_H
+#define LLVM_ADT_STRING_TABLE_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// A table of densely packed, null-terminated strings indexed by offset.
+///
+/// This table abstracts a densely concatenated list of null-terminated strings,
+/// each of which can be referenced using an offset into the table.
+///
+/// This requires and ensures that the string at offset 0 is also the empty
+/// string. This helps allow zero-initialized offsets form empty strings and
+/// avoids non-zero initialization when using a string literal pointer would
+/// allow a null pointer.
+///
+/// The primary use case is having a single global string literal for the table
+/// contents, and offsets into it in other global data structures to avoid
+/// dynamic relocations of individual string literal pointers in those global
+/// data structures.
+class StringTable {
+ StringRef Table;
+
+public:
+ // An offset into one of these packed string tables, used to select a string
+ // within the table.
+ //
+ // Typically these are created by TableGen or other code generator from
+ // computed offsets, and it just wraps that integer into a type until it is
+ // used with the relevant table.
+ //
+ // We also ensure that the empty string is at offset zero and default
+ // constructing this class gives you an offset of zero. This makes default
+ // constructing this type work similarly (after indexing the table) to default
+ // constructing a `StringRef`.
+ class Offset {
+ // Note that we ensure the empty string is at offset zero.
+ unsigned Value = 0;
+
+ public:
+ Offset() = default;
+ Offset(unsigned Value) : Value(Value) {}
+
+ unsigned value() const { return Value; }
+ };
+
+ // We directly handle string literals with a templated converting constructor
+ // because we *don't* want to do `strlen` on them -- we fully expect null
+ // bytes in this input. This is somewhat the opposite of how `StringLiteral`
+ // works.
+ template <size_t N>
+ constexpr StringTable(const char (&RawTable)[N]) : Table(RawTable, N) {
+ assert(!Table.empty() && "Requires at least a valid empty string.");
----------------
chandlerc wrote:
Yep, as long as they don't fire.
That said, these weren't because `StringRef` for some reason only supports `constexpr` calls to `empty`, `size`, and `data`. I've rewritten this to work in `constexpr` and tested it.
Also added the static assert, seems nice.
https://github.com/llvm/llvm-project/pull/119488
More information about the llvm-commits
mailing list