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
14252723Sdim#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
15252723Sdim#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
16202878Srdivacky
17252723Sdim#include "llvm/Analysis/CFGPrinter.h"
18202878Srdivacky#include "llvm/Pass.h"
19202878Srdivacky
20202878Srdivackynamespace llvm {
21252723Sdim
22202878Srdivackytemplate <class Analysis, bool Simple>
23252723Sdimclass DOTGraphTraitsViewer : public FunctionPass {
24252723Sdimpublic:
25252723Sdim  DOTGraphTraitsViewer(StringRef GraphName, char &ID)
26252723Sdim    : FunctionPass(ID), Name(GraphName) {}
27202878Srdivacky
28252723Sdim  virtual bool runOnFunction(Function &F) {
29252723Sdim    Analysis *Graph = &getAnalysis<Analysis>();
30252723Sdim    std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
31252723Sdim    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  }
42252723Sdim
43252723Sdimprivate:
44252723Sdim  std::string Name;
45202878Srdivacky};
46202878Srdivacky
47202878Srdivackytemplate <class Analysis, bool Simple>
48252723Sdimclass DOTGraphTraitsPrinter : public FunctionPass {
49252723Sdimpublic:
50252723Sdim  DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
51252723Sdim    : FunctionPass(ID), Name(GraphName) {}
52202878Srdivacky
53252723Sdim  virtual bool runOnFunction(Function &F) {
54252723Sdim    Analysis *Graph = &getAnalysis<Analysis>();
55252723Sdim    std::string Filename = Name + "." + F.getName().str() + ".dot";
56252723Sdim    std::string ErrorInfo;
57252723Sdim
58252723Sdim    errs() << "Writing '" << Filename << "'...";
59252723Sdim
60252723Sdim    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
61252723Sdim    std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
62252723Sdim    std::string Title = GraphName + " for '" + F.getName().str() + "' function";
63252723Sdim
64252723Sdim    if (ErrorInfo.empty())
65252723Sdim      WriteGraph(File, Graph, Simple, Title);
66252723Sdim    else
67252723Sdim      errs() << "  error opening file for writing!";
68252723Sdim    errs() << "\n";
69252723Sdim
70252723Sdim    return false;
71252723Sdim  }
72252723Sdim
73252723Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
74252723Sdim    AU.setPreservesAll();
75252723Sdim    AU.addRequired<Analysis>();
76252723Sdim  }
77252723Sdim
78252723Sdimprivate:
79202878Srdivacky  std::string Name;
80252723Sdim};
81202878Srdivacky
82252723Sdimtemplate <class Analysis, bool Simple>
83252723Sdimclass DOTGraphTraitsModuleViewer : public ModulePass {
84252723Sdimpublic:
85252723Sdim  DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
86252723Sdim    : ModulePass(ID), Name(GraphName) {}
87252723Sdim
88252723Sdim  virtual bool runOnModule(Module &M) {
89252723Sdim    Analysis *Graph = &getAnalysis<Analysis>();
90252723Sdim    std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
91252723Sdim
92252723Sdim    ViewGraph(Graph, Name, Simple, Title);
93252723Sdim
94252723Sdim    return false;
95202878Srdivacky  }
96202878Srdivacky
97252723Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
98252723Sdim    AU.setPreservesAll();
99252723Sdim    AU.addRequired<Analysis>();
100252723Sdim  }
101252723Sdim
102252723Sdimprivate:
103252723Sdim  std::string Name;
104252723Sdim};
105252723Sdim
106252723Sdimtemplate <class Analysis, bool Simple>
107252723Sdimclass DOTGraphTraitsModulePrinter : public ModulePass {
108252723Sdimpublic:
109252723Sdim  DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
110252723Sdim    : ModulePass(ID), Name(GraphName) {}
111252723Sdim
112252723Sdim  virtual bool runOnModule(Module &M) {
113252723Sdim    Analysis *Graph = &getAnalysis<Analysis>();
114252723Sdim    std::string Filename = Name + ".dot";
115252723Sdim    std::string ErrorInfo;
116252723Sdim
117202878Srdivacky    errs() << "Writing '" << Filename << "'...";
118202878Srdivacky
119202878Srdivacky    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
120252723Sdim    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";
127252723Sdim
128202878Srdivacky    return false;
129202878Srdivacky  }
130202878Srdivacky
131202878Srdivacky  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
132202878Srdivacky    AU.setPreservesAll();
133202878Srdivacky    AU.addRequired<Analysis>();
134202878Srdivacky  }
135252723Sdim
136252723Sdimprivate:
137252723Sdim  std::string Name;
138202878Srdivacky};
139252723Sdim
140252723Sdim} // end namespace llvm
141252723Sdim
142202878Srdivacky#endif
143