diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 |
5 files changed, 51 insertions, 22 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 3c5134268e8..39fcc827041 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -101,6 +101,12 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, return FnD; } + if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) && + trySkippingFunctionBody()) { + Actions.ActOnSkippedFunctionBody(FnD); + return FnD; + } + // In delayed template parsing mode, if we are within a class template // or if we are about to parse function member template then consume // the tokens and store them for parsing at the end of the translation unit. diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 95a0680994e..22c832650be 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2656,6 +2656,12 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them /// for later parsing. void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) { + if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) && + trySkippingFunctionBody()) { + Actions.ActOnSkippedFunctionBody(MDecl); + return; + } + LexedMethod* LM = new LexedMethod(this, MDecl); CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM); CachedTokens &Toks = LM->Toks; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 69989fe522e..8173d09cbbe 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1916,12 +1916,6 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { assert(Tok.is(tok::l_brace)); SourceLocation LBraceLoc = Tok.getLocation(); - if (SkipFunctionBodies && (!Decl || Actions.canSkipFunctionBody(Decl)) && - trySkippingFunctionBody()) { - BodyScope.Exit(); - return Actions.ActOnSkippedFunctionBody(Decl); - } - PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, "parsing function body"); @@ -1964,12 +1958,6 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { else Actions.ActOnDefaultCtorInitializers(Decl); - if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) && - trySkippingFunctionBody()) { - BodyScope.Exit(); - return Actions.ActOnSkippedFunctionBody(Decl); - } - // Save and reset current vtordisp stack if we have entered a C++ method body. bool IsCXXMethod = getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl); @@ -1990,27 +1978,43 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { } bool Parser::trySkippingFunctionBody() { - assert(Tok.is(tok::l_brace)); assert(SkipFunctionBodies && "Should only be called when SkipFunctionBodies is enabled"); - if (!PP.isCodeCompletionEnabled()) { - ConsumeBrace(); - SkipUntil(tok::r_brace); + SkipFunctionBody(); return true; } // We're in code-completion mode. Skip parsing for all function bodies unless // the body contains the code-completion point. TentativeParsingAction PA(*this); - ConsumeBrace(); - if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) { + bool IsTryCatch = Tok.is(tok::kw_try); + CachedTokens Toks; + bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks); + if (llvm::any_of(Toks, [](const Token &Tok) { + return Tok.is(tok::code_completion); + })) { + PA.Revert(); + return false; + } + if (ErrorInPrologue) { PA.Commit(); + SkipMalformedDecl(); return true; } - - PA.Revert(); - return false; + if (!SkipUntil(tok::r_brace, StopAtCodeCompletion)) { + PA.Revert(); + return false; + } + while (IsTryCatch && Tok.is(tok::kw_catch)) { + if (!SkipUntil(tok::l_brace, StopAtCodeCompletion) || + !SkipUntil(tok::r_brace, StopAtCodeCompletion)) { + PA.Revert(); + return false; + } + } + PA.Commit(); + return true; } /// ParseCXXTryBlock - Parse a C++ try-block. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 9ed2d72fcd9..f968f995d53 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1044,6 +1044,12 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, D.complete(DP); D.getMutableDeclSpec().abort(); + if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) && + trySkippingFunctionBody()) { + BodyScope.Exit(); + return Actions.ActOnSkippedFunctionBody(DP); + } + CachedTokens Toks; LexTemplateFunctionForLateParsing(Toks); @@ -1136,6 +1142,13 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, return Res; } + if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) && + trySkippingFunctionBody()) { + BodyScope.Exit(); + Actions.ActOnSkippedFunctionBody(Res); + return Actions.ActOnFinishFunctionBody(Res, nullptr, false); + } + if (Tok.is(tok::kw_try)) return ParseFunctionTryBlock(Res, BodyScope); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 49a650e2162..deb8d15c8ff 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11384,7 +11384,7 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { FD->setHasSkippedBody(); else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl)) MD->setHasSkippedBody(); - return ActOnFinishFunctionBody(Decl, nullptr); + return Decl; } Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { |