diff options
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 181 |
1 files changed, 83 insertions, 98 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index d2e4309..df9b996 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1495,8 +1495,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { StmtResult ForEachStmt; if (ForRange) { - ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, T.getOpenLocation(), - FirstPart.take(), + ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(), ForRangeInit.ColonLoc, ForRangeInit.RangeExpr.get(), T.getCloseLocation()); @@ -1505,7 +1504,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { // Similarly, we need to do the semantic analysis for a for-range // statement immediately in order to close over temporaries correctly. } else if (ForEach) { - ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, T.getOpenLocation(), + ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, FirstPart.take(), Collection.take(), T.getCloseLocation()); @@ -1657,112 +1656,98 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { SourceManager &SrcMgr = PP.getSourceManager(); SourceLocation EndLoc = AsmLoc; SmallVector<Token, 4> AsmToks; - SmallVector<unsigned, 4> LineEnds; - do { - bool InBraces = false; - unsigned short savedBraceCount = 0; - bool InAsmComment = false; - FileID FID; - unsigned LineNo = 0; - unsigned NumTokensRead = 0; - SourceLocation LBraceLoc; - - if (Tok.is(tok::l_brace)) { - // Braced inline asm: consume the opening brace. - InBraces = true; - savedBraceCount = BraceCount; - EndLoc = LBraceLoc = ConsumeBrace(); - ++NumTokensRead; - } else { - // Single-line inline asm; compute which line it is on. - std::pair<FileID, unsigned> ExpAsmLoc = - SrcMgr.getDecomposedExpansionLoc(EndLoc); - FID = ExpAsmLoc.first; - LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second); - } - SourceLocation TokLoc = Tok.getLocation(); - do { - // If we hit EOF, we're done, period. - if (Tok.is(tok::eof)) - break; + bool InBraces = false; + unsigned short savedBraceCount = 0; + bool InAsmComment = false; + FileID FID; + unsigned LineNo = 0; + unsigned NumTokensRead = 0; + SourceLocation LBraceLoc; + + if (Tok.is(tok::l_brace)) { + // Braced inline asm: consume the opening brace. + InBraces = true; + savedBraceCount = BraceCount; + EndLoc = LBraceLoc = ConsumeBrace(); + ++NumTokensRead; + } else { + // Single-line inline asm; compute which line it is on. + std::pair<FileID, unsigned> ExpAsmLoc = + SrcMgr.getDecomposedExpansionLoc(EndLoc); + FID = ExpAsmLoc.first; + LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second); + } - // The asm keyword is a statement separator, so multiple asm statements - // are allowed. - if (!InAsmComment && Tok.is(tok::kw_asm)) - break; + SourceLocation TokLoc = Tok.getLocation(); + do { + // If we hit EOF, we're done, period. + if (Tok.is(tok::eof)) + break; - if (!InAsmComment && Tok.is(tok::semi)) { - // A semicolon in an asm is the start of a comment. - InAsmComment = true; - if (InBraces) { - // 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 (!InBraces || 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 (!InBraces) - break; - // We're no longer in a comment. - InAsmComment = false; - } 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; - } + if (!InAsmComment && Tok.is(tok::semi)) { + // A semicolon in an asm is the start of a comment. + InAsmComment = true; + if (InBraces) { + // Compute which line the comment is on. + std::pair<FileID, unsigned> ExpSemiLoc = + SrcMgr.getDecomposedExpansionLoc(TokLoc); + FID = ExpSemiLoc.first; + LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second); } - if (!InAsmComment && InBraces && Tok.is(tok::r_brace) && - BraceCount == (savedBraceCount + 1)) { - // Consume the closing brace, and finish - EndLoc = ConsumeBrace(); + } else if (!InBraces || 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 (!InBraces) + break; + // We're no longer in a comment. + InAsmComment = false; + } 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; } - - // Consume the next token; make sure we don't modify the brace count etc. - // if we are in a comment. - EndLoc = TokLoc; - if (InAsmComment) - PP.Lex(Tok); - else { - AsmToks.push_back(Tok); - ConsumeAnyToken(); - } - TokLoc = Tok.getLocation(); - ++NumTokensRead; - } while (1); - - LineEnds.push_back(AsmToks.size()); - - if (InBraces && BraceCount != savedBraceCount) { - // __asm without closing brace (this can happen at EOF). - Diag(Tok, diag::err_expected_rbrace); - Diag(LBraceLoc, diag::note_matching) << "{"; - return StmtError(); - } else if (NumTokensRead == 0) { - // Empty __asm. - Diag(Tok, diag::err_expected_lbrace); - return StmtError(); } - // Multiple adjacent asm's form together into a single asm statement - // in the AST. - if (!Tok.is(tok::kw_asm)) + if (!InAsmComment && InBraces && Tok.is(tok::r_brace) && + BraceCount == (savedBraceCount + 1)) { + // Consume the closing brace, and finish + EndLoc = ConsumeBrace(); break; - EndLoc = ConsumeToken(); + } + + // Consume the next token; make sure we don't modify the brace count etc. + // if we are in a comment. + EndLoc = TokLoc; + if (InAsmComment) + PP.Lex(Tok); + else { + AsmToks.push_back(Tok); + ConsumeAnyToken(); + } + TokLoc = Tok.getLocation(); + ++NumTokensRead; } while (1); + if (InBraces && BraceCount != savedBraceCount) { + // __asm without closing brace (this can happen at EOF). + Diag(Tok, diag::err_expected_rbrace); + Diag(LBraceLoc, diag::note_matching) << "{"; + return StmtError(); + } else if (NumTokensRead == 0) { + // Empty __asm. + Diag(Tok, diag::err_expected_lbrace); + return StmtError(); + } + // FIXME: We should be passing source locations for better diagnostics. - return Actions.ActOnMSAsmStmt(AsmLoc, llvm::makeArrayRef(AsmToks), - llvm::makeArrayRef(LineEnds), EndLoc); + return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, + llvm::makeArrayRef(AsmToks), EndLoc); } /// ParseAsmStatement - Parse a GNU extended asm statement. |