diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp | 209 |
1 files changed, 136 insertions, 73 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp index 43b6965..d1f2138 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp @@ -41,6 +41,21 @@ using namespace clang; // C99 6.8: Statements and Blocks. //===----------------------------------------------------------------------===// +/// \brief Parse a standalone statement (for instance, as the body of an 'if', +/// 'while', or 'for'). +StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) { + StmtResult Res; + + // We may get back a null statement if we found a #pragma. Keep going until + // we get an actual statement. + do { + StmtVector Stmts; + Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); + } while (!Res.isInvalid() && !Res.get()); + + return Res; +} + /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'. /// StatementOrDeclaration: /// statement @@ -111,6 +126,38 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range); } +namespace { +class StatementFilterCCC : public CorrectionCandidateCallback { +public: + StatementFilterCCC(Token nextTok) : NextToken(nextTok) { + WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) || + nextTok.is(tok::identifier) || nextTok.is(tok::star) || + nextTok.is(tok::amp) || nextTok.is(tok::l_square); + WantExpressionKeywords = nextTok.is(tok::l_paren) || + nextTok.is(tok::identifier) || + nextTok.is(tok::arrow) || nextTok.is(tok::period); + WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) || + nextTok.is(tok::identifier) || + nextTok.is(tok::l_brace); + WantCXXNamedCasts = false; + } + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>()) + return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD); + if (NextToken.is(tok::equal)) + return candidate.getCorrectionDeclAs<VarDecl>(); + if (NextToken.is(tok::period) && + candidate.getCorrectionDeclAs<NamespaceDecl>()) + return false; + return CorrectionCandidateCallback::ValidateCandidate(candidate); + } + +private: + Token NextToken; +}; +} + StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts, bool OnlyStatement, SourceLocation *TrailingElseLoc, @@ -149,25 +196,12 @@ Retry: if (Next.isNot(tok::coloncolon)) { // Try to limit which sets of keywords should be included in typo // correction based on what the next token is. - // FIXME: Pass the next token into the CorrectionCandidateCallback and - // do this filtering in a more fine-grained manner. - CorrectionCandidateCallback DefaultValidator; - DefaultValidator.WantTypeSpecifiers = - Next.is(tok::l_paren) || Next.is(tok::less) || - Next.is(tok::identifier) || Next.is(tok::star) || - Next.is(tok::amp) || Next.is(tok::l_square); - DefaultValidator.WantExpressionKeywords = - Next.is(tok::l_paren) || Next.is(tok::identifier) || - Next.is(tok::arrow) || Next.is(tok::period); - DefaultValidator.WantRemainingKeywords = - Next.is(tok::l_paren) || Next.is(tok::semi) || - Next.is(tok::identifier) || Next.is(tok::l_brace); - DefaultValidator.WantCXXNamedCasts = false; - if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator) + StatementFilterCCC Validator(Next); + if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator) == ANK_Error) { // Handle errors here by skipping up to the next semicolon or '}', and // eat the semicolon if that's what stopped us. - SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::semi)) ConsumeToken(); return StmtError(); @@ -293,6 +327,7 @@ Retry: return StmtEmpty(); case tok::annot_pragma_fp_contract: + ProhibitAttributes(Attrs); Diag(Tok, diag::err_pragma_fp_contract_scope); ConsumeToken(); return StmtError(); @@ -303,12 +338,13 @@ Retry: return StmtEmpty(); case tok::annot_pragma_captured: + ProhibitAttributes(Attrs); return HandlePragmaCaptured(); case tok::annot_pragma_openmp: - SourceLocation DeclStart = Tok.getLocation(); - DeclGroupPtrTy Res = ParseOpenMPDeclarativeDirective(); - return Actions.ActOnDeclStmt(Res, DeclStart, Tok.getLocation()); + ProhibitAttributes(Attrs); + return ParseOpenMPDeclarativeOrExecutableDirective(); + } // If we reached this code, the statement must end in a semicolon. @@ -320,7 +356,7 @@ Retry: // succeed. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError); // Skip until we see a } or ;, but don't eat it. - SkipUntil(tok::r_brace, true, true); + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); } return Res; @@ -337,7 +373,7 @@ StmtResult Parser::ParseExprStatement() { // If the expression is invalid, skip ahead to the next semicolon or '}'. // Not doing this opens us up to the possibility of infinite loops if // ParseExpression does not consume any tokens. - SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::semi)) ConsumeToken(); return Actions.ActOnExprStmtError(); @@ -480,11 +516,40 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { // identifier ':' statement SourceLocation ColonLoc = ConsumeToken(); - // Read label attributes, if present. attrs will contain both C++11 and GNU - // attributes (if present) after this point. - MaybeParseGNUAttributes(attrs); + // Read label attributes, if present. + StmtResult SubStmt; + if (Tok.is(tok::kw___attribute)) { + ParsedAttributesWithRange TempAttrs(AttrFactory); + ParseGNUAttributes(TempAttrs); + + // In C++, GNU attributes only apply to the label if they are followed by a + // semicolon, to disambiguate label attributes from attributes on a labeled + // declaration. + // + // This doesn't quite match what GCC does; if the attribute list is empty + // and followed by a semicolon, GCC will reject (it appears to parse the + // attributes as part of a statement in that case). That looks like a bug. + if (!getLangOpts().CPlusPlus || Tok.is(tok::semi)) + attrs.takeAllFrom(TempAttrs); + else if (isDeclarationStatement()) { + StmtVector Stmts; + // FIXME: We should do this whether or not we have a declaration + // statement, but that doesn't work correctly (because ProhibitAttributes + // can't handle GNU attributes), so only call it in the one case where + // GNU attributes are allowed. + SubStmt = ParseStatementOrDeclarationAfterAttributes( + Stmts, /*OnlyStmts*/ true, 0, TempAttrs); + if (!TempAttrs.empty() && !SubStmt.isInvalid()) + SubStmt = Actions.ProcessStmtAttributes( + SubStmt.get(), TempAttrs.getList(), TempAttrs.Range); + } else { + Diag(Tok, diag::err_expected_semi_after) << "__attribute__"; + } + } - StmtResult SubStmt(ParseStatement()); + // If we've not parsed a statement yet, parse one now. + if (!SubStmt.isInvalid() && !SubStmt.isUsable()) + SubStmt = ParseStatement(); // Broken substmt shouldn't prevent the label from being added to the AST. if (SubStmt.isInvalid()) @@ -521,7 +586,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { // out of stack space in our recursive descent parser. As a special case, // flatten this recursion into an iterative loop. This is complex and gross, // but all the grossness is constrained to ParseCaseStatement (and some - // wierdness in the actions), so this is just local grossness :). + // weirdness in the actions), so this is just local grossness :). // TopLevelCase - This is the highest level we have parsed. 'case 1' in the // example above. @@ -552,7 +617,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { ExprResult LHS(MissingCase ? Expr : ParseConstantExpression()); MissingCase = false; if (LHS.isInvalid()) { - SkipUntil(tok::colon); + SkipUntil(tok::colon, StopAtSemi); return StmtError(); } @@ -565,7 +630,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { RHS = ParseConstantExpression(); if (RHS.isInvalid()) { - SkipUntil(tok::colon); + SkipUntil(tok::colon, StopAtSemi); return StmtError(); } } @@ -798,7 +863,6 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // only allowed at the start of a compound stmt regardless of the language. while (Tok.is(tok::kw___label__)) { SourceLocation LabelLoc = ConsumeToken(); - Diag(LabelLoc, diag::ext_gnu_local_label); SmallVector<Decl *, 8> DeclsInGroup; while (1) { @@ -817,8 +881,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { } DeclSpec DS(AttrFactory); - DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS, - DeclsInGroup.data(), DeclsInGroup.size()); + DeclGroupPtrTy Res = + Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation()); ExpectAndConsumeSemi(diag::err_expected_semi_declaration); @@ -1132,7 +1196,7 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { // will have no place to connect back with the switch. if (Tok.is(tok::l_brace)) { ConsumeBrace(); - SkipUntil(tok::r_brace, false, false); + SkipUntil(tok::r_brace); } else SkipUntil(tok::semi); return Switch; @@ -1283,7 +1347,7 @@ StmtResult Parser::ParseDoStatement() { if (!Body.isInvalid()) { Diag(Tok, diag::err_expected_while); Diag(DoLoc, diag::note_matching) << "do"; - SkipUntil(tok::semi, false, true); + SkipUntil(tok::semi, StopBeforeMatch); } return StmtError(); } @@ -1291,18 +1355,16 @@ StmtResult Parser::ParseDoStatement() { if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "do/while"; - SkipUntil(tok::semi, false, true); + SkipUntil(tok::semi, StopBeforeMatch); return StmtError(); } - // Parse the parenthesized condition. + // Parse the parenthesized expression. BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - // FIXME: Do not just parse the attribute contents and throw them away - ParsedAttributesWithRange attrs(AttrFactory); - MaybeParseCXX11Attributes(attrs); - ProhibitAttributes(attrs); + // A do-while expression is not a condition, so can't have attributes. + DiagnoseAndSkipCXX11Attributes(); ExprResult Cond = ParseExpression(); T.consumeClose(); @@ -1469,14 +1531,14 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { // for (expr : expr) { ... } Diag(Tok, diag::err_for_range_expected_decl) << FirstPart.get()->getSourceRange(); - SkipUntil(tok::r_paren, false, true); + SkipUntil(tok::r_paren, StopBeforeMatch); SecondPartIsInvalid = true; } else { if (!Value.isInvalid()) { Diag(Tok, diag::err_expected_semi_for); } else { // Skip until semicolon or rparen, don't consume it. - SkipUntil(tok::r_paren, true, true); + SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::semi)) ConsumeToken(); } @@ -1508,7 +1570,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { Diag(Tok, diag::err_expected_semi_for); else // Skip until semicolon or rparen, don't consume it. - SkipUntil(tok::r_paren, true, true); + SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); } if (Tok.is(tok::semi)) { @@ -1610,7 +1672,7 @@ StmtResult Parser::ParseGotoStatement() { SourceLocation StarLoc = ConsumeToken(); ExprResult R(ParseExpression()); if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. - SkipUntil(tok::semi, false, true); + SkipUntil(tok::semi, StopBeforeMatch); return StmtError(); } Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); @@ -1669,7 +1731,7 @@ StmtResult Parser::ParseReturnStatement() { } else R = ParseExpression(); if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. - SkipUntil(tok::semi, false, true); + SkipUntil(tok::semi, StopBeforeMatch); return StmtError(); } } @@ -2067,14 +2129,22 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { // We need an actual supported target. llvm::Triple TheTriple = Actions.Context.getTargetInfo().getTriple(); llvm::Triple::ArchType ArchTy = TheTriple.getArch(); + const std::string &TT = TheTriple.getTriple(); + const llvm::Target *TheTarget = 0; bool UnsupportedArch = (ArchTy != llvm::Triple::x86 && ArchTy != llvm::Triple::x86_64); - if (UnsupportedArch) + if (UnsupportedArch) { Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName(); - + } else { + std::string Error; + TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error); + if (!TheTarget) + Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error; + } + // If we don't support assembly, or the assembly is empty, we don't // need to instantiate the AsmParser, etc. - if (UnsupportedArch || AsmToks.empty()) { + if (!TheTarget || AsmToks.empty()) { return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(), /*NumOutputs*/ 0, /*NumInputs*/ 0, ConstraintRefs, ClobberRefs, Exprs, EndLoc); @@ -2086,19 +2156,16 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString)) return StmtError(); - // Find the target and create the target specific parser. - std::string Error; - const std::string &TT = TheTriple.getTriple(); - const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error); - - OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT)); OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT)); + OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT)); + // Get the instruction descriptor. + const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo()); OwningPtr<llvm::MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TT, "", "")); llvm::SourceMgr TempSrcMgr; - llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &TempSrcMgr); + llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr); llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>"); @@ -2109,10 +2176,8 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { OwningPtr<llvm::MCAsmParser> Parser(createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI)); OwningPtr<llvm::MCTargetAsmParser> - TargetParser(TheTarget->createMCAsmParser(*STI, *Parser)); + TargetParser(TheTarget->createMCAsmParser(*STI, *Parser, *MII)); - // Get the instruction descriptor. - const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); llvm::MCInstPrinter *IP = TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI); @@ -2214,7 +2279,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) { bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "asm"; - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return StmtError(); } BalancedDelimiterTracker T(*this, tok::l_paren); @@ -2333,7 +2398,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return true; } @@ -2347,14 +2412,14 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, ExprResult Constraint(ParseAsmStringLiteral()); if (Constraint.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return true; } Constraints.push_back(Constraint.release()); if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return true; } @@ -2364,7 +2429,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, ExprResult Res(ParseExpression()); T.consumeClose(); if (Res.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return true; } Exprs.push_back(Res.release()); @@ -2395,8 +2460,7 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { // If the function body could not be parsed, make a bogus compoundstmt. if (FnBody.isInvalid()) { Sema::CompoundScopeRAII CompoundScope(Actions); - FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, - MultiStmtArg(), false); + FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); } BodyScope.Exit(); @@ -2433,8 +2497,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { // compound statement as the body. if (FnBody.isInvalid()) { Sema::CompoundScopeRAII CompoundScope(Actions); - FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, - MultiStmtArg(), false); + FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); } BodyScope.Exit(); @@ -2448,7 +2511,7 @@ bool Parser::trySkippingFunctionBody() { if (!PP.isCodeCompletionEnabled()) { ConsumeBrace(); - SkipUntil(tok::r_brace, /*StopAtSemi=*/false, /*DontConsume=*/false); + SkipUntil(tok::r_brace); return true; } @@ -2456,8 +2519,7 @@ bool Parser::trySkippingFunctionBody() { // the body contains the code-completion point. TentativeParsingAction PA(*this); ConsumeBrace(); - if (SkipUntil(tok::r_brace, /*StopAtSemi=*/false, /*DontConsume=*/false, - /*StopAtCodeCompletion=*/true)) { + if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) { PA.Commit(); return true; } @@ -2530,9 +2592,10 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { } else { StmtVector Handlers; - ParsedAttributesWithRange attrs(AttrFactory); - MaybeParseCXX11Attributes(attrs); - ProhibitAttributes(attrs); + + // C++11 attributes can't appear here, despite this context seeming + // statement-like. + DiagnoseAndSkipCXX11Attributes(); if (Tok.isNot(tok::kw_catch)) return StmtError(Diag(Tok, diag::err_expected_catch)); @@ -2546,7 +2609,7 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { if (Handlers.empty()) return StmtError(); - return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(),Handlers); + return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), Handlers); } } |