diff options
| author | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-19 14:14:20 +0000 |
|---|---|---|
| committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-19 14:14:20 +0000 |
| commit | 4186cc7c08b2c1cdd7f7a583fa728e065b5be033 (patch) | |
| tree | 7dc97c873ec1ac33733e867a70308de8e0f52f81 /llvm/test | |
| parent | 18f1998a00492bb70de37aaab4441ea9cea306f5 (diff) | |
| download | bcm5719-llvm-4186cc7c08b2c1cdd7f7a583fa728e065b5be033.tar.gz bcm5719-llvm-4186cc7c08b2c1cdd7f7a583fa728e065b5be033.zip | |
TableGen: Check the dynamic type of !cast<Rec>(string)
Summary:
The docs already claim that this happens, but so far it hasn't. As a
consequence, existing TableGen files get this wrong a lot, but luckily
the fixes are all reasonably straightforward.
To make this work with all the existing forms of self-references (since
the true type of a record is only built up over time), the lookup of
self-references in !cast is delayed until the final resolving step.
Change-Id: If5923a72a252ba2fbc81a889d59775df0ef31164
Reviewers: arsenm, craig.topper, tra, MartinO
Subscribers: wdng, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D44475
llvm-svn: 327849
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/TableGen/cast-typeerror.td | 2 | ||||
| -rw-r--r-- | llvm/test/TableGen/self-reference.td | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/llvm/test/TableGen/cast-typeerror.td b/llvm/test/TableGen/cast-typeerror.td index 4cda44b2431..af33a01d27e 100644 --- a/llvm/test/TableGen/cast-typeerror.td +++ b/llvm/test/TableGen/cast-typeerror.td @@ -10,5 +10,5 @@ class C<string name> { B b = !cast<B>(name); } -// CHECK: error: Invalid value of type 'A' is found when setting 'b' of type 'B' +// CHECK: error: Expected type 'B', got 'A' in: !cast<B>("A0") def Test : C<"A0">; diff --git a/llvm/test/TableGen/self-reference.td b/llvm/test/TableGen/self-reference.td index a4f1d9a0737..89d72343047 100644 --- a/llvm/test/TableGen/self-reference.td +++ b/llvm/test/TableGen/self-reference.td @@ -16,6 +16,14 @@ // CHECK: dag q = (ops C0); // CHECK: } +// CHECK: def D0 { +// CHECK: D d = D0; +// CHECK: } + +// CHECK: def E0 { +// CHECK: E e = E0; +// CHECK: } + def ops; class A<dag d> { @@ -42,3 +50,26 @@ class C<string 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")>; |

