LLVM 23.0.0git
Enum.h
Go to the documentation of this file.
1//===-----------------------------------------------------------*- 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// Compact table to map enumeration to strings, generated at compile-time. Basic
10// usage:
11//
12// // Don't reference this elsewhere, this should _not_ go into the final
13// // binary!
14// constexpr EnumStringDef<EnumTy> Defs[] = {
15// {{"abc"}, 1},
16// {{"def"}, 2},
17// };
18// static constexpr auto EnumStrs = BUILD_ENUM_STRINGS(Defs);
19// // ...
20// StringRef Str = EnumStrings(EnumStrs).toString(2); // "def"
21//
22// The table supports multiple strings per enumeration entry for alternative
23// representations, this is e.g. used by llvm-readobj for LLVM and GNU names.
24//
25// Internally, "EnumStrs" above holds the array of enum definitions (EnumString)
26// and the actual strings in one data structure. This permits the EnumString to
27// reference the string with a small 16-bit offset from its location in memory.
28// This design allows for a small size and doesn't require any relocations.
29//
30//===----------------------------------------------------------------------===//
31
32#ifndef LLVM_SUPPORT_ENUM_H
33#define LLVM_SUPPORT_ENUM_H
34
35#include "llvm/ADT/ArrayRef.h"
37#include "llvm/ADT/StringRef.h"
40
41namespace llvm {
42
43/// Compile-time data representation of enum entries. Only use for constexpr
44/// variables passed to BUILD_ENUM_STRINGS, do NOT access the created variable
45/// directly in code! The idea is that this is only used at compile-time to
46/// build a more compact and relocation-free representation in the binary.
47template <typename T, unsigned NumStrs = 1> struct EnumStringDef {
48 std::array<std::string_view, NumStrs> Names;
50};
51
52template <typename T, unsigned NumStrs = 1> class EnumString {
53 template <typename, unsigned, size_t, size_t>
54 friend struct EnumStringsStorage;
55
56 uint16_t NameOff[NumStrs] = {}; ///< Name offsets relative to this pointer.
57 uint8_t NameSize[NumStrs] = {}; ///< Name string lengths.
58 T Value{}; ///< Enumeration value.
59
60 constexpr EnumString() {}
61 // Because name strings are stored relative to the address of this EnumString
62 // in (read-only) memory, EnumString is neither movable nor copyable.
63 EnumString(const EnumString &) = delete;
64 EnumString &operator=(const EnumString &) = delete;
65
66public:
67 constexpr StringRef name(unsigned Idx = 0) const {
68 assert(Idx < NumStrs);
69 return {reinterpret_cast<const char *>(this) + NameOff[Idx], NameSize[Idx]};
70 }
71 constexpr T value() const { return Value; }
72};
73
74namespace detail {
75template <typename T, unsigned NumStrs, size_t N>
76constexpr unsigned
78 unsigned Len = 0;
79 for (unsigned i = 0; i != N; i++)
80 for (unsigned j = 0; j != NumStrs; j++)
81 Len += Entries[i].Names[j].size();
82 return Len;
83}
84} // namespace detail
85
86template <typename T, unsigned NumStrs, size_t N, size_t StrLen>
89 char Strs[StrLen];
90
91 constexpr EnumStringsStorage(const EnumStringDef<T, NumStrs> (&Entries)[N])
92 : Data{}, Strs{} {
93 unsigned StrIdx = 0;
94 for (unsigned i = 0; i < N; i++) {
95 Data[i].Value = Entries[i].Value;
96 for (unsigned j = 0; j < NumStrs; j++) {
97 unsigned StrOff = offsetof(EnumStringsStorage, Strs) + StrIdx;
98 unsigned DataOff = offsetof(EnumStringsStorage, Data) +
99 i * sizeof(EnumString<T, NumStrs>);
100 assert(StrOff - DataOff <= UINT16_MAX && "enum string table too large");
101 std::string_view Name = Entries[i].Names[j];
102 assert(Name.size() <= UINT8_MAX && "enum name too long");
103 Data[i].NameSize[j] = Name.size();
104 Data[i].NameOff[j] = uint16_t(StrOff - DataOff);
105 for (char C : Name)
106 Strs[StrIdx++] = C;
107 }
108 };
109 }
110
111 constexpr size_t size() const { return N; }
112 const EnumString<T, NumStrs> &operator[](size_t Idx) const {
113 assert(Idx < N);
114 return Data[Idx];
115 }
116 const EnumString<T, NumStrs> *begin() const { return std::begin(Data); }
117 const EnumString<T, NumStrs> *end() const { return std::end(Data); }
118};
119
120#define BUILD_ENUM_STRINGS(Tab) \
121 (::llvm::EnumStringsStorage<decltype(Tab[0].Value), Tab[0].Names.size(), \
122 sizeof(Tab) / sizeof(Tab[0]), \
123 ::llvm::detail::enumStringsStorageSize(Tab)>{ \
124 Tab})
125
126template <typename T, unsigned NumStrs = 1> class EnumStrings {
127public:
129
130 template <size_t N, size_t StrLen>
132 : EnumValues(Table.Data, N) {}
133
134 template <typename TValue>
135 StringRef toString(TValue Value, unsigned StrIdx = 0) const {
136 // TODO: optimize with binary search?
137 for (const auto &EnumItem : EnumValues)
138 if (EnumItem.value() == Value)
139 return EnumItem.name(StrIdx);
140 return "";
141 }
142
143 template <typename TValue>
144 std::string toStringOrHex(TValue Value, unsigned StrIdx = 0) const {
145 if (StringRef Str = toString(Value, StrIdx); !Str.empty())
146 return Str.str();
147 return utohexstr(Value, true);
148 }
149
150 size_t size() const { return EnumValues.size(); }
151 const EnumString &operator[](size_t Idx) const { return EnumValues[Idx]; }
152 const EnumString *begin() const { return EnumValues.begin(); }
153 const EnumString *end() const { return EnumValues.end(); }
154
155private:
156 ArrayRef<EnumString> EnumValues;
157};
158
159template <typename T, unsigned NumStrs, size_t N, size_t StrLen>
162
163} // namespace llvm
164
165#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define offsetof(TYPE, MEMBER)
#define T
This file contains some functions that are useful when dealing with strings.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
constexpr T value() const
Definition Enum.h:71
constexpr StringRef name(unsigned Idx=0) const
Definition Enum.h:67
friend struct EnumStringsStorage
Definition Enum.h:54
const EnumString * begin() const
Definition Enum.h:152
const EnumString * end() const
Definition Enum.h:153
StringRef toString(TValue Value, unsigned StrIdx=0) const
Definition Enum.h:135
const EnumString & operator[](size_t Idx) const
Definition Enum.h:151
size_t size() const
Definition Enum.h:150
std::string toStringOrHex(TValue Value, unsigned StrIdx=0) const
Definition Enum.h:144
EnumStrings(const EnumStringsStorage< T, NumStrs, N, StrLen > &Table)
Definition Enum.h:131
::llvm::EnumString< T, NumStrs > EnumString
Definition Enum.h:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
LLVM Value Representation.
Definition Value.h:75
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
constexpr size_t NameSize
Definition XCOFF.h:30
constexpr unsigned enumStringsStorageSize(const EnumStringDef< T, NumStrs >(&Entries)[N])
Definition Enum.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
EnumStrings(const EnumStringsStorage< T, NumStrs, N, StrLen > &) -> EnumStrings< T, NumStrs >
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
#define N
Compile-time data representation of enum entries.
Definition Enum.h:47
std::array< std::string_view, NumStrs > Names
Definition Enum.h:48
const EnumString< T, NumStrs > * begin() const
Definition Enum.h:116
char Strs[StrLen]
Definition Enum.h:89
constexpr size_t size() const
Definition Enum.h:111
constexpr EnumStringsStorage(const EnumStringDef< T, NumStrs >(&Entries)[N])
Definition Enum.h:91
EnumString< T, NumStrs > Data[N]
Definition Enum.h:88
const EnumString< T, NumStrs > & operator[](size_t Idx) const
Definition Enum.h:112
const EnumString< T, NumStrs > * end() const
Definition Enum.h:117