diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-07-23 09:04:23 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-07-23 09:04:23 +0000 |
commit | 16a705f26d069a0c9e391bf064bcd1bc3496ca83 (patch) | |
tree | 2eec057bfcb602f27de4d4029da5cddebafaa3bf | |
parent | f7856437cfcf49523d81ebe1fc2351e3284dedfa (diff) |
Add template specializations to view the call graph in dot format.
- change the DenseMap used in callgraph to std::map, since DenseMap cannot
be used with mapped_iterator and friends.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76874 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/CallGraph.h | 58 | ||||
-rw-r--r-- | lib/Analysis/CallGraph.cpp | 21 |
2 files changed, 76 insertions, 3 deletions
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h index 9a05dad579..5725816f24 100644 --- a/include/clang/Analysis/CallGraph.h +++ b/include/clang/Analysis/CallGraph.h @@ -19,7 +19,10 @@ #include "clang/Index/Program.h" #include "clang/Frontend/ASTUnit.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/STLExtras.h" #include <vector> +#include <map> namespace clang { @@ -45,14 +48,14 @@ public: bool hasCallee() const { return begin() != end(); } - std::string getName() { return F.getPrintableName(); } + std::string getName() const { return F.getPrintableName(); } }; class CallGraph { /// Program manages all Entities. idx::Program Prog; - typedef llvm::DenseMap<idx::Entity, CallGraphNode *> FunctionMapTy; + typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy; /// FunctionMap owns all CallGraphNodes. FunctionMapTy FunctionMap; @@ -60,6 +63,10 @@ class CallGraph { /// CallerCtx maps a caller to its ASTContext. llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx; + /// Entry node of the call graph. + // FIXME: find the entry of the graph. + CallGraphNode *Entry; + public: ~CallGraph(); @@ -71,6 +78,8 @@ public: const_iterator begin() const { return FunctionMap.begin(); } const_iterator end() const { return FunctionMap.end(); } + CallGraphNode *getEntry() { return Entry; } + void addTU(ASTUnit &AST); idx::Program &getProgram() { return Prog; } @@ -79,8 +88,51 @@ public: void print(llvm::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->getEntry(); + } + + 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 diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp index 5605439ea9..bfc2c0d219 100644 --- a/lib/Analysis/CallGraph.cpp +++ b/lib/Analysis/CallGraph.cpp @@ -16,6 +16,8 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/StmtVisitor.h" +#include "llvm/Support/GraphWriter.h" + using namespace clang; using namespace idx; @@ -111,3 +113,22 @@ void CallGraph::print(llvm::raw_ostream &os) { void CallGraph::dump() { print(llvm::errs()); } + +void CallGraph::ViewCallGraph() const { + llvm::ViewGraph(*this, "CallGraph"); +} + +namespace llvm { + +template <> +struct DOTGraphTraits<CallGraph> : public DefaultDOTGraphTraits { + + static std::string getNodeLabel(const CallGraphNode *Node, + const CallGraph &CG, bool ShortNames) { + return Node->getName(); + + } + +}; + +} |