CallGraph.cpp revision a50a5cd9db67f061c94557d188b992be34ccad2f
1196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//== CallGraph.cpp - AST-based Call graph  ----------------------*- C++ -*--==//
2196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//
3196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//                     The LLVM Compiler Infrastructure
4196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//
5196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// This file is distributed under the University of Illinois Open Source
6196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// License. See LICENSE.TXT for details.
7196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//
8196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
9196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//
10196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//  This file defines the AST-based CallGraph.
11196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//
12196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
13196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/Analysis/CallGraph.h"
14196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
15196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/AST/ASTContext.h"
16196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/AST/Decl.h"
17196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/AST/StmtVisitor.h"
18196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
19196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "llvm/Support/GraphWriter.h"
20196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
21196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksusing namespace clang;
22196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
23196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks/// Determine if a declaration should be included in the graph.
24196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksstatic bool includeInGraph(const Decl *D) {
25196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
26196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    // We skip function template definitions, as their semantics is
27196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    // only determined when they are instantiated.
28196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (!FD->isThisDeclarationADefinition() ||
29196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        FD->isDependentContext())
30196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      return false;
31196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
32196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    IdentifierInfo *II = FD->getIdentifier();
33196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (II && II->getName().startswith("__inline"))
34196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      return false;
35196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
36196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
37196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) {
38196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (!ID->isThisDeclarationADefinition())
39196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      return false;
40196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
41196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
42196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  return true;
43196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
44196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
45196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace {
46196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks/// A helper class, which walks the AST and locates all the call sites in the
47196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks/// given function body.
48196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CGBuilder : public StmtVisitor<CGBuilder> {
49196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CallGraph *G;
50196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  const Decl *FD;
51196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CallGraphNode *CallerNode;
52196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
53196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic:
54196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CGBuilder(CallGraph *g, const Decl *D, CallGraphNode *N)
55196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    : G(g), FD(D), CallerNode(N) {}
56196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
57196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  void VisitStmt(Stmt *S) { VisitChildren(S); }
58196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
59196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  void VisitCallExpr(CallExpr *CE) {
60196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    // TODO: We need to handle ObjC method calls as well.
61196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (FunctionDecl *CalleeDecl = CE->getDirectCallee())
62196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      if (includeInGraph(CalleeDecl)) {
63196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        CallGraphNode *CalleeNode = G->getOrInsertFunction(CalleeDecl);
64196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        CallerNode->addCallee(CalleeNode, G);
65196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      }
66a50a5cd9db67f061c94557d188b992be34ccad2fDaniel Dunbar  }
67196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
68196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  void VisitChildren(Stmt *S) {
69196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    for (Stmt::child_range I = S->children(); I; ++I)
70196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      if (*I)
71196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        static_cast<CGBuilder*>(this)->Visit(*I);
72196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
73196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks};
74196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} // end anonymous namespace
75196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
76196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna ZaksCallGraph::CallGraph() {
77196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  Root = getOrInsertFunction(0);
78196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
79196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
80196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna ZaksCallGraph::~CallGraph() {
81196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (!FunctionMap.empty()) {
82196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
83196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        I != E; ++I)
84196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      delete I->second;
85196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    FunctionMap.clear();
86196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
87196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
88196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
89196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraph::addToCallGraph(Decl* D, bool IsGlobal) {
90196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CallGraphNode *Node = getOrInsertFunction(D);
91196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
92196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (IsGlobal)
93196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    Root->addCallee(Node, this);
94196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
95196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  // Process all the calls by this function as well.
96196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CGBuilder builder(this, D, Node);
97196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  builder.Visit(D->getBody());
98196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
99196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
100196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraph::addToCallGraph(DeclContext *DC) {
101196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
102196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks       I != E; ++I) {
103196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    Decl *D = *I;
104196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    switch (D->getKind()) {
105196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::CXXConstructor:
106196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::CXXDestructor:
107196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::CXXConversion:
108196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::CXXMethod:
109196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::Function: {
110196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      FunctionDecl *FD = cast<FunctionDecl>(D);
111196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      // We skip function template definitions, as their semantics is
112196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      // only determined when they are instantiated.
113196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      if (includeInGraph(FD))
114196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        // If this function has external linkage, anything could call it.
115196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        // Note, we are not precise here. For example, the function could have
116196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        // its address taken.
117196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        addToCallGraph(FD, FD->isGlobal());
118196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      break;
119196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    }
120196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
121196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::ObjCCategoryImpl:
122196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    case Decl::ObjCImplementation: {
123196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      ObjCImplDecl *ID = cast<ObjCImplDecl>(D);
124196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      for (ObjCContainerDecl::method_iterator MI = ID->meth_begin(),
125196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks          ME = ID->meth_end(); MI != ME; ++MI) {
126196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        if (includeInGraph(*MI))
127196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks          addToCallGraph(*MI, true);
128196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      }
129196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      break;
130196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    }
131196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
132196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    default:
133196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      break;
134196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    }
135196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
136196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
137196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
138196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna ZaksCallGraphNode *CallGraph::getOrInsertFunction(Decl *F) {
139196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  CallGraphNode *&Node = FunctionMap[F];
140196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (Node)
141196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    return Node;
142196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
143196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  Node = new CallGraphNode(F);
144196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  ParentlessNodes.insert(Node);
145196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  return Node;
146196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
147196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
148196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraph::print(raw_ostream &OS) const {
149196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  OS << " --- Call graph Dump --- \n";
150196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  for (const_iterator I = begin(), E = end(); I != E; ++I) {
151196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    OS << "  Function: ";
152196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (I->second == Root)
153196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      OS << "< root >";
154196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    else
155196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      I->second->print(OS);
156196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    OS << " calls: ";
157196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    for (CallGraphNode::iterator CI = I->second->begin(),
158196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks        CE = I->second->end(); CI != CE; ++CI) {
159196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      assert(*CI != Root && "No one can call the root node.");
160196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      (*CI)->print(OS);
161196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      OS << " ";
162196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    }
163196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    OS << '\n';
164196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
165196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  OS.flush();
166196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
167196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
168196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraph::dump() const {
169196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  print(llvm::errs());
170196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
171196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
172196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraph::viewGraph() const {
173196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  llvm::ViewGraph(this, "CallGraph");
174196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
175196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
176196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna ZaksStringRef CallGraphNode::getName() const {
177196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  if (const FunctionDecl *D = dyn_cast_or_null<FunctionDecl>(FD))
178196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (const IdentifierInfo *II = D->getIdentifier())
179196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      return II->getName();
180196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    return "< >";
181196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
182196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
183196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraphNode::print(raw_ostream &os) const {
184196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  os << getName();
185196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
186196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
187196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid CallGraphNode::dump() const {
188196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  print(llvm::errs());
189196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
190196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
191196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace llvm {
192196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
193196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakstemplate <>
194196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksstruct DOTGraphTraits<const CallGraph*> : public DefaultDOTGraphTraits {
195196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
196196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
197196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
198196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  static std::string getNodeLabel(const CallGraphNode *Node,
199196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks                                  const CallGraph *CG) {
200196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    if (CG->getRoot() == Node) {
201196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks      return "< root >";
202196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    }
203196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    return Node->getName();
204196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
205196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
206196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks};
207196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
208