Let the integrated assembler understand .exitm, PR20426.

llvm-svn: 213876
This commit is contained in:
Nico Weber 2014-07-24 17:08:39 +00:00
parent a9b498955c
commit 155dccd1eb
2 changed files with 104 additions and 8 deletions

View File

@ -92,8 +92,12 @@ struct MacroInstantiation {
/// The location where parsing should resume upon instantiation completion.
SMLoc ExitLoc;
/// The depth of TheCondStack at the start of the instantiation.
size_t CondStackDepth;
public:
MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I);
MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I,
size_t CondStackDepth);
};
struct ParseStatementInfo {
@ -351,7 +355,8 @@ private:
DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_MACROS_ON, DK_MACROS_OFF,
DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_SLEB128, DK_ULEB128,
DK_ERR, DK_ERROR, DK_WARNING,
DK_END
@ -403,6 +408,7 @@ private:
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
bool parseDirectiveExitMacro(StringRef Directive);
bool parseDirectiveEndMacro(StringRef Directive);
bool parseDirectiveMacro(SMLoc DirectiveLoc);
bool parseDirectiveMacrosOnOff(StringRef Directive);
@ -1541,6 +1547,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
return parseDirectiveMacrosOnOff(IDVal);
case DK_MACRO:
return parseDirectiveMacro(IDLoc);
case DK_EXITM:
return parseDirectiveExitMacro(IDVal);
case DK_ENDM:
case DK_ENDMACRO:
return parseDirectiveEndMacro(IDVal);
@ -1858,8 +1866,9 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
}
MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
MemoryBuffer *I)
: Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL) {}
MemoryBuffer *I, size_t CondStackDepth)
: Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
CondStackDepth(CondStackDepth) {}
static bool isOperator(AsmToken::TokenKind kind) {
switch (kind) {
@ -2122,8 +2131,9 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Create the macro instantiation object and add to the current macro
// instantiation stack.
MacroInstantiation *MI = new MacroInstantiation(
NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
MacroInstantiation *MI =
new MacroInstantiation(NameLoc, CurBuffer, getTok().getLoc(),
Instantiation, TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
@ -3471,6 +3481,26 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
"found in body which will have no effect");
}
/// parseDirectiveExitMacro
/// ::= .exitm
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Directive + "' directive");
if (!isInsideMacroInstantiation())
return TokError("unexpected '" + Directive + "' in file, "
"no current macro definition");
// Exit all conditionals that are active in the current macro.
while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
TheCondState = TheCondStack.back();
TheCondStack.pop_back();
}
handleMacroExit();
return false;
}
/// parseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
@ -4226,6 +4256,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
DirectiveKindMap[".exitm"] = DK_EXITM;
DirectiveKindMap[".endm"] = DK_ENDM;
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
DirectiveKindMap[".purgem"] = DK_PURGEM;
@ -4286,8 +4317,9 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
// Create the macro instantiation object and add to the current macro
// instantiation stack.
MacroInstantiation *MI = new MacroInstantiation(
DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
MacroInstantiation *MI =
new MacroInstantiation(DirectiveLoc, CurBuffer, getTok().getLoc(),
Instantiation, TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.

View File

@ -0,0 +1,64 @@
// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
// .exitm is encountered in a normal macro expansion
.macro REP
.rept 3
.long 0
.exitm
.endr
.endm
REP
// Only the output from the first rept expansion should make it through:
// CHECK: .long 0
// CHECK-NOT: .long 0
// .exitm is in a true branch
.macro A
.if 1
.long 1
.exitm
.endif
.long 1
.endm
A
// CHECK: .long 1
// CHECK-NOT: .long 1
// .exitm is in a false branch
.macro B
.if 1
.long 2
.else
.exitm
.endif
.long 2
.endm
B
// CHECK: .long 2
// CHECK: .long 2
// .exitm is in a false branch that is encountered prior to the true branch
.macro C
.if 0
.exitm
.else
.long 3
.endif
.long 3
.endm
C
// CHECK: .long 3
// CHECK: .long 3
// .exitm is in a macro that's expanded in a conditional block.
.macro D
.long 4
.exitm
.long 4
.endm
.if 1
D
.endif
// CHECK: .long 4
// CHECK-NOT: .long 4