From: Richard Smith Date: Tue, 27 Nov 2012 21:31:01 +0000 (+0000) Subject: Allow an ASTConsumer to selectively skip function bodies while parsing. Patch X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d1bac8d46740eb00085ec816af0829fd75fb4d5c;p=clang Allow an ASTConsumer to selectively skip function bodies while parsing. Patch by Olivier Goffart! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168726 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 37b0740cb9..4ce5852545 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -17,6 +17,7 @@ namespace clang { class ASTContext; class CXXRecordDecl; + class Decl; class DeclGroupRef; class HandleTagDeclDefinition; class PPMutationListener; @@ -130,6 +131,14 @@ public: /// PrintStats - If desired, print any statistics. virtual void PrintStats() {} + + /// \brief This callback is called for each function if the Parser was + /// initialized with \c SkipFunctionBodies set to \c true. + /// + /// \return \c true if the function's body should be skipped. The function + /// body may be parsed anyway if it is needed (for instance, if it contains + /// the code completion point or is constexpr). + virtual bool shouldSkipFunctionBody(Decl *D) { return true; } }; } // end namespace clang. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6a9065e94f..edf50d20ec 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7993,6 +7993,9 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { } bool Sema::canSkipFunctionBody(Decl *D) { + if (!Consumer.shouldSkipFunctionBody(D)) + return false; + if (isa(D)) return true; diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp index d40c613dd0..a45935db4e 100644 --- a/unittests/Tooling/ToolingTest.cpp +++ b/unittests/Tooling/ToolingTest.cpp @@ -10,6 +10,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CompilationDatabase.h" @@ -162,5 +163,28 @@ TEST(newFrontendActionFactory, InjectsEndOfSourceFileCallback) { } #endif +struct SkipBodyConsumer : public clang::ASTConsumer { + /// Skip the 'skipMe' function. + virtual bool shouldSkipFunctionBody(Decl *D) { + FunctionDecl *F = dyn_cast(D); + return F && F->getNameAsString() == "skipMe"; + } +}; + +struct SkipBodyAction : public clang::ASTFrontendAction { + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler, + StringRef) { + Compiler.getFrontendOpts().SkipFunctionBodies = true; + return new SkipBodyConsumer; + } +}; + +TEST(runToolOnCode, TestSkipFunctionBoddy) { + EXPECT_TRUE(runToolOnCode(new SkipBodyAction, + "int skipMe() { an_error_here }")); + EXPECT_FALSE(runToolOnCode(new SkipBodyAction, + "int skipMeNot() { an_error_here }")); +} + } // end namespace tooling } // end namespace clang