aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
authorPreston Gurd <preston.gurd@intel.com>2012-09-19 20:29:04 +0000
committerPreston Gurd <preston.gurd@intel.com>2012-09-19 20:29:04 +0000
commit6c9176aeec549adb4bbdd499664c4304ee151f68 (patch)
tree46009b02bf6d6270da5af9b68e82b81aa2cad3a6 /lib/MC/MCParser
parent6579eea90dfeb7540e37307cc30c8677759c5e4d (diff)
downloadexternal_llvm-6c9176aeec549adb4bbdd499664c4304ee151f68.zip
external_llvm-6c9176aeec549adb4bbdd499664c4304ee151f68.tar.gz
external_llvm-6c9176aeec549adb4bbdd499664c4304ee151f68.tar.bz2
Support default parameters/arguments for assembler macros.
This patch is based on the one by PaX Team. Patch by Andy Zhang! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164246 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index ca338ab..266d87e 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -47,7 +47,7 @@ namespace {
/// \brief Helper class for tracking macro definitions.
typedef std::vector<AsmToken> MacroArgument;
typedef std::vector<MacroArgument> MacroArguments;
-typedef StringRef MacroParameter;
+typedef std::pair<StringRef, MacroArgument> MacroParameter;
typedef std::vector<MacroParameter> MacroParameters;
struct Macro {
@@ -1534,7 +1534,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
StringRef Argument(Begin, I - (Pos +1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
- if (Parameters[Index] == Argument)
+ if (Parameters[Index].first == Argument)
break;
// FIXME: We should error at the macro definition.
@@ -1606,10 +1606,27 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
if (ParseMacroArgument(MA))
return true;
- A.push_back(MA);
+ if (!MA.empty() || !NParameters)
+ A.push_back(MA);
+ else if (NParameters) {
+ if (!M->Parameters[Parameter].second.empty())
+ A.push_back(M->Parameters[Parameter].second);
+ }
- if (Lexer.is(AsmToken::EndOfStatement))
+ // 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) {
+ if (M->Parameters[Parameter + 1].second.empty())
+ return TokError("macro argument '" +
+ Twine(M->Parameters[Parameter + 1].first) +
+ "' is missing");
+ else
+ continue;
+ }
return false;
+ }
if (Lexer.is(AsmToken::Comma))
Lex();
@@ -3091,8 +3108,15 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
MacroParameter Parameter;
- if (getParser().ParseIdentifier(Parameter))
+ if (getParser().ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.macro' directive");
+
+ if (getLexer().is(AsmToken::Equal)) {
+ Lex();
+ if (getParser().ParseMacroArgument(Parameter.second))
+ return true;
+ }
+
Parameters.push_back(Parameter);
if (getLexer().isNot(AsmToken::Comma))
@@ -3308,7 +3332,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
- if (ParseIdentifier(Parameter))
+ if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irp' directive");
Parameters.push_back(Parameter);
@@ -3354,7 +3378,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
- if (ParseIdentifier(Parameter))
+ if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irpc' directive");
Parameters.push_back(Parameter);