diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index dc21c928edf4..c8fc4c02bc11 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1138,7 +1138,7 @@ bool AsmParser::ParseStatement() { return ParseDirectiveEndIf(IDLoc); // If we are in a ".if 0" block, ignore this statement. - if (TheCondState.Ignore && !ParsingInlineAsm) { + if (TheCondState.Ignore) { EatToEndOfStatement(); return false; } @@ -3579,7 +3579,8 @@ enum AsmOpRewriteKind { AOK_Imm, AOK_Input, AOK_Output, - AOK_SizeDirective + AOK_SizeDirective, + AOK_Skip }; struct AsmOpRewrite { @@ -3619,9 +3620,24 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, // Clear the opcode. setOpcode(~0x0); + // Save the conditional ignore state of the parser prior to parsing the statement. + bool PreParseCondStateIgnore = TheCondState.Ignore; + + // Save the starting point of this statement in case we need to skip it. + SMLoc Start = getLexer().getLoc(); + if (ParseStatement()) return true; + // If PreParseCondStateIgnore is false, but TheCondState.Ignore is true, then we + // just parsed a directive that changed the state to ignore. Don't skip + // emitting this directive. + if (PreParseCondStateIgnore && TheCondState.Ignore) { + unsigned Len = getLexer().getLoc().getPointer() - Start.getPointer(); + AsmStrRewrites.push_back(AsmOpRewrite(AOK_Skip, Start, Len)); + continue; + } + if (isInstruction()) { const MCInstrDesc &Desc = MII->get(getOpcode()); @@ -3727,8 +3743,15 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, OS << StringRef(Start, Loc - Start); PrevKind = Kind; + // Skip the original expression. + if (Kind == AOK_Skip) { + Start = Loc + (*I).Len; + continue; + } + // Rewrite expressions in $N notation. switch (Kind) { + default: break; case AOK_Imm: OS << Twine("$$") + StringRef(Loc, (*I).Len); break;