diff options
Diffstat (limited to 'clang/lib/Parse/ParseStmtAsm.cpp')
-rw-r--r-- | clang/lib/Parse/ParseStmtAsm.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp index 58d69965de5..f1d2946e0e5 100644 --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -322,6 +322,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { SourceLocation EndLoc = AsmLoc; SmallVector<Token, 4> AsmToks; + bool SingleLineMode = true; unsigned BraceNesting = 0; unsigned short savedBraceCount = BraceCount; bool InAsmComment = false; @@ -333,6 +334,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { if (Tok.is(tok::l_brace)) { // Braced inline asm: consume the opening brace. + SingleLineMode = false; BraceNesting = 1; EndLoc = ConsumeBrace(); LBraceLocs.push_back(EndLoc); @@ -364,30 +366,39 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { } else if (!InAsmComment && Tok.is(tok::semi)) { // A semicolon in an asm is the start of a comment. InAsmComment = true; - if (BraceNesting) { + if (!SingleLineMode) { // Compute which line the comment is on. std::pair<FileID, unsigned> ExpSemiLoc = SrcMgr.getDecomposedExpansionLoc(TokLoc); FID = ExpSemiLoc.first; LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second); } - } else if (!BraceNesting || InAsmComment) { + } else if (SingleLineMode || InAsmComment) { // If end-of-line is significant, check whether this token is on a // new line. std::pair<FileID, unsigned> ExpLoc = SrcMgr.getDecomposedExpansionLoc(TokLoc); if (ExpLoc.first != FID || SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) { - // If this is a single-line __asm, we're done. - if (!BraceNesting) + // If this is a single-line __asm, we're done, except if the next + // line begins with an __asm too, in which case we finish a comment + // if needed and then keep processing the next line as a single + // line __asm. + bool isAsm = Tok.is(tok::kw_asm); + if (SingleLineMode && !isAsm) break; // We're no longer in a comment. InAsmComment = false; + if (isAsm) { + LineNo = SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second); + SkippedStartOfLine = Tok.isAtStartOfLine(); + } } else if (!InAsmComment && Tok.is(tok::r_brace)) { - // Single-line asm always ends when a closing brace is seen. - // FIXME: This is compatible with Apple gcc's -fasm-blocks; what - // does MSVC do here? - break; + // In MSVC mode, braces only participate in brace matching and + // separating the asm statements. This is an intentional + // departure from the Apple gcc behavior. + if (!BraceNesting) + break; } } if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) && @@ -398,7 +409,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { BraceNesting--; // Finish if all of the opened braces in the inline asm section were // consumed. - if (BraceNesting == 0) + if (BraceNesting == 0 && !SingleLineMode) break; else { LBraceLocs.pop_back(); |