From 275f65330731378c7cca967c19fb988038064235 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 9 Feb 2014 16:22:00 +0000 Subject: AsmParser: Parse (and ignore) nested .macro definitions. This enables a slightly odd feature of gas. The macro is defined when the outermost macro is instantiated. PR18599 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201045 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCParser/AsmParser.cpp | 29 ++++++++++++++++++-------- test/MC/AsmParser/macro-def-in-instantiation.s | 20 ++++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 459e126793..1736e7703c 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -3183,6 +3183,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { Lex(); AsmToken EndToken, StartToken = getTok(); + unsigned MacroDepth = 0; // Lex the macro definition. for (;;) { @@ -3191,15 +3192,25 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { return Error(DirectiveLoc, "no matching '.endmacro' in definition"); // Otherwise, check whether we have reach the .endmacro. - if (getLexer().is(AsmToken::Identifier) && - (getTok().getIdentifier() == ".endm" || - getTok().getIdentifier() == ".endmacro")) { - EndToken = getTok(); - Lex(); - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in '" + EndToken.getIdentifier() + - "' directive"); - break; + if (getLexer().is(AsmToken::Identifier)) { + if (getTok().getIdentifier() == ".endm" || + getTok().getIdentifier() == ".endmacro") { + if (MacroDepth == 0) { // Outermost macro. + EndToken = getTok(); + Lex(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '" + EndToken.getIdentifier() + + "' directive"); + break; + } else { + // Otherwise we just found the end of an inner macro. + --MacroDepth; + } + } else if (getTok().getIdentifier() == ".macro") { + // We allow nested macros. Those aren't instantiated until the outermost + // macro is expanded so just ignore them for now. + ++MacroDepth; + } } // Otherwise, scan til the end of the statement. diff --git a/test/MC/AsmParser/macro-def-in-instantiation.s b/test/MC/AsmParser/macro-def-in-instantiation.s index b6483b3b32..773df701aa 100644 --- a/test/MC/AsmParser/macro-def-in-instantiation.s +++ b/test/MC/AsmParser/macro-def-in-instantiation.s @@ -11,3 +11,23 @@ $4 .data // CHECK: .byte 10 .mybyte 10 + +// PR18599 +.macro macro_a + +.macro macro_b +.byte 10 +.macro macro_c +.endm + +macro_c +.purgem macro_c +.endm + +macro_b +.endm + +macro_a +macro_b +// CHECK: .byte 10 +// CHECK: .byte 10 -- cgit v1.2.3