cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
240 lines
6.3 KiB
TableGen
240 lines
6.3 KiB
TableGen
// 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<string str, int val1, int val2, bits<64> 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<bits<16> 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 ((uint16_t)Encoding != std::clamp((uint16_t)Encoding, (uint16_t)0xA, (uint16_t)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, CEnum kind, int enc> {
|
|
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, int val1> {
|
|
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<bits<8> value> {
|
|
bits<8> Value = value;
|
|
bit IsEven = !eq(!and(value, 1), 0);
|
|
bit IsOdd = !not(IsEven);
|
|
}
|
|
|
|
foreach i = {1-10} in {
|
|
def : EEntry<i>;
|
|
}
|
|
|
|
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";
|
|
}
|