[cfe-commits] r152651 - in /cfe/trunk: include/clang/Analysis/CallGraph.h lib/Analysis/CallGraph.cpp lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Anna Zaks ganna at apple.com
Tue Mar 13 12:32:08 PDT 2012


Author: zaks
Date: Tue Mar 13 14:32:08 2012
New Revision: 152651

URL: http://llvm.org/viewvc/llvm-project?rev=152651&view=rev
Log:
[analyzer] Refactor CallGraph to use Recursive AST visitor when
collecting function Decls.

Modified:
    cfe/trunk/include/clang/Analysis/CallGraph.h
    cfe/trunk/lib/Analysis/CallGraph.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Modified: cfe/trunk/include/clang/Analysis/CallGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CallGraph.h?rev=152651&r1=152650&r2=152651&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CallGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/CallGraph.h Tue Mar 13 14:32:08 2012
@@ -48,8 +48,9 @@
   /// \brief Add the given declaration to the call graph.
   void addToCallGraph(Decl *D, bool IsGlobal);
 
-  /// \brief Populate the call graph with the functions in the given DeclContext.
-  void addToCallGraph(DeclContext *DC);
+  /// \brief Populate the call graph with the functions in the given translation
+  /// unit.
+  void addToCallGraph(TranslationUnitDecl *TU);
 
   /// \brief Lookup the node for the given declaration.
   CallGraphNode *getNode(const Decl *) const;

Modified: cfe/trunk/lib/Analysis/CallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CallGraph.cpp?rev=152651&r1=152650&r2=152651&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CallGraph.cpp (original)
+++ cfe/trunk/lib/Analysis/CallGraph.cpp Tue Mar 13 14:32:08 2012
@@ -14,6 +14,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 
 #include "llvm/Support/GraphWriter.h"
@@ -71,6 +72,35 @@
         static_cast<CGBuilder*>(this)->Visit(*I);
   }
 };
+
+/// A helper class which walks the AST declarations.
+// TODO: We might want to specialize the visitor to shrink the call graph.
+// For example, we might not want to include the inline methods from header
+// files.
+class CGDeclVisitor : public RecursiveASTVisitor<CGDeclVisitor> {
+  CallGraph *CG;
+
+public:
+  CGDeclVisitor(CallGraph * InCG) : CG(InCG) {}
+
+  bool VisitFunctionDecl(FunctionDecl *FD) {
+    // We skip function template definitions, as their semantics is
+    // only determined when they are instantiated.
+    if (includeInGraph(FD))
+      // If this function has external linkage, anything could call it.
+      // Note, we are not precise here. For example, the function could have
+      // its address taken.
+      CG->addToCallGraph(FD, FD->isGlobal());
+    return true;
+  }
+
+  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+    if (includeInGraph(MD))
+      CG->addToCallGraph(MD, true);
+    return true;
+  }
+};
+
 } // end anonymous namespace
 
 CallGraph::CallGraph() {
@@ -98,42 +128,8 @@
   builder.Visit(D->getBody());
 }
 
-void CallGraph::addToCallGraph(DeclContext *DC) {
-  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
-       I != E; ++I) {
-    Decl *D = *I;
-    switch (D->getKind()) {
-    case Decl::CXXConstructor:
-    case Decl::CXXDestructor:
-    case Decl::CXXConversion:
-    case Decl::CXXMethod:
-    case Decl::Function: {
-      FunctionDecl *FD = cast<FunctionDecl>(D);
-      // We skip function template definitions, as their semantics is
-      // only determined when they are instantiated.
-      if (includeInGraph(FD))
-        // If this function has external linkage, anything could call it.
-        // Note, we are not precise here. For example, the function could have
-        // its address taken.
-        addToCallGraph(FD, FD->isGlobal());
-      break;
-    }
-
-    case Decl::ObjCCategoryImpl:
-    case Decl::ObjCImplementation: {
-      ObjCImplDecl *ID = cast<ObjCImplDecl>(D);
-      for (ObjCContainerDecl::method_iterator MI = ID->meth_begin(),
-          ME = ID->meth_end(); MI != ME; ++MI) {
-        if (includeInGraph(*MI))
-          addToCallGraph(*MI, true);
-      }
-      break;
-    }
-
-    default:
-      break;
-    }
-  }
+void CallGraph::addToCallGraph(TranslationUnitDecl *TU) {
+  CGDeclVisitor(this).TraverseDecl(TU);
 }
 
 CallGraphNode *CallGraph::getNode(const Decl *F) const {

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=152651&r1=152650&r2=152651&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Mar 13 14:32:08 2012
@@ -206,9 +206,9 @@
 
   virtual void HandleTranslationUnit(ASTContext &C);
 
-  /// \brief Build the call graph for the context and use it to define the order
+  /// \brief Build the call graph for the TU and use it to define the order
   /// in which the functions should be visited.
-  void HandleDeclContextGallGraph(ASTContext &C, DeclContext *dc);
+  void HandleDeclsGallGraph(TranslationUnitDecl *TU);
 
   /// \brief Run analyzes(syntax or path sensitive) on the given function.
   /// \param Mode - determines if we are requesting syntax only or path
@@ -261,12 +261,11 @@
 //===----------------------------------------------------------------------===//
 llvm::Timer* AnalysisConsumer::TUTotalTimer = 0;
 
-void AnalysisConsumer::HandleDeclContextGallGraph(ASTContext &C,
-                                                  DeclContext *dc) {
+void AnalysisConsumer::HandleDeclsGallGraph(TranslationUnitDecl *TU) {
   // Otherwise, use the Callgraph to derive the order.
   // Build the Call Graph.
   CallGraph CG;
-  CG.addToCallGraph(dc);
+  CG.addToCallGraph(TU);
 
   // Find the top level nodes - children of root + the unreachable (parentless)
   // nodes.
@@ -334,7 +333,7 @@
     TraverseDecl(TU);
 
     if (Mgr->shouldInlineCall())
-      HandleDeclContextGallGraph(C, TU);
+      HandleDeclsGallGraph(TU);
 
     // After all decls handled, run checkers on the entire TranslationUnit.
     checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);





More information about the cfe-commits mailing list