[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@intel.com>
This commit is contained in:
Nick Sarnie 2026-03-03 00:09:23 +09:00 committed by GitHub
parent dfcbf6c70e
commit bc0af9901b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 22 additions and 3 deletions

View File

@ -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,

View File

@ -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

View File

@ -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> {

View File

@ -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());