|  | // RUN: llvm-tblgen %s | FileCheck %s | 
|  | // XFAIL: vg_leak | 
|  |  | 
|  | // CHECK: --- Defs --- | 
|  |  | 
|  | // CHECK: def A0 { | 
|  | // CHECK:   dag a = (ops A0); | 
|  | // CHECK: } | 
|  |  | 
|  | // CHECK: def B0 { | 
|  | // CHECK:   dag a = (ops); | 
|  | // CHECK:   A b = B0; | 
|  | // CHECK: } | 
|  |  | 
|  | // CHECK: def C0 { | 
|  | // CHECK:   dag q = (ops C0); | 
|  | // CHECK: } | 
|  |  | 
|  | // CHECK: def D0 { | 
|  | // CHECK:   D d = D0; | 
|  | // CHECK: } | 
|  |  | 
|  | // CHECK: def E0 { | 
|  | // CHECK:   E e = E0; | 
|  | // CHECK: } | 
|  |  | 
|  | // CHECK: def F0 { | 
|  | // CHECK:   Fa as_a = F0; | 
|  | // CHECK:   Fb as_b = F0; | 
|  | // CHECK: } | 
|  | // CHECK: def F0x { | 
|  | // CHECK:   Fc as_c = F0; | 
|  | // CHECK: } | 
|  |  | 
|  | def ops; | 
|  |  | 
|  | class A<dag d> { | 
|  | dag a = d; | 
|  | } | 
|  |  | 
|  | // This type of self-reference is used in various places defining register | 
|  | // classes. | 
|  | def A0 : A<(ops A0)>; | 
|  |  | 
|  | class B<string self> { | 
|  | A b = !cast<A>(self); | 
|  | } | 
|  |  | 
|  | // A stronger form of this type of self-reference is used at least in the | 
|  | // SystemZ backend to define a record which is a ComplexPattern and an Operand | 
|  | // at the same time. | 
|  | def B0 : A<(ops)>, B<"B0">; | 
|  |  | 
|  | // Casting C0 to C by name here is tricky, because it happens while (or rather: | 
|  | // before) adding C as a superclass. However, SystemZ uses this pattern. | 
|  | class C<string self> { | 
|  | dag q = (ops !cast<C>(self)); | 
|  | } | 
|  |  | 
|  | def C0 : C<"C0">; | 
|  |  | 
|  | // Explore some unused corner cases. | 
|  | // | 
|  | // A self-reference within a class may seem icky, but it unavoidably falls out | 
|  | // orthogonally of having forward class declarations and late resolve of self | 
|  | // references. | 
|  | class D<string self> { | 
|  | D d = !cast<D>(self); | 
|  | } | 
|  |  | 
|  | def D0 : D<"D0">; | 
|  |  | 
|  | class E<E x> { | 
|  | E e = x; | 
|  | } | 
|  |  | 
|  | // Putting the !cast directly in the def should work as well: we shouldn't | 
|  | // depend on implementation details of when exactly the record is looked up. | 
|  | // | 
|  | // Note the difference between !cast<E>("E0") and plain E0: the latter wouldn't | 
|  | // work here because E0 does not yet have E as a superclass while the template | 
|  | // arguments are being parsed. | 
|  | def E0 : E<!cast<E>("E0")>; | 
|  |  | 
|  | // Ensure that records end up with the correct type even when direct self- | 
|  | // references are involved. | 
|  | class Fa; | 
|  | class Fb<Fa x> { | 
|  | Fa as_a = x; | 
|  | } | 
|  | class Fc<Fb x> { | 
|  | Fb as_b = x; | 
|  | } | 
|  |  | 
|  | def F0 : Fa, Fb<F0>, Fc<F0>; | 
|  | def F0x { | 
|  | Fc as_c = F0; | 
|  | } |