Add support for code fragments


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7440 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/FileLexer.l b/utils/TableGen/FileLexer.l
index 34a2818..a98a881 100644
--- a/utils/TableGen/FileLexer.l
+++ b/utils/TableGen/FileLexer.l
@@ -132,19 +132,21 @@
 
 %}
 
-Comment     \/\/.*
+Comment      \/\/.*
 
-Identifier  [a-zA-Z_][0-9a-zA-Z_]*
-Integer     [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+
-StringVal   \"[^"]*\"
-IncludeStr  include[ \t\n]+\"[^"]*\"
+Identifier   [a-zA-Z_][0-9a-zA-Z_]*
+Integer      [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+
+CodeFragment \[\{([^}]+|\}[^\]])*\}\]
+StringVal    \"[^"]*\"
+IncludeStr   include[ \t\n]+\"[^"]*\"
 
 %%
 
 {Comment}      { /* Ignore comments */ }
 
 {IncludeStr}   { HandleInclude(yytext); }
-
+{CodeFragment} { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2);
+                 return CODEFRAGMENT; }
 
 int            { return INT; }
 bit            { return BIT; }
diff --git a/utils/TableGen/FileParser.y b/utils/TableGen/FileParser.y
index e906a5e..d248242 100644
--- a/utils/TableGen/FileParser.y
+++ b/utils/TableGen/FileParser.y
@@ -155,7 +155,7 @@
 
 %token INT BIT STRING BITS LIST CODE CLASS DEF FIELD SET IN
 %token <IntVal>      INTVAL
-%token <StrVal>      ID STRVAL
+%token <StrVal>      ID STRVAL CODEFRAGMENT
 
 %type <Ty>           Type
 %type <RecPtr>       DefList DefListNE
@@ -217,6 +217,9 @@
   } | STRVAL {
     $$ = new StringInit(*$1);
     delete $1;
+  } | CODEFRAGMENT {
+    $$ = new CodeInit(*$1);
+    delete $1;
   } | '?' {
     $$ = new UnsetInit();
   } | '{' ValueList '}' {
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 308047a..3c07114 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -18,6 +18,7 @@
 class BitsInit;
 class IntInit;
 class StringInit;
+class CodeInit;
 class ListInit;
 class DefInit;
 class TypedInit;
@@ -39,6 +40,7 @@
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return 0; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue( TypedInit *TI) { return 0; }
@@ -135,6 +137,7 @@
 ///
 struct CodeRecTy : public RecTy {
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
+  Init *convertValue( CodeInit *CI) { return (Init*)CI; }
 
   void print(std::ostream &OS) const { OS << "code"; }
 };
@@ -321,6 +324,20 @@
   virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
 };
 
+/// CodeInit - "[{...}]" - Represent a code fragment.
+///
+class CodeInit : public Init {
+  std::string Value;
+public:
+  CodeInit(const std::string &V) : Value(V) {}
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; }
+};
+
 /// ListInit - [AL, AH, CL] - Represent a list of defs
 ///
 class ListInit : public Init {