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

David Greene greened at obbligato.org
Wed Oct 5 15:42:44 PDT 2011


Author: greened
Date: Wed Oct  5 17:42:44 2011
New Revision: 141232

URL: http://llvm.org/viewvc/llvm-project?rev=141232&view=rev
Log:
Parser Multidef Support

Add parser support to recognize multidefs.  No processing on the
multidef is done at this point.  The grammar is:

MultiDef = MULTIDEF ObjectName < Value, Declaration, Value > ObjectBody

The first Value must be resolveable to a list and the second Value
must be resolveable to an integer.  The Declaration is a temporary
value used as an iterator to refer to list items during processing.
It may be passed into the ObjectBody where it will be substituted with
the list value used to instantiate each def.

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

Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=141232&r1=141231&r2=141232&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed Oct  5 17:42:44 2011
@@ -1718,6 +1718,89 @@
 }
 
 
+/// ParseMultiDef - Parse and return a multiclass multidef, return the record
+/// corresponding to it.  This returns null on error.
+///
+///   MultiDefInst ::= MULTIDEF ObjectName '<' Value ',' Declaration ','
+///                                            Value '>' ObjectBody
+///
+bool TGParser::ParseMultiDef(MultiClass *CurMultiClass) {
+  assert(CurMultiClass && "No multiclass for multidef!");
+
+  SMLoc DefLoc = Lex.getLoc();
+  assert(Lex.getCode() == tgtok::MultiDef && "Unknown tok");
+  Lex.Lex();  // Eat the 'multidef' token.  
+
+  // Parse ObjectName and make a record for it.
+  Record *CurRec = new Record(ParseObjectName(), DefLoc, Records);
+  
+  if (Lex.getCode() != tgtok::less)
+    return TokError("multidef init requires a non-empty list of values");
+  Lex.Lex();  // Eat the '<'
+
+  Init *ListI = ParseValue(CurRec, 0);
+  if (ListI == 0)
+    return TokError("First multidef init must be of list type");
+
+  if (Lex.getCode() != tgtok::comma)
+    return TokError("expected comma in multidef");
+  Lex.Lex();  // Eat the comma
+
+  std::string ItemName = ParseDeclaration(CurRec, false/*Not a template arg*/);
+  if (ItemName.empty())
+    return TokError("expected declaration in multidef");
+
+  if (Lex.getCode() != tgtok::comma)
+    return TokError("expected comma in multidef");
+  Lex.Lex();  // Eat the comma
+
+  Init *IntI = ParseValue(CurRec, 0);
+  if (IntI == 0)
+    return TokError("expected integer value in multidef");
+
+  if (Lex.getCode() != tgtok::greater)
+    return TokError("multidef init requires a non-empty list of values");
+  Lex.Lex();  // Eat the '>'
+
+  TypedInit *List = dynamic_cast<TypedInit *>(ListI);
+  if (dynamic_cast<ListRecTy *>(List->getType()) == 0)
+    return TokError("First multidef init must be of list type");
+
+  IntInit *Int = dynamic_cast<IntInit *>(IntI);
+  if (Int == 0)
+    return TokError("Second multidef init must be a constant integer");
+
+  // Add it to the multiclass.
+  for (unsigned i = 0, e = CurMultiClass->MultiDefPrototypes.size();
+       i != e; ++i)
+    if (CurMultiClass->MultiDefPrototypes[i].Rec->getName()
+        == CurRec->getName())
+      return Error(DefLoc, "multidef '" + CurRec->getName() +
+                   "' already defined in this multiclass!");
+
+  CurMultiClass->MultiDefPrototypes.push_back(
+    MultiClass::MultiDef(CurRec, List, Int, ItemName));
+  
+  if (ParseObjectBody(CurRec))
+    return true;
+  
+  // If ObjectBody has template arguments, it's an error.
+  assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
+
+  // Copy the template arguments for the multiclass into the
+  // multidef.
+  const std::vector<std::string> &TArgs = CurMultiClass->Rec.getTemplateArgs();
+
+  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+    const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
+    assert(RV && "Template arg doesn't exist?");
+    CurRec->addValue(*RV);
+  }
+
+  return false;
+}
+
+
 /// ParseClass - Parse a tblgen class definition.
 ///
 ///   ClassInst ::= CLASS ID TemplateArgList? ObjectBody
@@ -1903,10 +1986,12 @@
     while (Lex.getCode() != tgtok::r_brace) {
       switch (Lex.getCode()) {
         default:
-          return TokError("expected 'let', 'def' or 'defm' in multiclass body");
+          return TokError("expected 'let', 'def', 'defm' or 'multidef'"
+                          "in multiclass body");
         case tgtok::Let:
         case tgtok::Def:
         case tgtok::Defm:
+        case tgtok::MultiDef:
           if (ParseObject(CurMultiClass))
             return true;
          break;
@@ -2153,6 +2238,7 @@
 /// ParseObject
 ///   Object ::= ClassInst
 ///   Object ::= DefInst
+///   Object ::= MultiDefInst
 ///   Object ::= MultiClassInst
 ///   Object ::= DefMInst
 ///   Object ::= LETCommand '{' ObjectList '}'
@@ -2163,6 +2249,7 @@
     return TokError("Expected class, def, defm, multiclass or let definition");
   case tgtok::Let:   return ParseTopLevelLet(MC);
   case tgtok::Def:   return ParseDef(MC);
+  case tgtok::MultiDef:   return ParseMultiDef(MC);
   case tgtok::Defm:  return ParseDefm(MC);
   case tgtok::Class: return ParseClass();
   case tgtok::MultiClass: return ParseMultiClass();

Modified: llvm/trunk/lib/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.h?rev=141232&r1=141231&r2=141232&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.h (original)
+++ llvm/trunk/lib/TableGen/TGParser.h Wed Oct  5 17:42:44 2011
@@ -100,6 +100,7 @@
                             SMLoc DefmPrefixLoc);
   bool ParseDefm(MultiClass *CurMultiClass);
   bool ParseDef(MultiClass *CurMultiClass);
+  bool ParseMultiDef(MultiClass *CurMultiClass);
   bool ParseTopLevelLet(MultiClass *CurMultiClass);
   std::vector<LetRecord> ParseLetList();
 





More information about the llvm-commits mailing list