summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorSimon Tatham <simon.tatham@arm.com>2019-12-11 12:02:15 +0000
committerSimon Tatham <simon.tatham@arm.com>2019-12-11 12:05:22 +0000
commit1fed9a0c0c3e74c21dfbd1edf18411a33b742f52 (patch)
tree48690ac8255c77890878bbecb0cd72c83f88be0a /llvm/test
parentafb13afcf2232c81fe8097832e5b6a2bde6bb3a5 (diff)
downloadbcm5719-llvm-1fed9a0c0c3e74c21dfbd1edf18411a33b742f52.tar.gz
bcm5719-llvm-1fed9a0c0c3e74c21dfbd1edf18411a33b742f52.zip
[TableGen] Add bang-operators !getop and !setop.
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
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/TableGen/getsetop.td61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/test/TableGen/getsetop.td b/llvm/test/TableGen/getsetop.td
new file mode 100644
index 00000000000..81dc59d0622
--- /dev/null
+++ b/llvm/test/TableGen/getsetop.td
@@ -0,0 +1,61 @@
+// 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
+}
OpenPOWER on IntegriCloud