Index: llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h =================================================================== --- llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -40,6 +40,7 @@ AOK_Output, // Rewrite in terms of $N. AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). AOK_Label, // Rewrite local labels. + AOK_EndOfStatement, // Add EndOfStatement (e.g., "\n\t"). AOK_Skip // Skip emission (e.g., offset/type operators). }; @@ -55,6 +56,7 @@ 3, // AOK_Output 5, // AOK_SizeDirective 1, // AOK_Label + 5, // AOK_EndOfStatement 2 // AOK_Skip }; Index: llvm/trunk/lib/MC/MCParser/AsmParser.cpp =================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp @@ -251,6 +251,7 @@ bool parseStatement(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI); + bool parseCurlyBlockScope(SmallVectorImpl& AsmStrRewrites); void eatToEndOfLine(); bool parseCppHashLineFilenameComment(SMLoc L); @@ -1820,6 +1821,24 @@ return false; } +// Parse and erase curly braces marking block start/end +bool +AsmParser::parseCurlyBlockScope(SmallVectorImpl &AsmStrRewrites) { + // Identify curly brace marking block start/end + if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly)) + return false; + + SMLoc StartLoc = Lexer.getLoc(); + Lex(); // Eat the brace + if (Lexer.is(AsmToken::EndOfStatement)) + Lex(); // Eat EndOfStatement following the brace + + // Erase the block start/end brace from the output asm string + AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() - + StartLoc.getPointer()); + return true; +} + /// eatToEndOfLine uses the Lexer to eat the characters to the end of the line /// since they may not be able to be tokenized to get to the end of line token. void AsmParser::eatToEndOfLine() { @@ -4983,6 +5002,10 @@ unsigned InputIdx = 0; unsigned OutputIdx = 0; while (getLexer().isNot(AsmToken::Eof)) { + // Parse curly braces marking block start/end + if (parseCurlyBlockScope(AsmStrRewrites)) + continue; + ParseStatementInfo Info(&AsmStrRewrites); if (parseStatement(Info, &SI)) return true; @@ -5159,6 +5182,9 @@ OS << '.'; OS << AR.Val; break; + case AOK_EndOfStatement: + OS << "\n\t"; + break; } // Skip the original expression. Index: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2304,6 +2304,7 @@ Name == "repne" || Name == "repnz" || Name == "rex64" || Name == "data16"; + bool CurlyAsEndOfStatement = false; // This does the actual operand parsing. Don't parse any more if we have a // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we // just want to parse the "lock" as the first instruction and the "incl" as @@ -2331,7 +2332,12 @@ break; } - if (getLexer().isNot(AsmToken::EndOfStatement)) + // In MS inline asm curly braces mark the begining/end of a block, therefore + // they should be interepreted as end of statement + CurlyAsEndOfStatement = + isParsingIntelSyntax() && isParsingInlineAsm() && + (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly)); + if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement) return ErrorAndEatStatement(getLexer().getLoc(), "unexpected token in argument list"); } @@ -2340,6 +2346,10 @@ if (getLexer().is(AsmToken::EndOfStatement) || (isPrefix && getLexer().is(AsmToken::Slash))) Parser.Lex(); + else if (CurlyAsEndOfStatement) + // Add an actual EndOfStatement before the curly brace + Info.AsmRewrites->emplace_back(AOK_EndOfStatement, + getLexer().getTok().getLoc(), 0); // This is for gas compatibility and cannot be done in td. // Adding "p" for some floating point with no argument.