summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp71
-rw-r--r--llvm/test/MC/AsmParser/macro-err1.s2
-rw-r--r--llvm/test/MC/AsmParser/macros-argument-parsing-diagnostics.s24
-rw-r--r--llvm/test/MC/AsmParser/macros-argument-parsing.s51
4 files changed, 132 insertions, 16 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 03b004ecfac..4f7734153ac 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1937,39 +1937,80 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
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 (parseMacroArgument(MA))
+ if (!Lexer.is(AsmToken::Equal)) {
+ TokError("expected '=' after formal parameter identifier");
+ eatToEndOfStatement();
+ return true;
+ }
+ Lex();
+
+ NamedParametersFound = true;
+ }
+
+ if (NamedParametersFound && FA.first.empty()) {
+ Error(Lexer.getLoc(), "cannot mix positional and keyword arguments");
+ eatToEndOfStatement();
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);
+ if (parseMacroArgument(FA.second))
+ return true;
+
+ 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) {
diff --git a/llvm/test/MC/AsmParser/macro-err1.s b/llvm/test/MC/AsmParser/macro-err1.s
index 924deb0cf6e..bd9c837d8be 100644
--- a/llvm/test/MC/AsmParser/macro-err1.s
+++ b/llvm/test/MC/AsmParser/macro-err1.s
@@ -7,4 +7,4 @@
foo 42, 42
-// CHECK: Too many arguments
+// CHECK: too many positional arguments
diff --git a/llvm/test/MC/AsmParser/macros-argument-parsing-diagnostics.s b/llvm/test/MC/AsmParser/macros-argument-parsing-diagnostics.s
new file mode 100644
index 00000000000..a1970e0c9d5
--- /dev/null
+++ b/llvm/test/MC/AsmParser/macros-argument-parsing-diagnostics.s
@@ -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: ^
+
diff --git a/llvm/test/MC/AsmParser/macros-argument-parsing.s b/llvm/test/MC/AsmParser/macros-argument-parsing.s
index 097a2702a06..11da298e00e 100644
--- a/llvm/test/MC/AsmParser/macros-argument-parsing.s
+++ b/llvm/test/MC/AsmParser/macros-argument-parsing.s
@@ -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
+
OpenPOWER on IntegriCloud