blob: 5789d3ba570ff831679a6f832e76633166e85aec [file] [log] [blame]
Nicolai Haehnle0715b9e2018-03-19 14:14:10 +00001// 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
Nicolai Haehnlec9cc57b2018-03-19 14:14:20 +000019// CHECK: def D0 {
20// CHECK: D d = D0;
21// CHECK: }
22
23// CHECK: def E0 {
24// CHECK: E e = E0;
25// CHECK: }
26
Nicolai Haehnle02dea262018-03-21 17:12:53 +000027// 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
Nicolai Haehnle0715b9e2018-03-19 14:14:10 +000035def ops;
36
37class A<dag d> {
38 dag a = d;
39}
40
41// This type of self-reference is used in various places defining register
42// classes.
43def A0 : A<(ops A0)>;
44
45class B<string self> {
46 A b = !cast<A>(self);
47}
48
49// A stronger form of this type of self-reference is used at least in the
50// SystemZ backend to define a record which is a ComplexPattern and an Operand
51// at the same time.
52def B0 : A<(ops)>, B<"B0">;
53
54// Casting C0 to C by name here is tricky, because it happens while (or rather:
55// before) adding C as a superclass. However, SystemZ uses this pattern.
56class C<string self> {
57 dag q = (ops !cast<C>(self));
58}
59
60def C0 : C<"C0">;
Nicolai Haehnlec9cc57b2018-03-19 14:14:20 +000061
62// Explore some unused corner cases.
63//
64// A self-reference within a class may seem icky, but it unavoidably falls out
65// orthogonally of having forward class declarations and late resolve of self
66// references.
67class D<string self> {
68 D d = !cast<D>(self);
69}
70
71def D0 : D<"D0">;
72
73class E<E x> {
74 E e = x;
75}
76
77// Putting the !cast directly in the def should work as well: we shouldn't
78// depend on implementation details of when exactly the record is looked up.
79//
80// Note the difference between !cast<E>("E0") and plain E0: the latter wouldn't
81// work here because E0 does not yet have E as a superclass while the template
82// arguments are being parsed.
83def E0 : E<!cast<E>("E0")>;
Nicolai Haehnle02dea262018-03-21 17:12:53 +000084
85// Ensure that records end up with the correct type even when direct self-
86// references are involved.
87class Fa;
88class Fb<Fa x> {
89 Fa as_a = x;
90}
91class Fc<Fb x> {
92 Fb as_b = x;
93}
94
95def F0 : Fa, Fb<F0>, Fc<F0>;
96def F0x {
97 Fc as_c = F0;
98}