[llvm] r201630 - MCAsmParser: support required parameters

Saleem Abdulrasool compnerd at compnerd.org
Tue Feb 18 19:00:29 PST 2014


Author: compnerd
Date: Tue Feb 18 21:00:29 2014
New Revision: 201630

URL: http://llvm.org/viewvc/llvm-project?rev=201630&view=rev
Log:
MCAsmParser: support required parameters

This enhances the macro parser to parse and handle parameter qualifications,
which is needed to support required formal parameters in macro definitions.  A
required parameter may not be defaulted (though providing a default value is
accepted with a warning).  This improves GAS compatibility.

Partially addresses PR9248.

Added:
    llvm/trunk/test/MC/AsmParser/macro-qualifier-diagnostics.s
    llvm/trunk/test/MC/AsmParser/macro-qualifier.s
Modified:
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=201630&r1=201629&r2=201630&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Feb 18 21:00:29 2014
@@ -58,6 +58,9 @@ typedef std::vector<MCAsmMacroArgument>
 struct MCAsmMacroParameter {
   StringRef Name;
   MCAsmMacroArgument Value;
+  bool Required;
+
+  MCAsmMacroParameter() : Required(false) { }
 };
 
 typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
@@ -1940,26 +1943,23 @@ bool AsmParser::parseMacroArgument(MCAsm
 bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
                                     MCAsmMacroArguments &A) {
   const unsigned NParameters = M ? M->Parameters.size() : 0;
+  bool NamedParametersFound = false;
+  SmallVector<SMLoc, 4> FALocs;
 
   A.resize(NParameters);
-  for (unsigned PI = 0; PI < NParameters; ++PI)
-    if (!M->Parameters[PI].Value.empty())
-      A[PI] = M->Parameters[PI].Value;
-
-  bool NamedParametersFound = false;
+  FALocs.resize(NParameters);
 
   // 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) {
+    SMLoc IDLoc = Lexer.getLoc();
     MCAsmMacroParameter FA;
-    SMLoc L;
 
     if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
-      L = Lexer.getLoc();
       if (parseIdentifier(FA.Name)) {
-        Error(L, "invalid argument identifier for formal argument");
+        Error(IDLoc, "invalid argument identifier for formal argument");
         eatToEndOfStatement();
         return true;
       }
@@ -1975,7 +1975,7 @@ bool AsmParser::parseMacroArguments(cons
     }
 
     if (NamedParametersFound && FA.Name.empty()) {
-      Error(Lexer.getLoc(), "cannot mix positional and keyword arguments");
+      Error(IDLoc, "cannot mix positional and keyword arguments");
       eatToEndOfStatement();
       return true;
     }
@@ -1989,8 +1989,9 @@ bool AsmParser::parseMacroArguments(cons
       for (FAI = 0; FAI < NParameters; ++FAI)
         if (M->Parameters[FAI].Name == FA.Name)
           break;
+
       if (FAI >= NParameters) {
-        Error(L,
+        Error(IDLoc,
               "parameter named '" + FA.Name + "' does not exist for macro '" +
               M->Name + "'");
         return true;
@@ -2002,13 +2003,33 @@ bool AsmParser::parseMacroArguments(cons
       if (A.size() <= PI)
         A.resize(PI + 1);
       A[PI] = FA.Value;
+
+      if (FALocs.size() <= PI)
+        FALocs.resize(PI + 1);
+
+      FALocs[PI] = Lexer.getLoc();
     }
 
     // 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))
-      return false;
+    if (Lexer.is(AsmToken::EndOfStatement)) {
+      bool Failure = false;
+      for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
+        if (A[FAI].empty()) {
+          if (M->Parameters[FAI].Required) {
+            Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
+                  "missing value for required parameter "
+                  "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
+            Failure = true;
+          }
+
+          if (!M->Parameters[FAI].Value.empty())
+            A[FAI] = M->Parameters[FAI].Value;
+        }
+      }
+      return Failure;
+    }
 
     if (Lexer.is(AsmToken::Comma))
       Lex();
@@ -3210,10 +3231,36 @@ bool AsmParser::parseDirectiveMacro(SMLo
     if (parseIdentifier(Parameter.Name))
       return TokError("expected identifier in '.macro' directive");
 
+    if (Lexer.is(AsmToken::Colon)) {
+      Lex();  // consume ':'
+
+      SMLoc QualLoc;
+      StringRef Qualifier;
+
+      QualLoc = Lexer.getLoc();
+      if (parseIdentifier(Qualifier))
+        return Error(QualLoc, "missing parameter qualifier for "
+                     "'" + Parameter.Name + "' in macro '" + Name + "'");
+
+      if (Qualifier == "req")
+        Parameter.Required = true;
+      else
+        return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
+                     "for '" + Parameter.Name + "' in macro '" + Name + "'");
+    }
+
     if (getLexer().is(AsmToken::Equal)) {
       Lex();
+
+      SMLoc ParamLoc;
+
+      ParamLoc = Lexer.getLoc();
       if (parseMacroArgument(Parameter.Value))
         return true;
+
+      if (Parameter.Required)
+        Warning(ParamLoc, "pointless default value for required parameter "
+                "'" + Parameter.Name + "' in macro '" + Name + "'");
     }
 
     Parameters.push_back(Parameter);

Added: llvm/trunk/test/MC/AsmParser/macro-qualifier-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-qualifier-diagnostics.s?rev=201630&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-qualifier-diagnostics.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-qualifier-diagnostics.s Tue Feb 18 21:00:29 2014
@@ -0,0 +1,64 @@
+# RUN: not llvm-mc -triple i386 -o /dev/null %s 2>&1 | FileCheck %s
+
+	.macro missing_qualifier parameter:
+
+# CHECK: error: missing parameter qualifier for 'parameter' in macro 'missing_qualifier'
+# CHECK: 	.macro missing_qualifier parameter:
+# CHECK:                                           ^
+
+	.macro non_identifier_qualifier parameter:0
+
+# CHECK: error: missing parameter qualifier for 'parameter' in macro 'non_identifier_qualifier'
+# CHECK: 	.macro non_identifier_qualifier parameter:0
+# CHECK:                                                  ^
+
+	.macro invalid_qualifier parameter:invalid_qualifier
+
+# CHECK: error: invalid_qualifier is not a valid parameter qualifier for 'parameter' in macro 'invalid_qualifier'
+# CHECK: 	.macro invalid_qualifier parameter:invalid_qualifier
+# CHECK:                                           ^
+
+	.macro pointless_default parameter:req=default
+	.endm
+
+# CHECK: warning: pointless default value for required parameter 'parameter' in macro 'pointless_default'
+# CHECK: 	.macro pointless_default parameter:req=default
+# CHECK:                                               ^
+
+	.macro missing_required_parameter parameter:req
+	.endm
+
+	missing_required_parameter
+
+# CHECK: error: missing value for required parameter 'parameter' in macro 'missing_required_parameter'
+# CHECK: 	missing_required_parameter
+# CHECK:                                  ^
+
+	.macro missing_second_required_argument first=0 second:req
+	.endm
+
+	missing_second_required_argument
+
+# CHECK: error: missing value for required parameter 'second' in macro 'missing_second_required_argument'
+# CHECK: 	missing_second_required_argument
+# CHECK:                                        ^
+
+	.macro second_third_required first=0 second:req third:req
+	.endm
+
+	second_third_required 0
+
+# CHECK: error: missing value for required parameter 'second' in macro 'second_third_required'
+# CHECK: 	second_third_required 0
+# CHECK:                               ^
+
+# CHECK: error: missing value for required parameter 'third' in macro 'second_third_required'
+# CHECK: 	second_third_required 0
+# CHECK:                               ^
+
+	second_third_required third=3 first=1
+
+# CHECK: error: missing value for required parameter 'second' in macro 'second_third_required'
+# CHECK: 	second_third_required third=3 first=1
+# CHECK:                                             ^
+

Added: llvm/trunk/test/MC/AsmParser/macro-qualifier.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-qualifier.s?rev=201630&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-qualifier.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-qualifier.s Tue Feb 18 21:00:29 2014
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -triple i386 -o - %s | FileCheck %s
+
+	.macro required parameter:req
+		.long \parameter
+	.endm
+
+	required 0
+# CHECK: .long 0
+
+	.macro required_with_default parameter:req=0
+		.long \parameter
+	.endm
+
+	required 1
+# CHECK: .long 1
+





More information about the llvm-commits mailing list