[llvm] r201499 - MCAsmParser: better handling for named arguments

Saleem Abdulrasool compnerd at compnerd.org
Sun Feb 16 16:40:18 PST 2014


Author: compnerd
Date: Sun Feb 16 18:40:17 2014
New Revision: 201499

URL: http://llvm.org/viewvc/llvm-project?rev=201499&view=rev
Log:
MCAsmParser: better handling for named arguments

Until this point only macro definition with named parameters were parsed but the
names were ignored.  This adds support for using that information for named
parameter instantiation.

In order to support the full semantics of the keyword arguments, the arguments
are no longer lazily initialised since the keyword arguments can be specified
out of order and partially if they are defaulted.  Prepopulate the arguments
with the default value for any defaulted parameters, and then parse the
specified arguments.

This simplies some of the handling of the arguments in the inner loop since
empty arguments simply increment the parameter index and move on.

Note that keyword and positional arguments cannot be mixed.

Added:
    llvm/trunk/test/MC/AsmParser/macros-argument-parsing-diagnostics.s
Modified:
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/test/MC/AsmParser/macro-err1.s
    llvm/trunk/test/MC/AsmParser/macros-argument-parsing.s

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=201499&r1=201498&r2=201499&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sun Feb 16 18:40:17 2014
@@ -1937,39 +1937,80 @@ bool AsmParser::parseMacroArguments(cons
                                     MCAsmMacroArguments &A) {
   const unsigned NParameters = M ? M->Parameters.size() : 0;
 
+  A.resize(NParameters);
+  for (unsigned PI = 0; PI < NParameters; ++PI)
+    if (!M->Parameters[PI].second.empty())
+      A[PI] = M->Parameters[PI].second;
+
+  bool NamedParametersFound = false;
+
   // Parse two kinds of macro invocations:
   // - macros defined without any parameters accept an arbitrary number of them
   // - macros defined with parameters accept at most that many of them
   for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
        ++Parameter) {
-    MCAsmMacroArgument MA;
+    MCAsmMacroParameter FA;
+    SMLoc L;
+
+    if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
+      L = Lexer.getLoc();
+      if (parseIdentifier(FA.first)) {
+        Error(L, "invalid argument identifier for formal argument");
+        eatToEndOfStatement();
+        return true;
+      }
+
+      if (!Lexer.is(AsmToken::Equal)) {
+        TokError("expected '=' after formal parameter identifier");
+        eatToEndOfStatement();
+        return true;
+      }
+      Lex();
+
+      NamedParametersFound = true;
+    }
 
-    if (parseMacroArgument(MA))
+    if (NamedParametersFound && FA.first.empty()) {
+      Error(Lexer.getLoc(), "cannot mix positional and keyword arguments");
+      eatToEndOfStatement();
+      return true;
+    }
+
+    if (parseMacroArgument(FA.second))
       return true;
 
-    if (!MA.empty() || (!NParameters && !Lexer.is(AsmToken::EndOfStatement)))
-      A.push_back(MA);
-    else if (NParameters) {
-      if (!M->Parameters[Parameter].second.empty())
-        A.push_back(M->Parameters[Parameter].second);
-      else
-        A.push_back(MA);
+    unsigned PI = Parameter;
+    if (!FA.first.empty()) {
+      unsigned FAI = 0;
+      for (FAI = 0; FAI < NParameters; ++FAI)
+        if (M->Parameters[FAI].first == FA.first)
+          break;
+      if (FAI >= NParameters) {
+        Error(L,
+              "parameter named '" + FA.first + "' does not exist for macro '" +
+              M->Name + "'");
+        return true;
+      }
+      PI = FAI;
+    }
+
+    if (!FA.second.empty()) {
+      if (A.size() <= PI)
+        A.resize(PI + 1);
+      A[PI] = FA.second;
     }
 
     // At the end of the statement, fill in remaining arguments that have
     // default values. If there aren't any, then the next argument is
     // required but missing
-    if (Lexer.is(AsmToken::EndOfStatement)) {
-      if (NParameters && Parameter < NParameters - 1) {
-        continue;
-      }
+    if (Lexer.is(AsmToken::EndOfStatement))
       return false;
-    }
 
     if (Lexer.is(AsmToken::Comma))
       Lex();
   }
-  return TokError("Too many arguments");
+
+  return TokError("too many positional arguments");
 }
 
 const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) {

Modified: llvm/trunk/test/MC/AsmParser/macro-err1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-err1.s?rev=201499&r1=201498&r2=201499&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-err1.s (original)
+++ llvm/trunk/test/MC/AsmParser/macro-err1.s Sun Feb 16 18:40:17 2014
@@ -7,4 +7,4 @@
 
 foo 42,  42
 
-// CHECK: Too many arguments
+// CHECK: too many positional arguments

Added: llvm/trunk/test/MC/AsmParser/macros-argument-parsing-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macros-argument-parsing-diagnostics.s?rev=201499&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macros-argument-parsing-diagnostics.s (added)
+++ llvm/trunk/test/MC/AsmParser/macros-argument-parsing-diagnostics.s Sun Feb 16 18:40:17 2014
@@ -0,0 +1,24 @@
+# RUN: not llvm-mc -triple i386 -filetype asm -o /dev/null %s 2>&1 | FileCheck %s
+
+	.macro double first = -1, second = -1
+		# begin entry
+		.long \first
+		.long \second
+		# end entry
+	.endm
+
+	double 0, 1, 2
+# CHECK: error: too many positional arguments
+# CHECK: 	double 0, 1, 2
+# CHECK:                     ^
+
+	double second = 1, 2
+# CHECK: error: cannot mix positional and keyword arguments
+# CHECK: 	double second = 1, 2
+# CHECK:                           ^
+
+	double third = 0
+# CHECK: error: parameter named 'third' does not exist for macro 'double'
+# CHECK: 	double third = 0
+# CHECK:               ^
+

Modified: llvm/trunk/test/MC/AsmParser/macros-argument-parsing.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macros-argument-parsing.s?rev=201499&r1=201498&r2=201499&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macros-argument-parsing.s (original)
+++ llvm/trunk/test/MC/AsmParser/macros-argument-parsing.s Sun Feb 16 18:40:17 2014
@@ -8,3 +8,54 @@
 
 # CHECK: .long 1
 
+	.macro double first = -1, second = -1
+		# begin entry
+		.long \first
+		.long \second
+		# end entry
+	.endm
+
+	double
+# CHECK: .long -1
+# CHECK: .long -1
+
+	double 1
+# CHECK: .long 1
+# CHECK: .long -1
+
+	double 2, 3
+# CHECK: .long 2
+# CHECK: .long 3
+
+	double , 4
+# CHECK: .long -1
+# CHECK: .long 4
+
+	double 5, second = 6
+# CHECK: .long 5
+# CHECK: .long 6
+
+	double first = 7
+# CHECK: .long 7
+# CHECK: .long -1
+
+	double second = 8
+# CHECK: .long -1
+# CHECK: .long 8
+
+	double second = 9, first = 10
+# CHECK: .long 10
+# CHECK: .long 9
+
+	double second + 11
+# CHECK: .long second+11
+# CHECK: .long -1
+
+	double , second + 12
+# CHECK: .long -1
+# CHECK: .long second+12
+
+	double second
+# CHECK: .long second
+# CHECK: .long -1
+





More information about the llvm-commits mailing list