1202878Srdivacky//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
2202878Srdivacky//
3202878Srdivacky//                     The LLVM Compiler Infrastructure
4202878Srdivacky//
5202878Srdivacky// This file is distributed under the University of Illinois Open Source
6202878Srdivacky// License. See LICENSE.TXT for details.
7202878Srdivacky//
8202878Srdivacky//===----------------------------------------------------------------------===//
9202878Srdivacky//
10202878Srdivacky// Templates to create dotty viewer and printer passes for GraphTraits graphs.
11202878Srdivacky//
12202878Srdivacky//===----------------------------------------------------------------------===//
13202878Srdivacky
14249423Sdim#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
15249423Sdim#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
16202878Srdivacky
17249423Sdim#include "llvm/Analysis/CFGPrinter.h"
18202878Srdivacky#include "llvm/Pass.h"
19202878Srdivacky
20202878Srdivackynamespace llvm {
21249423Sdim
22202878Srdivackytemplate <class Analysis, bool Simple>
23249423Sdimclass DOTGraphTraitsViewer : public FunctionPass {
24249423Sdimpublic:
25249423Sdim  DOTGraphTraitsViewer(StringRef GraphName, char &ID)
26249423Sdim    : FunctionPass(ID), Name(GraphName) {}
27202878Srdivacky
28249423Sdim  virtual bool runOnFunction(Function &F) {
29249423Sdim    Analysis *Graph = &getAnalysis<Analysis>();
30249423Sdim    std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
31249423Sdim    std::string Title = GraphName + " for '" + F.getName().str() + "' function";
32202878Srdivacky
33202878Srdivacky    ViewGraph(Graph, Name, Simple, Title);
34202878Srdivacky
35202878Srdivacky    return false;
36202878Srdivacky  }
37202878Srdivacky
38202878Srdivacky  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
39202878Srdivacky    AU.setPreservesAll();
40202878Srdivacky    AU.addRequired<Analysis>();
41202878Srdivacky  }
42249423Sdim
43249423Sdimprivate:
44249423Sdim  std::string Name;
45202878Srdivacky};
46202878Srdivacky
47202878Srdivackytemplate <class Analysis, bool Simple>
48249423Sdimclass DOTGraphTraitsPrinter : public FunctionPass {
49249423Sdimpublic:
50249423Sdim  DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
51249423Sdim    : FunctionPass(ID), Name(GraphName) {}
52202878Srdivacky
53249423Sdim  virtual bool runOnFunction(Function &F) {
54249423Sdim    Analysis *Graph = &getAnalysis<Analysis>();
55249423Sdim    std::string Filename = Name + "." + F.getName().str() + ".dot";
56249423Sdim    std::string ErrorInfo;
57249423Sdim
58249423Sdim    errs() << "Writing '" << Filename << "'...";
59249423Sdim
60249423Sdim    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
61249423Sdim    std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
62249423Sdim    std::string Title = GraphName + " for '" + F.getName().str() + "' function";
63249423Sdim
64249423Sdim    if (ErrorInfo.empty())
65249423Sdim      WriteGraph(File, Graph, Simple, Title);
66249423Sdim    else
67249423Sdim      errs() << "  error opening file for writing!";
68249423Sdim    errs() << "\n";
69249423Sdim
70249423Sdim    return false;
71249423Sdim  }
72249423Sdim
73249423Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
74249423Sdim    AU.setPreservesAll();
75249423Sdim    AU.addRequired<Analysis>();
76249423Sdim  }
77249423Sdim
78249423Sdimprivate:
79202878Srdivacky  std::string Name;
80249423Sdim};
81202878Srdivacky
82249423Sdimtemplate <class Analysis, bool Simple>
83249423Sdimclass DOTGraphTraitsModuleViewer : public ModulePass {
84249423Sdimpublic:
85249423Sdim  DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
86249423Sdim    : ModulePass(ID), Name(GraphName) {}
87249423Sdim
88249423Sdim  virtual bool runOnModule(Module &M) {
89249423Sdim    Analysis *Graph = &getAnalysis<Analysis>();
90249423Sdim    std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
91249423Sdim
92249423Sdim    ViewGraph(Graph, Name, Simple, Title);
93249423Sdim
94249423Sdim    return false;
95202878Srdivacky  }
96202878Srdivacky
97249423Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
98249423Sdim    AU.setPreservesAll();
99249423Sdim    AU.addRequired<Analysis>();
100249423Sdim  }
101249423Sdim
102249423Sdimprivate:
103249423Sdim  std::string Name;
104249423Sdim};
105249423Sdim
106249423Sdimtemplate <class Analysis, bool Simple>
107249423Sdimclass DOTGraphTraitsModulePrinter : public ModulePass {
108249423Sdimpublic:
109249423Sdim  DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
110249423Sdim    : ModulePass(ID), Name(GraphName) {}
111249423Sdim
112249423Sdim  virtual bool runOnModule(Module &M) {
113249423Sdim    Analysis *Graph = &getAnalysis<Analysis>();
114249423Sdim    std::string Filename = Name + ".dot";
115249423Sdim    std::string ErrorInfo;
116249423Sdim
117202878Srdivacky    errs() << "Writing '" << Filename << "'...";
118202878Srdivacky
119202878Srdivacky    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
120249423Sdim    std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
121202878Srdivacky
122202878Srdivacky    if (ErrorInfo.empty())
123218893Sdim      WriteGraph(File, Graph, Simple, Title);
124202878Srdivacky    else
125202878Srdivacky      errs() << "  error opening file for writing!";
126202878Srdivacky    errs() << "\n";
127249423Sdim
128202878Srdivacky    return false;
129202878Srdivacky  }
130202878Srdivacky
131202878Srdivacky  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
132202878Srdivacky    AU.setPreservesAll();
133202878Srdivacky    AU.addRequired<Analysis>();
134202878Srdivacky  }
135249423Sdim
136249423Sdimprivate:
137249423Sdim  std::string Name;
138202878Srdivacky};
139249423Sdim
140249423Sdim} // end namespace llvm
141249423Sdim
142202878Srdivacky#endif
143