From 9219d1b764d9ce765012a933d4c19eb23968387f Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 27 Nov 2012 21:31:01 +0000 Subject: [PATCH] Allow an ASTConsumer to selectively skip function bodies while parsing. Patch by Olivier Goffart! llvm-svn: 168726 --- clang/include/clang/AST/ASTConsumer.h | 9 +++++++++ clang/lib/Sema/SemaDecl.cpp | 3 +++ clang/unittests/Tooling/ToolingTest.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/clang/include/clang/AST/ASTConsumer.h b/clang/include/clang/AST/ASTConsumer.h index 37b0740..4ce5852 100644 --- a/clang/include/clang/AST/ASTConsumer.h +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6a9065e..edf50d2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp index d40c613..a45935d 100644 --- a/clang/unittests/Tooling/ToolingTest.cpp +++ b/clang/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 -- 2.7.4