mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
4855f53b1d
Summary: These allow you to get and set the operator of a dag node, without affecting its list of arguments. `!getop` is slightly fiddly because in many contexts you need its return value to have a static type more specific than 'any record'. It works to say `!cast<BaseClass>(!getop(...))`, but it's cumbersome, so I made `!getop` take an optional type suffix itself, so that can be written as the shorter `!getop<BaseClass>(...)`. Reviewers: hfinkel, nhaehnle Reviewed By: nhaehnle Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71191
62 lines
2.0 KiB
TableGen
62 lines
2.0 KiB
TableGen
// RUN: llvm-tblgen %s | FileCheck %s
|
|
// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
|
|
// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
|
|
// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
|
|
|
|
class Base;
|
|
class OtherBase;
|
|
|
|
def foo: Base;
|
|
def bar: Base;
|
|
def qux: OtherBase;
|
|
|
|
def test {
|
|
dag orig = (foo 1, 2:$a, $b);
|
|
dag another = (qux "hello", $world);
|
|
|
|
// CHECK: dag replaceWithBar = (bar 1, 2:$a, ?:$b);
|
|
dag replaceWithBar = !setop(orig, bar);
|
|
|
|
// CHECK: dag replaceWithBaz = (qux 1, 2:$a, ?:$b);
|
|
dag replaceWithBaz = !setop(orig, qux);
|
|
|
|
// CHECK: Base getopWithCast = foo;
|
|
Base getopWithCast = !getop<Base>(orig);
|
|
|
|
// CHECK: dag getopToSetop = (foo "hello", ?:$world);
|
|
dag getopToSetop = !setop(another, !getop(orig));
|
|
|
|
// CHECK: dag getopToBangDag = (foo 1:$a, 2:$b, 3:$c);
|
|
dag getopToBangDag = !dag(!getop(orig), [1, 2, 3], ["a", "b", "c"]);
|
|
|
|
// CHECK: dag getopToDagInit = (foo "it worked");
|
|
dag getopToDagInit = (!getop(orig) "it worked");
|
|
|
|
#ifdef ERROR1
|
|
// !getop(...) has a static type of 'any record at all, with no
|
|
// required superclasses'. That's too general to use in an
|
|
// assignment whose LHS demands an instance of Base, so we expect a
|
|
// static (parse-time) type-checking error.
|
|
|
|
// ERROR1: error: Value 'noCast' of type 'Base' is incompatible with initializer '!getop(orig)' of type '{}'
|
|
Base noCast = !getop(orig);
|
|
#endif
|
|
|
|
#ifdef ERROR2
|
|
// Here, we expect a _dynamic_ type error, when it turns out at
|
|
// evaluation time that the operator of 'another' is a record that
|
|
// isn't an instance of the specified base class.
|
|
|
|
// ERROR2: error: Expected type 'Base', got 'OtherBase' in: !getop((qux "hello", ?:$world))
|
|
Base badCast = !getop<Base>(another);
|
|
#endif
|
|
|
|
#ifdef ERROR3
|
|
// Obviously, you shouldn't be able to give any type to !getop that
|
|
// isn't a class type.
|
|
|
|
// ERROR3: error: type for !getop must be a record type
|
|
int ridiculousCast = !getop<int>(orig);
|
|
#endif
|
|
}
|