xref: /llvm-project/llvm/test/TableGen/self-reference.td (revision 267b573b55f7f43aaeaf4860e31101cd6a3dbba0)
1// RUN: llvm-tblgen %s | FileCheck %s
2// XFAIL: vg_leak
3
4// CHECK: --- Defs ---
5
6// CHECK: def A0 {
7// CHECK:   dag a = (ops A0);
8// CHECK: }
9
10// CHECK: def B0 {
11// CHECK:   dag a = (ops);
12// CHECK:   A b = B0;
13// CHECK: }
14
15// CHECK: def C0 {
16// CHECK:   dag q = (ops C0);
17// CHECK: }
18
19// CHECK: def D0 {
20// CHECK:   D d = D0;
21// CHECK: }
22
23// CHECK: def E0 {
24// CHECK:   E e = E0;
25// CHECK: }
26
27// CHECK: def F0 {
28// CHECK:   Fa as_a = F0;
29// CHECK:   Fb as_b = F0;
30// CHECK: }
31// CHECK: def F0x {
32// CHECK:   Fc as_c = F0;
33// CHECK: }
34
35// CHECK: def anonymous_0 {
36// CHECK:   G g = anonymous_0;
37// CHECK: }
38// CHECK: def anonymous_1 {
39// CHECK:   G g = anonymous_1;
40// CHECK: }
41// CHECK: def anonymous_2 {
42// CHECK:   G g = anonymous_2;
43// CHECK: }
44// CHECK: def anonymous_5 {
45// CHECK:   G g = anonymous_5;
46// CHECK: }
47
48def ops;
49
50class A<dag d> {
51  dag a = d;
52}
53
54// This type of self-reference is used in various places defining register
55// classes.
56def A0 : A<(ops A0)>;
57
58class B<string self> {
59  A b = !cast<A>(self);
60}
61
62// A stronger form of this type of self-reference is used at least in the
63// SystemZ backend to define a record which is a ComplexPattern and an Operand
64// at the same time.
65def B0 : A<(ops)>, B<"B0">;
66
67// Casting C0 to C by name here is tricky, because it happens while (or rather:
68// before) adding C as a superclass. However, SystemZ uses this pattern.
69class C<string self> {
70  dag q = (ops !cast<C>(self));
71}
72
73def C0 : C<"C0">;
74
75// Explore some unused corner cases.
76//
77// A self-reference within a class may seem icky, but it unavoidably falls out
78// orthogonally of having forward class declarations and late resolve of self
79// references.
80class D<string self> {
81  D d = !cast<D>(self);
82}
83
84def D0 : D<"D0">;
85
86class E<E x> {
87  E e = x;
88}
89
90// Putting the !cast directly in the def should work as well: we shouldn't
91// depend on implementation details of when exactly the record is looked up.
92//
93// Note the difference between !cast<E>("E0") and plain E0: the latter wouldn't
94// work here because E0 does not yet have E as a superclass while the template
95// arguments are being parsed.
96def E0 : E<!cast<E>("E0")>;
97
98// Ensure that records end up with the correct type even when direct self-
99// references are involved.
100class Fa;
101class Fb<Fa x> {
102  Fa as_a = x;
103}
104class Fc<Fb x> {
105  Fb as_b = x;
106}
107
108def F0 : Fa, Fb<F0>, Fc<F0>;
109def F0x {
110  Fc as_c = F0;
111}
112
113// anonymous record self-reference in foreach and multiclass
114class G {
115  G g = !cast<G>(NAME);
116}
117
118foreach _ = [1, 2] in
119  def : G;
120
121multiclass H {
122  def : G;
123}
124
125defm : H;
126defm : H;
127