[clang] ffcc076 - [[Clang CallGraph]] CallGraph should still record calls to decls.

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 20 08:55:41 PDT 2020


Author: Erich Keane
Date: 2020-03-20T08:55:23-07:00
New Revision: ffcc076a2b23363025de2f67243086963f235b20

URL: https://github.com/llvm/llvm-project/commit/ffcc076a2b23363025de2f67243086963f235b20
DIFF: https://github.com/llvm/llvm-project/commit/ffcc076a2b23363025de2f67243086963f235b20.diff

LOG: [[Clang CallGraph]] CallGraph should still record calls to decls.

Discovered by a downstream user, we found that the CallGraph ignores
callees unless they are defined.  This seems foolish, and prevents
combining the report with other reports to create unified reports.
Additionally, declarations contain information that is likely useful to
consumers of the CallGraph.

This patch implements this by splitting the includeInGraph function into
two versions, the current one plus one that is for callees only.  The
only difference currently is that includeInGraph checks for a body, then
calls includeCalleeInGraph.

Differential Revision: https://reviews.llvm.org/D76435

Added: 
    

Modified: 
    clang/include/clang/Analysis/CallGraph.h
    clang/lib/Analysis/CallGraph.cpp
    clang/test/Analysis/debug-CallGraph.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h
index 041050319239..6f7159330f5d 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -66,6 +66,11 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
   /// Determine if a declaration should be included in the graph.
   static bool includeInGraph(const Decl *D);
 
+  /// Determine if a declaration should be included in the graph for the 
+  /// purposes of being a callee. This is similar to includeInGraph except
+  /// it permits declarations, not just definitions.
+  static bool includeCalleeInGraph(const Decl *D);
+
   /// Lookup the node for the given declaration.
   CallGraphNode *getNode(const Decl *) const;
 

diff  --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp
index 419f3ad2e724..59cc939b6fd1 100644
--- a/clang/lib/Analysis/CallGraph.cpp
+++ b/clang/lib/Analysis/CallGraph.cpp
@@ -67,7 +67,7 @@ class CGBuilder : public StmtVisitor<CGBuilder> {
   }
 
   void addCalledDecl(Decl *D, Expr *CallExpr) {
-    if (G->includeInGraph(D)) {
+    if (G->includeCalleeInGraph(D)) {
       CallGraphNode *CalleeNode = G->getOrInsertNode(D);
       CallerNode->addCallee({CalleeNode, CallExpr});
     }
@@ -157,6 +157,10 @@ bool CallGraph::includeInGraph(const Decl *D) {
   if (!D->hasBody())
     return false;
 
+  return includeCalleeInGraph(D);
+}
+
+bool CallGraph::includeCalleeInGraph(const Decl *D) {
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // We skip function template definitions, as their semantics is
     // only determined when they are instantiated.

diff  --git a/clang/test/Analysis/debug-CallGraph.cpp b/clang/test/Analysis/debug-CallGraph.cpp
index 5453e2f21533..120bb38d3bb3 100644
--- a/clang/test/Analysis/debug-CallGraph.cpp
+++ b/clang/test/Analysis/debug-CallGraph.cpp
@@ -97,9 +97,10 @@ namespace CallDecl {
 }
 
 // CHECK:--- Call graph Dump ---
-// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ SomeNS::templ SomeNS::templUser Lambdas::Callee Lambdas::f1 Lambdas::f1\(\)::\(anonymous class\)::operator\(\) Lambdas::f1\(\)::\(anonymous class\)::operator\(\) CallDecl::SomeDef CallDecl::Caller CallDecl::SomeOtherDecl $}}
-// CHECK-NEXT: {{Function: CallDecl::Caller calls: CallDecl::SomeOtherDecl $}}
+// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ SomeNS::templ SomeNS::templUser Lambdas::Callee Lambdas::f1 Lambdas::f1\(\)::\(anonymous class\)::operator\(\) Lambdas::f1\(\)::\(anonymous class\)::operator\(\) CallDecl::SomeDef CallDecl::Caller CallDecl::SomeDecl CallDecl::SomeOtherDecl $}}
+// CHECK-NEXT: {{Function: CallDecl::Caller calls: CallDecl::SomeDecl CallDecl::SomeOtherDecl $}}
 // CHECK-NEXT: {{Function: CallDecl::SomeOtherDecl calls: CallDecl::SomeDef $}}
+// CHECK-NEXT: {{Function: CallDecl::SomeDecl calls: $}}
 // CHECK-NEXT: {{Function: CallDecl::SomeDef calls: $}}
 // CHECK-NEXT: {{Function: Lambdas::f1 calls: Lambdas::f1\(\)::\(anonymous class\)::operator\(\) Lambdas::f1\(\)::\(anonymous class\)::operator\(\) $}}
 // CHECK-NEXT: {{Function: Lambdas::f1\(\)::\(anonymous class\)::operator\(\) calls: Lambdas::Callee $}}


        


More information about the cfe-commits mailing list