[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:
parent
dfcbf6c70e
commit
bc0af9901b
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user