[PATCH] D40782: [tablegen] Add !codeconcat operator which works like !strconcat

Johannes Altmanninger via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 18 00:55:09 PST 2017


johannes updated this revision to Diff 127306.
johannes added a comment.

remove codeconcat, make strconcat return code if all arguments are


https://reviews.llvm.org/D40782

Files:
  docs/TableGen/LangIntro.rst
  lib/TableGen/Record.cpp
  test/TableGen/strconcat.td


Index: test/TableGen/strconcat.td
===================================================================
--- test/TableGen/strconcat.td
+++ test/TableGen/strconcat.td
@@ -1,24 +1,28 @@
 // RUN: llvm-tblgen %s | FileCheck %s
 
-// CHECK: class Y<string Y:S = ?> {
+// CHECK: class Y<string Y:S = ?, code Y:C = ?> {
 // CHECK:   string T = !strconcat(Y:S, "foo");
 // CHECK:   string T2 = !strconcat(Y:S, !strconcat("foo", !strconcat(Y:S, "bar")));
 // CHECK:   string S = "foobar";
+// CHECK:   code T3 = !strconcat(Y:C, [{ ; }]);
 // CHECK: }
 
 // CHECK: def Z {
 // CHECK:   string T = "fufoo";
 // CHECK:   string T2 = "fufoofubar";
 // CHECK:   string S = "foobar";
+// CHECK:   code T3 = [{ 1 ; }];
 // CHECK: }
 
-class Y<string S> {
+class Y<string S, code C> {
   string T = !strconcat(S, "foo");
   // More than two arguments is equivalent to nested calls
   string T2 = !strconcat(S, "foo", S, "bar");
 
   // String values concatenate lexically, as in C.
   string S = "foo" "bar";
+
+  code T3 = !strconcat(C, [{ ; }]);
 }
 
-def Z : Y<"fu">;
+def Z : Y<"fu", [{ 1 }]>;
Index: lib/TableGen/Record.cpp
===================================================================
--- lib/TableGen/Record.cpp
+++ lib/TableGen/Record.cpp
@@ -763,11 +763,10 @@
   ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
 }
 
-static StringInit *ConcatStringInits(const StringInit *I0,
-                                     const StringInit *I1) {
+template <class T> static T *ConcatStringLikeInits(const T *I0, const T *I1) {
   SmallString<80> Concat(I0->getValue());
   Concat.append(I1->getValue());
-  return StringInit::get(Concat);
+  return T::get(Concat);
 }
 
 Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
@@ -807,10 +806,14 @@
     break;
   }
   case STRCONCAT: {
+    CodeInit *LHSc = dyn_cast<CodeInit>(LHS);
+    CodeInit *RHSc = dyn_cast<CodeInit>(RHS);
+    if (LHSc && RHSc)
+      return ConcatStringLikeInits(LHSc, RHSc);
     StringInit *LHSs = dyn_cast<StringInit>(LHS);
     StringInit *RHSs = dyn_cast<StringInit>(RHS);
     if (LHSs && RHSs)
-      return ConcatStringInits(LHSs, RHSs);
+      return ConcatStringLikeInits(LHSs, RHSs);
     break;
   }
   case EQ: {
@@ -1896,7 +1899,7 @@
   // Shortcut for the common case of concatenating two strings.
   if (const StringInit *I0s = dyn_cast<StringInit>(I0))
     if (const StringInit *I1s = dyn_cast<StringInit>(I1))
-      return ConcatStringInits(I0s, I1s);
+      return ConcatStringLikeInits(I0s, I1s);
   return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get());
 }
 
Index: docs/TableGen/LangIntro.rst
===================================================================
--- docs/TableGen/LangIntro.rst
+++ docs/TableGen/LangIntro.rst
@@ -174,7 +174,8 @@
 ``!strconcat(a, b, ...)``
     A string value that is the result of concatenating the 'a' and 'b' strings.
     More than two arguments are accepted with the result being the concatenation
-    of all the strings given.
+    of all the strings given. If all arguments are code fragments, then so is
+    the return value.
 
 ``str1#str2``
     "#" (paste) is a shorthand for !strconcat.  It may concatenate things that


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40782.127306.patch
Type: text/x-patch
Size: 3206 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171218/e3d1727d/attachment-0001.bin>


More information about the llvm-commits mailing list