// RUN: llvm-tblgen -gen-searchable-tables -I %p/../../include %s | FileCheck %s // RUN: not llvm-tblgen -gen-searchable-tables -I %p/../../include -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s // XFAIL: vg_leak include "llvm/TableGen/SearchableTable.td" // CHECK-LABEL: GET_BValues_DECL // CHECK: enum BValues { // CHECK: BAlice = 172, // CHECK: BBob = 20, // CHECK: BCharlie = 128, // CHECK: BEve = 76, // CHECK: } // CHECK-LABEL: GET_CEnum_DECL // CHECK: enum CEnum { // CHECK: CBar // CHECK: CBaz // CHECK: CFoo // CHECK: } // CHECK-LABEL: GET_ATable_DECL // CHECK: const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2); // CHECK-LABEL: GET_ATable_IMPL // CHECK: constexpr AEntry ATable[] = { // CHECK-NOT: { "aaa" // CHECK: { "baz", 0x2, 0x6, 0xFFFFFFFF00000000 }, // CHECK: { "foo", 0x4, 0x4, 0x100000000 }, // CHECK: { "foobar", 0x4, 0x5, 0x100000000 }, // CHECK: { "bar", 0x5, 0x3, 0x100000000 }, // CHECK: }; // CHECK: const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) { // CHECK: return &*Idx; // CHECK: } class AEntry val3> { string Str = str; bits<8> Val1 = val1; bits<10> Val2 = val2; bits<64> Val3 = val3; bit IsNeeded = 1; } def : AEntry<"aaa", 0, 0, 0> { let IsNeeded = 0; } def : AEntry<"bar", 5, 3, 0x100000000>; def : AEntry<"baz", 2, 6, 0xFFFFFFFF00000000>; def : AEntry<"foo", 4, 4, 0b0000000000000000000000000000000100000000000000000000000000000000>; def : AEntry<"foobar", 4, 5, 4294967296>; def ATable : GenericTable { let FilterClass = "AEntry"; let FilterClassField = "IsNeeded"; let Fields = ["Str", "Val1", "Val2", "Val3"]; let PrimaryKey = ["Val1", "Val2"]; let PrimaryKeyName = "lookupATableByValues"; } // CHECK-LABEL: GET_BTable_IMPL // CHECK: constexpr BTypeName BTable[] = { // CHECK: { "BAlice", 0xAC, false, }, // CHECK: { "BBob", 0x14, false, Bob == 13 }, // CHECK: { "BCharlie", 0x80, true, Charlie == 42 }, // CHECK: { "BEve", 0x4C, true, Eve == 108 }, // CHECK: }; // CHECK: const BTypeName *lookupBTableByName(StringRef Name) { // CHECK: return &BTable[Idx->_index]; // CHECK: } // CHECK: const BTypeName *lookupBTableByNameAndFlag(StringRef Name, bool Flag) { // CHECK: return &BTable[Idx->_index]; // CHECK: } class BEntry enc, bit flag = 0, code test = [{}]> { string Name = NAME; bits<16> Encoding = enc; bit Flag = flag; code Test = test; } def BAlice : BEntry<0xac>; def BBob : BEntry<0x14, 0, [{Bob == 13}]>; def BCharlie : BEntry<0x80, 1, "Charlie == 42">; def BEve : BEntry<0x4c, 1, [{Eve == }] # 108>; def BValues : GenericEnum { let FilterClass = "BEntry"; let NameField = "Name"; let ValueField = "Encoding"; } def BTable : GenericTable { let FilterClass = "BEntry"; string CppTypeName = "BTypeName"; let Fields = ["Name", "Encoding", "Flag", "Test"]; string TypeOf_Test = "code"; } def lookupBTableByName : SearchIndex { let Table = BTable; let Key = ["Name"]; } def lookupBTableByNameAndFlag : SearchIndex { let Table = BTable; let Key = ["Name", "Flag"]; } // CHECK-LABEL: GET_CTable_DECL // CHECK: const CEntry *lookupCEntryByEncoding(uint16_t Encoding); // CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind); // CHECK-LABEL: GET_CTable_IMPL // CHECK: const CEntry *lookupCEntryByEncoding(uint16_t Encoding) { // CHECK: if ((Encoding < 0xA) || // CHECK: (Encoding > 0xF)) // CHECK: return nullptr; // CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind) { // CHECK: Index[] = { // CHECK: { "ALICE", CBar, 1 }, // CHECK: { "ALICE", CFoo, 0 }, // CHECK: { "BOB", CBaz, 2 }, class CEnum; def CFoo : CEnum; def CBar : CEnum; def CBaz : CEnum; def CEnum : GenericEnum { let FilterClass = "CEnum"; } class CEntry { string Name = name; CEnum Kind = kind; bits<16> Encoding = enc; } def : CEntry<"alice", CFoo, 10>; def : CEntry<"alice", CBar, 13>; def : CEntry<"bob", CBaz, 15>; def CTable : GenericTable { let FilterClass = "CEntry"; let Fields = ["Name", "Kind", "Encoding"]; string TypeOf_Kind = "CEnum"; let PrimaryKey = ["Encoding"]; let PrimaryKeyName = "lookupCEntryByEncoding"; let PrimaryKeyEarlyOut = 1; } def lookupCEntry : SearchIndex { let Table = CTable; let Key = ["Name", "Kind"]; } #ifdef ERROR1 class DEntry { string Str = str; bits<8> Val1 = val1; } def DFoo : DEntry<"foo", 1>; // ERROR1: [[@LINE+1]]:5: error: Record 'DBar' for table 'DTable' is missing field 'Val1' def DBar : DEntry<"bar", ?>; def DTable : GenericTable { let FilterClass = "DEntry"; let Fields = ["Str", "Val1"]; } #endif // ERROR1 // CHECK-LABEL: GET_EEntryEvenTable_DECL // CHECK: const EEntry *lookupEEntryEvenTableByValue(uint8_t Value); // CHECK-LABEL: GET_EEntryEvenTable_IMPL // CHECK: constexpr EEntry EEntryEvenTable[] = { // CHECK: { 0x2 // CHECK: { 0x4 // CHECK: { 0x6 // CHECK: { 0x8 // CHECK: { 0xA // CHECK: }; // CHECK: const EEntry *lookupEEntryEvenTableByValue(uint8_t Value) { // CHECK: return &*Idx; // CHECK: } // CHECK-LABEL: GET_EEntryOddTable_DECL // CHECK: const EEntry *lookupEEntryOddTableByValue(uint8_t Value); // CHECK-LABEL: GET_EEntryOddTable_IMPL // CHECK: constexpr EEntry EEntryOddTable[] = { // CHECK: { 0x1 // CHECK: { 0x3 // CHECK: { 0x5 // CHECK: { 0x7 // CHECK: { 0x9 // CHECK: }; // CHECK: const EEntry *lookupEEntryOddTableByValue(uint8_t Value) { // CHECK: return &*Idx; // CHECK: } // We can construct two GenericTables with the same FilterClass, so that they // select from the same overall set of records, but assign them with different // FilterClassField values so that they include different subsets of the records // of that class. class EEntry value> { bits<8> Value = value; bit IsEven = !eq(!and(value, 1), 0); bit IsOdd = !not(IsEven); } foreach i = {1-10} in { def : EEntry; } def EEntryEvenTable : GenericTable { let FilterClass = "EEntry"; let FilterClassField = "IsEven"; let Fields = ["Value"]; let PrimaryKey = ["Value"]; let PrimaryKeyName = "lookupEEntryEvenTableByValue"; } def EEntryOddTable : GenericTable { let FilterClass = "EEntry"; let FilterClassField = "IsOdd"; let Fields = ["Value"]; let PrimaryKey = ["Value"]; let PrimaryKeyName = "lookupEEntryOddTableByValue"; }