From 6c9176aeec549adb4bbdd499664c4304ee151f68 Mon Sep 17 00:00:00 2001 From: Preston Gurd Date: Wed, 19 Sep 2012 20:29:04 +0000 Subject: [PATCH] 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 --- lib/MC/MCParser/AsmParser.cpp | 38 +++++++++++++++++++++++++++++++------- test/MC/AsmParser/macro-args.s | 12 ++++++++++-- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index ca338abed4e..266d87e1490 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 MacroArgument; typedef std::vector MacroArguments; -typedef StringRef MacroParameter; +typedef std::pair MacroParameter; typedef std::vector 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); diff --git a/test/MC/AsmParser/macro-args.s b/test/MC/AsmParser/macro-args.s index 6d084213e40..3269369be02 100644 --- a/test/MC/AsmParser/macro-args.s +++ b/test/MC/AsmParser/macro-args.s @@ -4,10 +4,18 @@ movl \var@GOTOFF(%ebx),\re2g .endm +.macro GET_DEFAULT var, re2g=%ebx, re3g=%ecx +movl 2(\re2g, \re3g, 2), \var +.endm + +GET is_sse, %eax +// CHECK: movl is_sse@GOTOFF(%ebx), %eax -GET is_sse, %eax +GET_DEFAULT %ebx, , %edx +// CHECK: movl 2(%ebx,%edx,2), %ebx -// CHECK: movl is_sse@GOTOFF(%ebx), %eax +GET_DEFAULT %ebx, %edx +// CHECK: movl 2(%edx,%ecx,2), %ebx .macro bar .long $n -- 2.11.0