Modernize raw_fd_ostream's constructor a bit.
[oota-llvm.git] / include / llvm / Analysis / DOTGraphTraitsPass.h
1 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Templates to create dotty viewer and printer passes for GraphTraits graphs.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
15 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
16
17 #include "llvm/Analysis/CFGPrinter.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Support/FileSystem.h"
20
21 namespace llvm {
22
23 /// \brief Default traits class for extracting a graph from an analysis pass.
24 ///
25 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
26 template <typename AnalysisT, typename GraphT = AnalysisT *>
27 struct DefaultAnalysisGraphTraits {
28   static GraphT getGraph(AnalysisT *A) { return A; }
29 };
30
31 template <
32     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
33     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
34 class DOTGraphTraitsViewer : public FunctionPass {
35 public:
36   DOTGraphTraitsViewer(StringRef GraphName, char &ID)
37       : FunctionPass(ID), Name(GraphName) {}
38
39   bool runOnFunction(Function &F) override {
40     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
41     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
42     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
43
44     ViewGraph(Graph, Name, IsSimple, Title);
45
46     return false;
47   }
48
49   void getAnalysisUsage(AnalysisUsage &AU) const override {
50     AU.setPreservesAll();
51     AU.addRequired<AnalysisT>();
52   }
53
54 private:
55   std::string Name;
56 };
57
58 template <
59     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
60     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
61 class DOTGraphTraitsPrinter : public FunctionPass {
62 public:
63   DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
64       : FunctionPass(ID), Name(GraphName) {}
65
66   bool runOnFunction(Function &F) override {
67     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
68     std::string Filename = Name + "." + F.getName().str() + ".dot";
69     std::error_code EC;
70
71     errs() << "Writing '" << Filename << "'...";
72
73     raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
74     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
75     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
76
77     if (!EC)
78       WriteGraph(File, Graph, IsSimple, Title);
79     else
80       errs() << "  error opening file for writing!";
81     errs() << "\n";
82
83     return false;
84   }
85
86   void getAnalysisUsage(AnalysisUsage &AU) const override {
87     AU.setPreservesAll();
88     AU.addRequired<AnalysisT>();
89   }
90
91 private:
92   std::string Name;
93 };
94
95 template <
96     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
97     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
98 class DOTGraphTraitsModuleViewer : public ModulePass {
99 public:
100   DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
101       : ModulePass(ID), Name(GraphName) {}
102
103   bool runOnModule(Module &M) override {
104     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
105     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
106
107     ViewGraph(Graph, Name, IsSimple, Title);
108
109     return false;
110   }
111
112   void getAnalysisUsage(AnalysisUsage &AU) const override {
113     AU.setPreservesAll();
114     AU.addRequired<AnalysisT>();
115   }
116
117 private:
118   std::string Name;
119 };
120
121 template <
122     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
123     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
124 class DOTGraphTraitsModulePrinter : public ModulePass {
125 public:
126   DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
127       : ModulePass(ID), Name(GraphName) {}
128
129   bool runOnModule(Module &M) override {
130     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
131     std::string Filename = Name + ".dot";
132     std::error_code EC;
133
134     errs() << "Writing '" << Filename << "'...";
135
136     raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
137     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
138
139     if (!EC)
140       WriteGraph(File, Graph, IsSimple, Title);
141     else
142       errs() << "  error opening file for writing!";
143     errs() << "\n";
144
145     return false;
146   }
147
148   void getAnalysisUsage(AnalysisUsage &AU) const override {
149     AU.setPreservesAll();
150     AU.addRequired<AnalysisT>();
151   }
152
153 private:
154   std::string Name;
155 };
156
157 } // end namespace llvm
158
159 #endif