147 lines
4.2 KiB
C++
147 lines
4.2 KiB
C++
//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defined the CallGraph and CallGraphNode classes.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
|
|
#define LLVM_CLANG_ANALYSIS_CALLGRAPH
|
|
|
|
#include "clang/Index/ASTLocation.h"
|
|
#include "clang/Index/Entity.h"
|
|
#include "clang/Index/Program.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/GraphTraits.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
namespace clang {
|
|
|
|
class CallGraphNode {
|
|
idx::Entity F;
|
|
typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
|
|
std::vector<CallRecord> CalledFunctions;
|
|
|
|
public:
|
|
CallGraphNode(idx::Entity f) : F(f) {}
|
|
|
|
typedef std::vector<CallRecord>::iterator iterator;
|
|
typedef std::vector<CallRecord>::const_iterator const_iterator;
|
|
|
|
iterator begin() { return CalledFunctions.begin(); }
|
|
iterator end() { return CalledFunctions.end(); }
|
|
const_iterator begin() const { return CalledFunctions.begin(); }
|
|
const_iterator end() const { return CalledFunctions.end(); }
|
|
|
|
void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
|
|
CalledFunctions.push_back(std::make_pair(L, Node));
|
|
}
|
|
|
|
bool hasCallee() const { return begin() != end(); }
|
|
|
|
std::string getName() const { return F.getPrintableName(); }
|
|
|
|
Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
|
|
};
|
|
|
|
class CallGraph {
|
|
/// Program manages all Entities.
|
|
idx::Program &Prog;
|
|
|
|
typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
|
|
|
|
/// FunctionMap owns all CallGraphNodes.
|
|
FunctionMapTy FunctionMap;
|
|
|
|
/// CallerCtx maps a caller to its ASTContext.
|
|
llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
|
|
|
|
/// Root node is the 'main' function or 0.
|
|
CallGraphNode *Root;
|
|
|
|
/// ExternalCallingNode has edges to all external functions.
|
|
CallGraphNode *ExternalCallingNode;
|
|
|
|
public:
|
|
CallGraph(idx::Program &P);
|
|
~CallGraph();
|
|
|
|
typedef FunctionMapTy::iterator iterator;
|
|
typedef FunctionMapTy::const_iterator const_iterator;
|
|
|
|
iterator begin() { return FunctionMap.begin(); }
|
|
iterator end() { return FunctionMap.end(); }
|
|
const_iterator begin() const { return FunctionMap.begin(); }
|
|
const_iterator end() const { return FunctionMap.end(); }
|
|
|
|
CallGraphNode *getRoot() { return Root; }
|
|
|
|
CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
|
|
|
|
void addTU(ASTContext &AST);
|
|
|
|
idx::Program &getProgram() { return Prog; }
|
|
|
|
CallGraphNode *getOrInsertFunction(idx::Entity F);
|
|
|
|
Decl *getDecl(CallGraphNode *Node);
|
|
|
|
void print(raw_ostream &os);
|
|
void dump();
|
|
|
|
void ViewCallGraph() const;
|
|
};
|
|
|
|
} // end clang namespace
|
|
|
|
namespace llvm {
|
|
|
|
template <> struct GraphTraits<clang::CallGraph> {
|
|
typedef clang::CallGraph GraphType;
|
|
typedef clang::CallGraphNode NodeType;
|
|
|
|
typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
|
|
typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;
|
|
|
|
typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
|
|
|
|
static NodeType *getEntryNode(GraphType *CG) {
|
|
return CG->getExternalCallingNode();
|
|
}
|
|
|
|
static ChildIteratorType child_begin(NodeType *N) {
|
|
return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
|
|
}
|
|
static ChildIteratorType child_end(NodeType *N) {
|
|
return map_iterator(N->end(), CGNDerefFun(CGNDeref));
|
|
}
|
|
|
|
typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
|
|
typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;
|
|
|
|
typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;
|
|
|
|
static nodes_iterator nodes_begin(const GraphType &CG) {
|
|
return map_iterator(CG.begin(), DerefFun(CGDeref));
|
|
}
|
|
static nodes_iterator nodes_end(const GraphType &CG) {
|
|
return map_iterator(CG.end(), DerefFun(CGDeref));
|
|
}
|
|
|
|
static NodeType *CGNDeref(CGNPairTy P) { return P.second; }
|
|
|
|
static NodeType *CGDeref(PairTy P) { return P.second; }
|
|
};
|
|
|
|
} // end llvm namespace
|
|
|
|
#endif
|