[llvm-commits] [llvm] r142525 - in /llvm/trunk/lib/TableGen: TGLexer.cpp TGLexer.h TGParser.cpp

David Greene greened at obbligato.org
Wed Oct 19 06:04:43 PDT 2011


Author: greened
Date: Wed Oct 19 08:04:43 2011
New Revision: 142525

URL: http://llvm.org/viewvc/llvm-project?rev=142525&view=rev
Log:
Implement Paste

Add a paste operator '#' to take two identifier-like strings and joint
them.  Internally paste gets represented as a !strconcat() with any
necessary casts to string added.

This will be used to implement basic for loop functionality as in:

for i = [0, 1, 2, 3, 4, 5, 6, 7] {
  def R#i : Register<...>
}

Modified:
    llvm/trunk/lib/TableGen/TGLexer.cpp
    llvm/trunk/lib/TableGen/TGLexer.h
    llvm/trunk/lib/TableGen/TGParser.cpp

Modified: llvm/trunk/lib/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.cpp?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/lib/TableGen/TGLexer.cpp Wed Oct 19 08:04:43 2011
@@ -91,10 +91,10 @@
 
   switch (CurChar) {
   default:
-    // Handle letters: [a-zA-Z_#]
-    if (isalpha(CurChar) || CurChar == '_' || CurChar == '#')
+    // Handle letters: [a-zA-Z_]
+    if (isalpha(CurChar) || CurChar == '_')
       return LexIdentifier();
-      
+
     // Unknown character, emit an error.
     return ReturnError(TokStart, "Unexpected character");
   case EOF: return tgtok::Eof;
@@ -111,6 +111,7 @@
   case ')': return tgtok::r_paren;
   case '=': return tgtok::equal;
   case '?': return tgtok::question;
+  case '#': return tgtok::paste;
       
   case 0:
   case ' ':
@@ -250,8 +251,7 @@
   const char *IdentStart = TokStart;
 
   // Match the rest of the identifier regex: [0-9a-zA-Z_#]*
-  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' ||
-         *CurPtr == '#')
+  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
     ++CurPtr;
 
   // Check to see if this identifier is a keyword.

Modified: llvm/trunk/lib/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.h?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.h (original)
+++ llvm/trunk/lib/TableGen/TGLexer.h Wed Oct 19 08:04:43 2011
@@ -39,7 +39,8 @@
     colon, semi,        // : ;
     comma, period,      // , .
     equal, question,    // = ?
-    
+    paste,              // #
+
     // Keywords.
     Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
     MultiClass, String,

Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed Oct 19 08:04:43 2011
@@ -1083,6 +1083,12 @@
   Init *R = 0;
   switch (Lex.getCode()) {
   default: TokError("Unknown token when parsing a value"); break;
+  case tgtok::paste:
+    // This is a leading paste operation.  This is deprecated but
+    // still exists in some .td files.  Ignore it.
+    Lex.Lex();  // Skip '#'.
+    return ParseSimpleValue(CurRec, ItemType, Mode);
+    break;
   case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break;
   case tgtok::StrVal: {
     std::string Val = Lex.getCurStrVal();
@@ -1410,6 +1416,56 @@
       Result = FieldInit::get(Result, Lex.getCurStrVal());
       Lex.Lex();  // eat field name
       break;
+
+    case tgtok::paste:
+      SMLoc PasteLoc = Lex.getLoc();
+
+      // Create a !strconcat() operation, first casting each operand to
+      // a string if necessary.
+
+      TypedInit *LHS = dynamic_cast<TypedInit *>(Result);
+      if (!LHS) {
+        Error(PasteLoc, "LHS of paste is not typed!");
+        return 0;
+      }
+  
+      if (LHS->getType() != StringRecTy::get()) {
+        LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get());
+      }
+
+      TypedInit *RHS = 0;
+
+      Lex.Lex();  // Eat the '#'.
+      switch (Lex.getCode()) { 
+      case tgtok::colon:
+      case tgtok::semi:
+      case tgtok::l_brace:
+        // These are all of the tokens that can begin an object body.
+        // Some of these can also begin values but we disallow those cases
+        // because they are unlikely to be useful.
+       
+        // Trailing paste, concat with an empty string.
+        RHS = StringInit::get("");
+        break;
+
+      default:
+        Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode);
+        RHS = dynamic_cast<TypedInit *>(RHSResult);
+        if (!RHS) {
+          Error(PasteLoc, "RHS of paste is not typed!");
+          return 0;
+        }
+
+        if (RHS->getType() != StringRecTy::get()) {
+          RHS = UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get());
+        }
+  
+        break;
+      }
+
+      Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS,
+                              StringRecTy::get())->Fold(CurRec, CurMultiClass);
+      break;
     }
   }
 }
@@ -1979,41 +2035,23 @@
   // instantiated def a unique name.  Otherwise, if "#NAME#" exists in the
   // name, substitute the prefix for #NAME#.  Otherwise, use the defm name
   // as a prefix.
-  StringInit *DefNameString =
-    dynamic_cast<StringInit *>(DefProto->getNameInit());
-
-  if (DefNameString == 0) {
-    Error(DefmPrefixLoc, "Def name is not a string");
-    return 0;
-  }
 
   if (DefmPrefix == 0)
     DefmPrefix = StringInit::get(GetNewAnonymousName());
 
   Init *DefName = DefProto->getNameInit();
 
-  // See if we can substitute #NAME#.
-  Init *NewDefName =
-    TernOpInit::get(TernOpInit::SUBST,
-                    StringInit::get("#NAME#"),
-                    DefmPrefix,
-                    DefName,
-                    StringRecTy::get())->Fold(DefProto, &MC);
-
-  if (NewDefName == DefName) {
-    // We did't do any substitution.  We should concatenate the given
-    // prefix and name.
-    if (DefmPrefix == 0)
-      DefmPrefix = StringInit::get(GetNewAnonymousName());
+  StringInit *DefNameString = dynamic_cast<StringInit *>(DefName);
 
+  if (DefNameString != 0) {
+    // We have a fully expanded string so there are no operators to
+    // resolve.  We should concatenate the given prefix and name.
     DefName =
       BinOpInit::get(BinOpInit::STRCONCAT,
                      UnOpInit::get(UnOpInit::CAST, DefmPrefix,
                                    StringRecTy::get())->Fold(DefProto, &MC),
                      DefName, StringRecTy::get())->Fold(DefProto, &MC);
   }
-  else
-    DefName = NewDefName;
 
   Record *CurRec = new Record(DefName, DefmPrefixLoc, Records);
 





More information about the llvm-commits mailing list