diff options
| author | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-06 13:48:20 +0000 |
|---|---|---|
| committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-06 13:48:20 +0000 |
| commit | 13080fd14e71fa4cf64bdd477ebc8ca01b9c856f (patch) | |
| tree | 2547fbbc63a81a89beb1f5b7920cd599acbd7237 /llvm/test | |
| parent | 945a84a03ca30c2a610e878dc2199591b3422d87 (diff) | |
| download | bcm5719-llvm-13080fd14e71fa4cf64bdd477ebc8ca01b9c856f.tar.gz bcm5719-llvm-13080fd14e71fa4cf64bdd477ebc8ca01b9c856f.zip | |
TableGen: Generalize record types to fix typeIsConvertibleTo et al.
Summary:
Allow RecordRecTy to represent the type "subclass of N superclasses",
where N may be zero. Furthermore, generate RecordRecTy instances only
with actual classes in the list.
Keeping track of multiple superclasses is required to resolve the type
of a list correctly in some cases. The old code relied on the incorrect
behavior of typeIsConvertibleTo, and an earlier version of this change
relied on a modified ordering of superclasses (it was committed in
r325884 and then reverted because unfortunately some of clang-tblgen's
backends depend on the ordering).
Previously, the DefInit for each Record would have a RecordRecTy of
that Record as its type. Now, all defs with the same superclasses will
share the same type.
This allows us to be more consistent about type checks involving records:
- typeIsConvertibleTo actually requires the LHS to be a subtype of the
RHS
- resolveTypes will return the least supertype of given record types in
all cases
- different record types in the two branches of an !if are handled
correctly
Add a test that used to be accepted without flagging the obvious type
error.
Change-Id: Ib366db1a4e6a079f1a0851e469b402cddae76714
Reviewers: arsenm, craig.topper, tra, MartinO
Subscribers: wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D43680
llvm-svn: 326783
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/TableGen/if-type.td | 11 | ||||
| -rw-r--r-- | llvm/test/TableGen/if.td | 24 |
2 files changed, 35 insertions, 0 deletions
diff --git a/llvm/test/TableGen/if-type.td b/llvm/test/TableGen/if-type.td new file mode 100644 index 00000000000..809195be007 --- /dev/null +++ b/llvm/test/TableGen/if-type.td @@ -0,0 +1,11 @@ +// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s +// XFAIL: vg_leak + +class A<int dummy> {} +class B<int dummy> : A<dummy> {} +class C<int dummy> : A<dummy> {} + +// CHECK: Value 'x' of type 'C' is incompatible with initializer '{{.*}}' of type 'A' +class X<int cc, B b, C c> { + C x = !if(cc, b, c); +} diff --git a/llvm/test/TableGen/if.td b/llvm/test/TableGen/if.td index 019e4dd1585..a6af59e7283 100644 --- a/llvm/test/TableGen/if.td +++ b/llvm/test/TableGen/if.td @@ -73,6 +73,30 @@ def DI1: I1<1>; // CHECK-NEXT: int i = 0; def DI2: I2<1>; +// Check that !if with operands of different subtypes can initialize a +// supertype variable. +// +// CHECK: def EXd1 { +// CHECK: E x = E1d; +// CHECK: } +// +// CHECK: def EXd2 { +// CHECK: E x = E2d; +// CHECK: } +class E<int dummy> {} +class E1<int dummy> : E<dummy> {} +class E2<int dummy> : E<dummy> {} + +class EX<int cc, E1 b, E2 c> { + E x = !if(cc, b, c); +} + +def E1d : E1<0>; +def E2d : E2<0>; + +def EXd1 : EX<1, E1d, E2d>; +def EXd2 : EX<0, E1d, E2d>; + // CHECK: def One // CHECK-NEXT: list<int> first = [1, 2, 3]; // CHECK-NEXT: list<int> rest = [1, 2, 3]; |

