blob: 5605439ea94c3a8cd77934ba7f0e8c1b6fc692fa [file] [log] [blame]
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +00001//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defined the CallGraph and CGBuilder classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Analysis/CallGraph.h"
15
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/StmtVisitor.h"
18
19using namespace clang;
20using namespace idx;
21
22namespace {
23class CGBuilder : public StmtVisitor<CGBuilder> {
24
25 CallGraph &G;
26 FunctionDecl *FD;
27
Argyrios Kyrtzidisf7cf15c2009-07-21 00:07:06 +000028 Entity CallerEnt;
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000029
30 CallGraphNode *CallerNode;
31
32public:
Argyrios Kyrtzidisf7cf15c2009-07-21 00:07:06 +000033 CGBuilder(CallGraph &g, FunctionDecl *fd, Entity E, CallGraphNode *N)
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000034 : G(g), FD(fd), CallerEnt(E), CallerNode(N) {}
35
Zhongxing Xu93cbae32009-07-18 08:49:07 +000036 void VisitStmt(Stmt *S) { VisitChildren(S); }
Zhongxing Xu24ff0302009-07-17 05:49:16 +000037
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000038 void VisitCallExpr(CallExpr *CE);
39
40 void VisitChildren(Stmt *S) {
41 for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I != E;++I)
42 if (*I)
43 static_cast<CGBuilder*>(this)->Visit(*I);
44 }
45};
46}
47
48void CGBuilder::VisitCallExpr(CallExpr *CE) {
Zhongxing Xua0042542009-07-17 07:29:51 +000049 if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) {
Argyrios Kyrtzidisf7cf15c2009-07-21 00:07:06 +000050 Entity Ent = Entity::get(CalleeDecl, G.getProgram());
Zhongxing Xua0042542009-07-17 07:29:51 +000051 CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent);
Zhongxing Xu7f66bd22009-07-17 07:36:20 +000052
53 Decl *Parent = ASTLocation::FindImmediateParent(FD, CE);
54
55 CallerNode->addCallee(ASTLocation(Parent, CE), CalleeNode);
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000056 }
57}
58
59CallGraph::~CallGraph() {
60 if (!FunctionMap.empty()) {
61 for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
62 I != E; ++I)
63 delete I->second;
64 FunctionMap.clear();
65 }
66}
67
68void CallGraph::addTU(ASTUnit &AST) {
69 ASTContext &Ctx = AST.getASTContext();
70 DeclContext *DC = Ctx.getTranslationUnitDecl();
71
72 for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
73 I != E; ++I) {
74
75 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
76 if (FD->isThisDeclarationADefinition()) {
77 // Set caller's ASTContext.
Argyrios Kyrtzidisf7cf15c2009-07-21 00:07:06 +000078 Entity Ent = Entity::get(FD, Prog);
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000079 CallGraphNode *Node = getOrInsertFunction(Ent);
80 CallerCtx[Node] = &Ctx;
81
82 CGBuilder builder(*this, FD, Ent, Node);
83 builder.Visit(FD->getBody());
84 }
85 }
86 }
87}
88
Argyrios Kyrtzidisf7cf15c2009-07-21 00:07:06 +000089CallGraphNode *CallGraph::getOrInsertFunction(Entity F) {
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +000090 CallGraphNode *&Node = FunctionMap[F];
91 if (Node)
92 return Node;
93
94 return Node = new CallGraphNode(F);
95}
96
97void CallGraph::print(llvm::raw_ostream &os) {
98 for (iterator I = begin(), E = end(); I != E; ++I) {
Zhongxing Xu24ff0302009-07-17 05:49:16 +000099 if (I->second->hasCallee()) {
Argyrios Kyrtzidis4c7c5a12009-07-21 07:52:21 +0000100 os << "function: " << I->first.getPrintableName()
Zhongxing Xu56aac3f2009-07-17 07:49:44 +0000101 << " calls:\n";
Zhongxing Xu24ff0302009-07-17 05:49:16 +0000102 for (CallGraphNode::iterator CI = I->second->begin(),
103 CE = I->second->end(); CI != CE; ++CI) {
Argyrios Kyrtzidis4c7c5a12009-07-21 07:52:21 +0000104 os << " " << CI->second->getName().c_str();
Zhongxing Xu24ff0302009-07-17 05:49:16 +0000105 }
106 os << '\n';
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +0000107 }
Zhongxing Xu6bd8fb52009-07-16 00:54:12 +0000108 }
109}
110
111void CallGraph::dump() {
112 print(llvm::errs());
113}