]> granicus.if.org Git - clang/commitdiff
Add template specializations to view the call graph in dot format.
authorZhongxing Xu <xuzhongxing@gmail.com>
Thu, 23 Jul 2009 09:04:23 +0000 (09:04 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Thu, 23 Jul 2009 09:04:23 +0000 (09:04 +0000)
 - 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
lib/Analysis/CallGraph.cpp

index 9a05dad5790bc827a5294fa42373de46298c6c44..5725816f2441d5ab52a617b3e19d8e133ecb1100 100644 (file)
 #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
index 5605439ea94c3a8cd77934ba7f0e8c1b6fc692fa..bfc2c0d2194f5dd331680fbb3071f7926dee7444 100644 (file)
@@ -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();
+    
+  }
+
+};
+
+}