summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/AsmParser.cpp
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-02-17 00:40:17 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-02-17 00:40:17 +0000
commit696002f3b4612502d4140f28352c1427ef66a04c (patch)
tree412884808d7c0436c383b046351de8d3a56cea60 /lib/MC/MCParser/AsmParser.cpp
parent09d1d540c8f14761c88e8b53cafe465ed24132f6 (diff)
downloadllvm-696002f3b4612502d4140f28352c1427ef66a04c.tar.gz
llvm-696002f3b4612502d4140f28352c1427ef66a04c.tar.bz2
llvm-696002f3b4612502d4140f28352c1427ef66a04c.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201499 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp71
1 files changed, 56 insertions, 15 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 03b004ecfa..4f7734153a 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/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) {