forked from OSchip/llvm-project
Add two nodes to the call graph:
- Root is the main function or 0. - ExternalCallingNode has edges to all external functions. llvm-svn: 76876
This commit is contained in:
parent
a598e5c9d5
commit
ee5d708e55
|
@ -63,11 +63,14 @@ class CallGraph {
|
||||||
/// CallerCtx maps a caller to its ASTContext.
|
/// CallerCtx maps a caller to its ASTContext.
|
||||||
llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
|
llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
|
||||||
|
|
||||||
/// Entry node of the call graph.
|
/// Root node is the 'main' function or 0.
|
||||||
// FIXME: find the entry of the graph.
|
CallGraphNode *Root;
|
||||||
CallGraphNode *Entry;
|
|
||||||
|
/// ExternalCallingNode has edges to all external functions.
|
||||||
|
CallGraphNode *ExternalCallingNode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CallGraph();
|
||||||
~CallGraph();
|
~CallGraph();
|
||||||
|
|
||||||
typedef FunctionMapTy::iterator iterator;
|
typedef FunctionMapTy::iterator iterator;
|
||||||
|
@ -78,7 +81,9 @@ public:
|
||||||
const_iterator begin() const { return FunctionMap.begin(); }
|
const_iterator begin() const { return FunctionMap.begin(); }
|
||||||
const_iterator end() const { return FunctionMap.end(); }
|
const_iterator end() const { return FunctionMap.end(); }
|
||||||
|
|
||||||
CallGraphNode *getEntry() { return Entry; }
|
CallGraphNode *getRoot() { return Root; }
|
||||||
|
|
||||||
|
CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
|
||||||
|
|
||||||
void addTU(ASTUnit &AST);
|
void addTU(ASTUnit &AST);
|
||||||
|
|
||||||
|
@ -106,7 +111,7 @@ template <> struct GraphTraits<clang::CallGraph> {
|
||||||
typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
|
typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
|
||||||
|
|
||||||
static NodeType *getEntryNode(GraphType *CG) {
|
static NodeType *getEntryNode(GraphType *CG) {
|
||||||
return CG->getEntry();
|
return CG->getExternalCallingNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChildIteratorType child_begin(NodeType *N) {
|
static ChildIteratorType child_begin(NodeType *N) {
|
||||||
|
|
|
@ -58,6 +58,10 @@ void CGBuilder::VisitCallExpr(CallExpr *CE) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallGraph::CallGraph() : Root(0) {
|
||||||
|
ExternalCallingNode = getOrInsertFunction(Entity());
|
||||||
|
}
|
||||||
|
|
||||||
CallGraph::~CallGraph() {
|
CallGraph::~CallGraph() {
|
||||||
if (!FunctionMap.empty()) {
|
if (!FunctionMap.empty()) {
|
||||||
for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
|
for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
|
||||||
|
@ -80,6 +84,14 @@ void CallGraph::addTU(ASTUnit &AST) {
|
||||||
Entity Ent = Entity::get(FD, Prog);
|
Entity Ent = Entity::get(FD, Prog);
|
||||||
CallGraphNode *Node = getOrInsertFunction(Ent);
|
CallGraphNode *Node = getOrInsertFunction(Ent);
|
||||||
CallerCtx[Node] = &Ctx;
|
CallerCtx[Node] = &Ctx;
|
||||||
|
|
||||||
|
// If this function has external linkage, anything could call it.
|
||||||
|
if (FD->isGlobal())
|
||||||
|
ExternalCallingNode->addCallee(idx::ASTLocation(), Node);
|
||||||
|
|
||||||
|
// Set root node to 'main' function.
|
||||||
|
if (FD->getNameAsString() == "main")
|
||||||
|
Root = Node;
|
||||||
|
|
||||||
CGBuilder builder(*this, FD, Ent, Node);
|
CGBuilder builder(*this, FD, Ent, Node);
|
||||||
builder.Visit(FD->getBody());
|
builder.Visit(FD->getBody());
|
||||||
|
|
|
@ -65,5 +65,5 @@ int main(int argc, char **argv) {
|
||||||
for (unsigned i = 0, e = TUnits.size(); i != e; ++i)
|
for (unsigned i = 0, e = TUnits.size(); i != e; ++i)
|
||||||
CG->addTU(*(TUnits[i]->AST));
|
CG->addTU(*(TUnits[i]->AST));
|
||||||
|
|
||||||
CG->dump();
|
CG->ViewCallGraph();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue