From 5fd01545238f23d044c8f899267c9fbece88c9ed Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Tue, 26 Sep 2006 23:45:08 +0000
Subject: [PATCH] Add support for ${:foo} syntax, where "foo" is passed into
 "printSpecial" and has no associated operand.  This is useful for portably
 encoding stuff like the comment character into an asm string.

llvm-svn: 30617
---
 llvm/utils/TableGen/AsmWriterEmitter.cpp | 39 +++++++++++++++---------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 2ea74494f24a..a67ee531a654 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -98,7 +98,9 @@ std::string AsmWriterOperand::getCode() const {
   if (OperandType == isLiteralTextOperand)
     return "O << \"" + Str + "\"; ";
 
-  std::string Result = Str + "(MI, " + utostr(MIOpNo);
+  std::string Result = Str + "(MI";
+  if (MIOpNo != ~0U)
+    Result += ", " + utostr(MIOpNo);
   if (!MiModifier.empty())
     Result += ", \"" + MiModifier + '"';
   return Result + "); ";
@@ -172,7 +174,8 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
                           AsmString.begin()+VarEnd);
 
       // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
-      // into printOperand.
+      // into printOperand.  Also support ${:feature}, which is passed into
+      // printSpecial.
       std::string Modifier;
       
       // In order to avoid starting the next string at the terminating curly
@@ -204,23 +207,29 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
                 + CGI.TheDef->getName() + "'";
         ++VarEnd;
       }
-      if (VarName.empty())
+      if (VarName.empty() && Modifier.empty())
         throw "Stray '$' in '" + CGI.TheDef->getName() +
               "' asm string, maybe you want $$?";
 
-      unsigned OpNo = CGI.getOperandNamed(VarName);
-      CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+      if (VarName.empty()) {
+        // Just a modifier, pass this into printSpecial.
+        Operands.push_back(AsmWriterOperand("printSpecial", ~0U, Modifier));
+      } else {
+        // Otherwise, normal operand.
+        unsigned OpNo = CGI.getOperandNamed(VarName);
+        CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
 
-      // If this is a two-address instruction, verify the second operand isn't
-      // used.
-      unsigned MIOp = OpInfo.MIOperandNo;
-      if (CGI.isTwoAddress && MIOp == 1)
-        throw "Should refer to operand #0 instead of #1 for two-address"
-              " instruction '" + CGI.TheDef->getName() + "'!";
-
-      if (CurVariant == Variant || CurVariant == ~0U) 
-        Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
-                                            Modifier));
+        // If this is a two-address instruction, verify the second operand isn't
+        // used.
+        unsigned MIOp = OpInfo.MIOperandNo;
+        if (CGI.isTwoAddress && MIOp == 1)
+          throw "Should refer to operand #0 instead of #1 for two-address"
+                " instruction '" + CGI.TheDef->getName() + "'!";
+        
+        if (CurVariant == Variant || CurVariant == ~0U) 
+          Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
+                                              Modifier));
+      }
       LastEmitted = VarEnd;
     }
   }