[llvm] bc0af99 - [TableGen] Allow specification of underlying type for GenericEnum (#183769)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 07:09:29 PST 2026
Author: Nick Sarnie
Date: 2026-03-02T15:09:23Z
New Revision: bc0af9901b5178204ece0658a0a0b0f57aef6aac
URL: https://github.com/llvm/llvm-project/commit/bc0af9901b5178204ece0658a0a0b0f57aef6aac
DIFF: https://github.com/llvm/llvm-project/commit/bc0af9901b5178204ece0658a0a0b0f57aef6aac.diff
LOG: [TableGen] Allow specification of underlying type for GenericEnum (#183769)
Allow specification of the underlying C++ data type for `GenericEnum`.
I ran into this because I was trying to use a TableGen-genered enum in
`DenseSet` which requires the underlying type be specified.
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
Added:
Modified:
llvm/docs/TableGen/BackEnds.rst
llvm/include/llvm/TableGen/SearchableTable.td
llvm/test/TableGen/generic-tables.td
llvm/utils/TableGen/SearchableTableEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/docs/TableGen/BackEnds.rst b/llvm/docs/TableGen/BackEnds.rst
index 1e3cb8783df16..ea74dfd217b2e 100644
--- a/llvm/docs/TableGen/BackEnds.rst
+++ b/llvm/docs/TableGen/BackEnds.rst
@@ -629,6 +629,10 @@ using the ``let`` statement.
field, it will be assigned an integer value. Values are assigned in
alphabetical order starting with 0.
+* ``string UnderlyingType``. The name of the underlying C++ data type
+ of the enum. If a record has no such field, there will be no specification
+ in the generated enum.
+
Here is an example where the values of the elements are specified
explicitly, as a template argument to the ``BEntry`` class. The resulting
C++ code is shown.
@@ -670,6 +674,7 @@ by element name.
def CEnum : GenericEnum {
let FilterClass = "CEnum";
+ let UnderlyingType = "uint32_t";
}
class CEnum;
@@ -681,7 +686,7 @@ by element name.
.. code-block:: text
#ifdef GET_CEnum_DECL
- enum CEnum {
+ enum CEnum : uint32_t {
CBar = 0,
CBaz = 1,
CFoo = 2,
diff --git a/llvm/include/llvm/TableGen/SearchableTable.td b/llvm/include/llvm/TableGen/SearchableTable.td
index f10e1597d8da7..71b837731c440 100644
--- a/llvm/include/llvm/TableGen/SearchableTable.td
+++ b/llvm/include/llvm/TableGen/SearchableTable.td
@@ -47,6 +47,12 @@ class GenericEnum {
// If ValueField is not set, enum values will be assigned automatically,
// starting at 0, according to a lexicographical sort of the entry names.
string ValueField;
+
+ // (Optional) Underlying C++ data type of the enum.
+ //
+ // If UnderlyingType is not set, there will be no specification in
+ // the generated enum.
+ string UnderlyingType;
}
// Define a record derived from this class to generate a generic table. This
diff --git a/llvm/test/TableGen/generic-tables.td b/llvm/test/TableGen/generic-tables.td
index 6b72a3e807e7d..ca29dcff75c0e 100644
--- a/llvm/test/TableGen/generic-tables.td
+++ b/llvm/test/TableGen/generic-tables.td
@@ -13,7 +13,7 @@ include "llvm/TableGen/SearchableTable.td"
// CHECK: }
// CHECK-LABEL: GET_CEnum_DECL
-// CHECK: enum CEnum {
+// CHECK: enum CEnum : uint64_t {
// CHECK: CBar
// CHECK: CBaz
// CHECK: CFoo
@@ -130,6 +130,7 @@ def CBaz : CEnum;
def CEnum : GenericEnum {
let FilterClass = "CEnum";
+ let UnderlyingType = "uint64_t";
}
class CEntry<string name, CEnum kind, int enc> {
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 88aa6bf8e9242..e100682bbcec3 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -55,6 +55,7 @@ struct GenericEnum {
const Record *Class = nullptr;
std::string PreprocessorGuard;
MapVector<const Record *, Entry> Entries;
+ std::string UnderlyingType;
const Entry *getEntry(const Record *Def) const {
auto II = Entries.find(Def);
@@ -336,7 +337,10 @@ void SearchableTableEmitter::emitGenericEnum(const GenericEnum &Enum,
raw_ostream &OS) {
emitIfdef((Twine("GET_") + Enum.PreprocessorGuard + "_DECL").str(), OS);
- OS << "enum " << Enum.Name << " {\n";
+ OS << "enum " << Enum.Name;
+ if (!Enum.UnderlyingType.empty())
+ OS << " : " << Enum.UnderlyingType;
+ OS << " {\n";
for (const auto &[Name, Value] :
make_second_range(Enum.Entries.getArrayRef()))
OS << " " << Name << " = " << Value << ",\n";
@@ -763,6 +767,9 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
Twine("Enum FilterClass '") + FilterClass +
"' does not exist");
+ if (!EnumRec->isValueUnset("UnderlyingType"))
+ Enum->UnderlyingType = EnumRec->getValueAsString("UnderlyingType");
+
collectEnumEntries(*Enum, NameField, ValueField,
Records.getAllDerivedDefinitions(FilterClass));
EnumMap.try_emplace(EnumRec, Enum.get());
More information about the llvm-commits
mailing list