//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
-#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
+#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
-#include "llvm/Pass.h"
#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/FileSystem.h"
namespace llvm {
-template <class Analysis, bool Simple>
-struct DOTGraphTraitsViewer : public FunctionPass {
- std::string Name;
- DOTGraphTraitsViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
- Name = GraphName;
- }
+/// \brief Default traits class for extracting a graph from an analysis pass.
+///
+/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
+template <typename AnalysisT, typename GraphT = AnalysisT *>
+struct DefaultAnalysisGraphTraits {
+ static GraphT getGraph(AnalysisT *A) { return A; }
+};
+
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsViewer : public FunctionPass {
+public:
+ DOTGraphTraitsViewer(StringRef GraphName, char &ID)
+ : FunctionPass(ID), Name(GraphName) {}
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph;
- std::string Title, GraphName;
- Graph = &getAnalysis<Analysis>();
- GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- Title = GraphName + " for '" + F.getNameStr() + "' function";
- ViewGraph(Graph, Name, Simple, Title);
+ bool runOnFunction(Function &F) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
+ std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
+ ViewGraph(Graph, Name, IsSimple, Title);
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
+
+private:
+ std::string Name;
};
-template <class Analysis, bool Simple>
-struct DOTGraphTraitsPrinter : public FunctionPass {
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsPrinter : public FunctionPass {
+public:
+ DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
+ : FunctionPass(ID), Name(GraphName) {}
+
+ bool runOnFunction(Function &F) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string Filename = Name + "." + F.getName().str() + ".dot";
+ std::string ErrorInfo;
+
+ errs() << "Writing '" << Filename << "'...";
+
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+ std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
+ std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
+ if (ErrorInfo.empty())
+ WriteGraph(File, Graph, IsSimple, Title);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<AnalysisT>();
+ }
+private:
std::string Name;
+};
+
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsModuleViewer : public ModulePass {
+public:
+ DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
+ : ModulePass(ID), Name(GraphName) {}
+
+ bool runOnModule(Module &M) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
- DOTGraphTraitsPrinter(std::string GraphName, const void *ID)
- : FunctionPass(ID) {
- Name = GraphName;
+ ViewGraph(Graph, Name, IsSimple, Title);
+
+ return false;
}
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph;
- std::string Filename = Name + "." + F.getNameStr() + ".dot";
- errs() << "Writing '" << Filename << "'...";
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<AnalysisT>();
+ }
+private:
+ std::string Name;
+};
+
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsModulePrinter : public ModulePass {
+public:
+ DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
+ : ModulePass(ID), Name(GraphName) {}
+
+ bool runOnModule(Module &M) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string Filename = Name + ".dot";
std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
- Graph = &getAnalysis<Analysis>();
- std::string Title, GraphName;
- GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- Title = GraphName + " for '" + F.getNameStr() + "' function";
+ errs() << "Writing '" << Filename << "'...";
+
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+ std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
if (ErrorInfo.empty())
- WriteGraph(File, Graph, Simple, Name, Title);
+ WriteGraph(File, Graph, IsSimple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
+
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
+
+private:
+ std::string Name;
};
-}
+
+} // end namespace llvm
+
#endif