Pengcheng Wang 883612859b
[TableGen] Add !instances operator to get defined records (#129680)
The format is: `!instances<T>([regex])`.
    
This operator produces a list of records whose type is `T`. If
`regex` is provided, only records whose name matches the regular
expression `regex` will be included. The format of `regex` is ERE
(Extended POSIX Regular Expressions).
2025-03-28 16:31:00 +08:00

134 lines
3.7 KiB
TableGen

// RUN: llvm-tblgen %s | FileCheck %s
// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
// XFAIL: vg_leak
class A;
def a0 : A;
def a1 : A;
class B : A;
def b0 : B;
def b1 : B;
// CHECK-LABEL: def test0_instances_A {
// CHECK-NEXT: list<A> instances = [a0, a1, b0, b1];
// CHECK-NEXT: }
def test0_instances_A {
list<A> instances = !instances<A>();
}
// CHECK-LABEL: def test1_instances_A_x0 {
// CHECK-NEXT: list<A> instances = [a0, b0];
// CHECK-NEXT: }
def test1_instances_A_x0 {
list<A> instances = !instances<A>(".*0");
}
// CHECK-LABEL: def test2_instances_A_x1 {
// CHECK-NEXT: list<A> instances = [a1, b1];
// CHECK-NEXT: }
def test2_instances_A_x1 {
list<A> instances = !instances<A>(".*1");
}
// CHECK-LABEL: def test3_instances_B {
// CHECK-NEXT: list<B> instances = [b0, b1];
// CHECK-NEXT: }
def test3_instances_B {
list<B> instances = !instances<B>();
}
//-----------------------------------------------------------------------------//
def a2 : A;
def b2 : B;
class ClassTest {
list<A> instances_A = !instances<A>();
list<B> instances_B = !instances<B>();
}
def a3 : A;
def b3 : B;
def test4_in_class_def : ClassTest;
// CHECK-LABEL: def test4_in_class_def {
// CHECK-NEXT: list<A> instances_A = [a0, a1, a2, a3, b0, b1, b2, b3];
// CHECK-NEXT: list<B> instances_B = [b0, b1, b2, b3];
// CHECK-NEXT: }
//-----------------------------------------------------------------------------//
// Self-recurrence is not supported, so it won't be count in.
// CHECK-LABEL: def test5_self_recurrence {
// CHECK-NEXT: list<A> instances_A = [a0, a1, a2, a3, b0, b1, b2, b3];
// CHECK-NEXT: }
def test5_self_recurrence : A {
list<A> instances_A = !instances<A>();
}
//-----------------------------------------------------------------------------//
// Test these in multiclasses/loops.
class C {
list<C> instances_C = !instances<C>();
}
multiclass MultiClassTest {
foreach i = 0-2 in {
def "c"#i : C;
}
}
// CHECK-LABEL: def test6_in_multiclass_def_c0 {
// CHECK-NEXT: list<C> instances_C = [];
// CHECK-NEXT: }
// CHECK-LABEL: def test6_in_multiclass_def_c1 {
// CHECK-NEXT: list<C> instances_C = [test6_in_multiclass_def_c0];
// CHECK-NEXT: }
// CHECK-LABEL: def test6_in_multiclass_def_c2 {
// CHECK-NEXT: list<C> instances_C = [test6_in_multiclass_def_c0, test6_in_multiclass_def_c1];
// CHECK-NEXT: }
defm test6_in_multiclass_def_ : MultiClassTest;
//-----------------------------------------------------------------------------//
// Default argument/temporary actual parameter will be considered as well.
class D<int n>;
class TestArgument<D d = D<0>> {
list<D> instances_D = !instances<D>();
}
// CHECK-LABEL: def test7_default_arg {
// CHECK-NEXT: list<D> instances_D = [anonymous_0];
// CHECK-NEXT: }
def test7_default_arg : TestArgument;
// CHECK-LABEL: def test8_anonymous0_arg {
// CHECK-NEXT: list<D> instances_D = [anonymous_0, anonymous_1];
// CHECK-NEXT: }
// CHECK-LABEL: def test8_anonymous1_arg {
// CHECK-NEXT: list<D> instances_D = [anonymous_0, anonymous_1, anonymous_2];
// CHECK-NEXT: }
def test8_anonymous0_arg : TestArgument<D<1>>;
def test8_anonymous1_arg : TestArgument<D<2>>;
//-----------------------------------------------------------------------------//
#ifdef ERROR1
defvar error1 = !instances<A>(123);
// ERROR1: error: expected string type argument in !instances operator
#endif
#ifdef ERROR2
defvar error2 = !instances<1>("");
// ERROR2: error: Unknown token when expecting a type
#endif
#ifdef ERROR3
defvar error3 = !instances<A>("([)]");
// ERROR3: error: invalid regex '([)]'
#endif