From 16a705f26d069a0c9e391bf064bcd1bc3496ca83 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Thu, 23 Jul 2009 09:04:23 +0000 Subject: [PATCH] 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 --- include/clang/Analysis/CallGraph.h | 58 ++++++++++++++++++++++++++++-- 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 +#include 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 FunctionMapTy; + typedef std::map FunctionMapTy; /// FunctionMap owns all CallGraphNodes. FunctionMapTy FunctionMap; @@ -60,6 +63,10 @@ class CallGraph { /// CallerCtx maps a caller to its ASTContext. llvm::DenseMap 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 { + typedef clang::CallGraph GraphType; + typedef clang::CallGraphNode NodeType; + + typedef std::pair CGNPairTy; + typedef std::pointer_to_unary_function CGNDerefFun; + + typedef mapped_iterator 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 PairTy; + typedef std::pointer_to_unary_function DerefFun; + + typedef mapped_iterator 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 : public DefaultDOTGraphTraits { + + static std::string getNodeLabel(const CallGraphNode *Node, + const CallGraph &CG, bool ShortNames) { + return Node->getName(); + + } + +}; + +} -- 2.50.1