]> granicus.if.org Git - clang/commitdiff
Allow an ASTConsumer to selectively skip function bodies while parsing. Patch
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 27 Nov 2012 21:31:01 +0000 (21:31 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 27 Nov 2012 21:31:01 +0000 (21:31 +0000)
by Olivier Goffart!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168726 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTConsumer.h
lib/Sema/SemaDecl.cpp
unittests/Tooling/ToolingTest.cpp

index 37b0740cb98b68d6c4ab7e38acae3f87c6a61796..4ce58525459631726ff31f3283353ddabf5e309c 100644 (file)
@@ -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.
index 6a9065e94fc8ec16f6b65d95f59f3c905e42e96b..edf50d20ec899fe829ce45b86bb09e2827510214 100644 (file)
@@ -7993,6 +7993,9 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
 }
 
 bool Sema::canSkipFunctionBody(Decl *D) {
+  if (!Consumer.shouldSkipFunctionBody(D))
+    return false;
+
   if (isa<ObjCMethodDecl>(D))
     return true;
 
index d40c613dd0592ca04d5e7406a28b26f9285de179..a45935db4e36b5fc949505fcea61712ab132815f 100644 (file)
@@ -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<FunctionDecl>(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