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

llvm-svn: 201045
This commit is contained in:
Benjamin Kramer 2014-02-09 16:22:00 +00:00
parent 8815574a16
commit dd9c671cdc
2 changed files with 40 additions and 9 deletions

View File

@ -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.

View File

@ -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