CallGraph.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. //===- CallGraph.cpp - AST-based Call graph -------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the AST-based CallGraph.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/Analysis/CallGraph.h"
  13. #include "clang/AST/Decl.h"
  14. #include "clang/AST/DeclBase.h"
  15. #include "clang/AST/DeclObjC.h"
  16. #include "clang/AST/Expr.h"
  17. #include "clang/AST/ExprObjC.h"
  18. #include "clang/AST/Stmt.h"
  19. #include "clang/AST/StmtVisitor.h"
  20. #include "clang/Basic/IdentifierTable.h"
  21. #include "clang/Basic/LLVM.h"
  22. #include "llvm/ADT/PostOrderIterator.h"
  23. #include "llvm/ADT/STLExtras.h"
  24. #include "llvm/ADT/Statistic.h"
  25. #include "llvm/Support/Casting.h"
  26. #include "llvm/Support/Compiler.h"
  27. #include "llvm/Support/DOTGraphTraits.h"
  28. #include "llvm/Support/GraphWriter.h"
  29. #include "llvm/Support/raw_ostream.h"
  30. #include <cassert>
  31. #include <memory>
  32. #include <string>
  33. using namespace clang;
  34. #define DEBUG_TYPE "CallGraph"
  35. STATISTIC(NumObjCCallEdges, "Number of Objective-C method call edges");
  36. STATISTIC(NumBlockCallEdges, "Number of block call edges");
  37. namespace {
  38. /// A helper class, which walks the AST and locates all the call sites in the
  39. /// given function body.
  40. class CGBuilder : public StmtVisitor<CGBuilder> {
  41. CallGraph *G;
  42. CallGraphNode *CallerNode;
  43. public:
  44. CGBuilder(CallGraph *g, CallGraphNode *N) : G(g), CallerNode(N) {}
  45. void VisitStmt(Stmt *S) { VisitChildren(S); }
  46. Decl *getDeclFromCall(CallExpr *CE) {
  47. if (FunctionDecl *CalleeDecl = CE->getDirectCallee())
  48. return CalleeDecl;
  49. // Simple detection of a call through a block.
  50. Expr *CEE = CE->getCallee()->IgnoreParenImpCasts();
  51. if (BlockExpr *Block = dyn_cast<BlockExpr>(CEE)) {
  52. NumBlockCallEdges++;
  53. return Block->getBlockDecl();
  54. }
  55. return nullptr;
  56. }
  57. void addCalledDecl(Decl *D, Expr *CallExpr) {
  58. if (G->includeCalleeInGraph(D)) {
  59. CallGraphNode *CalleeNode = G->getOrInsertNode(D);
  60. CallerNode->addCallee({CalleeNode, CallExpr});
  61. }
  62. }
  63. void VisitCallExpr(CallExpr *CE) {
  64. if (Decl *D = getDeclFromCall(CE))
  65. addCalledDecl(D, CE);
  66. VisitChildren(CE);
  67. }
  68. void VisitLambdaExpr(LambdaExpr *LE) {
  69. if (FunctionTemplateDecl *FTD = LE->getDependentCallOperator())
  70. for (FunctionDecl *FD : FTD->specializations())
  71. G->VisitFunctionDecl(FD);
  72. else if (CXXMethodDecl *MD = LE->getCallOperator())
  73. G->VisitFunctionDecl(MD);
  74. }
  75. void VisitCXXNewExpr(CXXNewExpr *E) {
  76. if (FunctionDecl *FD = E->getOperatorNew())
  77. addCalledDecl(FD, E);
  78. VisitChildren(E);
  79. }
  80. void VisitCXXConstructExpr(CXXConstructExpr *E) {
  81. CXXConstructorDecl *Ctor = E->getConstructor();
  82. if (FunctionDecl *Def = Ctor->getDefinition())
  83. addCalledDecl(Def, E);
  84. VisitChildren(E);
  85. }
  86. // Include the evaluation of the default argument.
  87. void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
  88. Visit(E->getExpr());
  89. }
  90. // Include the evaluation of the default initializers in a class.
  91. void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
  92. Visit(E->getExpr());
  93. }
  94. // Adds may-call edges for the ObjC message sends.
  95. void VisitObjCMessageExpr(ObjCMessageExpr *ME) {
  96. if (ObjCInterfaceDecl *IDecl = ME->getReceiverInterface()) {
  97. Selector Sel = ME->getSelector();
  98. // Find the callee definition within the same translation unit.
  99. Decl *D = nullptr;
  100. if (ME->isInstanceMessage())
  101. D = IDecl->lookupPrivateMethod(Sel);
  102. else
  103. D = IDecl->lookupPrivateClassMethod(Sel);
  104. if (D) {
  105. addCalledDecl(D, ME);
  106. NumObjCCallEdges++;
  107. }
  108. }
  109. }
  110. void VisitChildren(Stmt *S) {
  111. for (Stmt *SubStmt : S->children())
  112. if (SubStmt)
  113. this->Visit(SubStmt);
  114. }
  115. };
  116. } // namespace
  117. void CallGraph::addNodesForBlocks(DeclContext *D) {
  118. if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
  119. addNodeForDecl(BD, true);
  120. for (auto *I : D->decls())
  121. if (auto *DC = dyn_cast<DeclContext>(I))
  122. addNodesForBlocks(DC);
  123. }
  124. CallGraph::CallGraph() {
  125. Root = getOrInsertNode(nullptr);
  126. }
  127. CallGraph::~CallGraph() = default;
  128. bool CallGraph::includeInGraph(const Decl *D) {
  129. assert(D);
  130. if (!D->hasBody())
  131. return false;
  132. return includeCalleeInGraph(D);
  133. }
  134. bool CallGraph::includeCalleeInGraph(const Decl *D) {
  135. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
  136. // We skip function template definitions, as their semantics is
  137. // only determined when they are instantiated.
  138. if (FD->isDependentContext())
  139. return false;
  140. IdentifierInfo *II = FD->getIdentifier();
  141. if (II && II->getName().startswith("__inline"))
  142. return false;
  143. }
  144. return true;
  145. }
  146. void CallGraph::addNodeForDecl(Decl* D, bool IsGlobal) {
  147. assert(D);
  148. // Allocate a new node, mark it as root, and process its calls.
  149. CallGraphNode *Node = getOrInsertNode(D);
  150. // Process all the calls by this function as well.
  151. CGBuilder builder(this, Node);
  152. if (Stmt *Body = D->getBody())
  153. builder.Visit(Body);
  154. // Include C++ constructor member initializers.
  155. if (auto constructor = dyn_cast<CXXConstructorDecl>(D)) {
  156. for (CXXCtorInitializer *init : constructor->inits()) {
  157. builder.Visit(init->getInit());
  158. }
  159. }
  160. }
  161. CallGraphNode *CallGraph::getNode(const Decl *F) const {
  162. FunctionMapTy::const_iterator I = FunctionMap.find(F);
  163. if (I == FunctionMap.end()) return nullptr;
  164. return I->second.get();
  165. }
  166. CallGraphNode *CallGraph::getOrInsertNode(Decl *F) {
  167. if (F && !isa<ObjCMethodDecl>(F))
  168. F = F->getCanonicalDecl();
  169. std::unique_ptr<CallGraphNode> &Node = FunctionMap[F];
  170. if (Node)
  171. return Node.get();
  172. Node = std::make_unique<CallGraphNode>(F);
  173. // Make Root node a parent of all functions to make sure all are reachable.
  174. if (F)
  175. Root->addCallee({Node.get(), /*Call=*/nullptr});
  176. return Node.get();
  177. }
  178. void CallGraph::print(raw_ostream &OS) const {
  179. OS << " --- Call graph Dump --- \n";
  180. // We are going to print the graph in reverse post order, partially, to make
  181. // sure the output is deterministic.
  182. llvm::ReversePostOrderTraversal<const CallGraph *> RPOT(this);
  183. for (llvm::ReversePostOrderTraversal<const CallGraph *>::rpo_iterator
  184. I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
  185. const CallGraphNode *N = *I;
  186. OS << " Function: ";
  187. if (N == Root)
  188. OS << "< root >";
  189. else
  190. N->print(OS);
  191. OS << " calls: ";
  192. for (CallGraphNode::const_iterator CI = N->begin(),
  193. CE = N->end(); CI != CE; ++CI) {
  194. assert(CI->Callee != Root && "No one can call the root node.");
  195. CI->Callee->print(OS);
  196. OS << " ";
  197. }
  198. OS << '\n';
  199. }
  200. OS.flush();
  201. }
  202. LLVM_DUMP_METHOD void CallGraph::dump() const {
  203. print(llvm::errs());
  204. }
  205. void CallGraph::viewGraph() const {
  206. llvm::ViewGraph(this, "CallGraph");
  207. }
  208. void CallGraphNode::print(raw_ostream &os) const {
  209. if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(FD))
  210. return ND->printQualifiedName(os);
  211. os << "< >";
  212. }
  213. LLVM_DUMP_METHOD void CallGraphNode::dump() const {
  214. print(llvm::errs());
  215. }
  216. namespace llvm {
  217. template <>
  218. struct DOTGraphTraits<const CallGraph*> : public DefaultDOTGraphTraits {
  219. DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
  220. static std::string getNodeLabel(const CallGraphNode *Node,
  221. const CallGraph *CG) {
  222. if (CG->getRoot() == Node) {
  223. return "< root >";
  224. }
  225. if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Node->getDecl()))
  226. return ND->getNameAsString();
  227. else
  228. return "< >";
  229. }
  230. };
  231. } // namespace llvm