//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Templates to create dotty viewer and printer passes for GraphTraits graphs.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H

#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/GraphWriter.h"

namespace llvm {

/// Default traits class for extracting a graph from an analysis pass.
///
/// This assumes that 'GraphT' is 'AnalysisT::Result *', and pass it through
template <typename Result, typename GraphT = Result *>
struct DefaultAnalysisGraphTraits {
  static GraphT getGraph(Result R) { return &R; }
};

template <typename GraphT>
void viewGraphForFunction(Function &F, GraphT Graph, StringRef Name,
                          bool IsSimple) {
  std::string GraphName = DOTGraphTraits<GraphT *>::getGraphName(&Graph);

  ViewGraph(Graph, Name, IsSimple,
            GraphName + " for '" + F.getName() + "' function");
}

template <typename AnalysisT, bool IsSimple,
          typename GraphT = typename AnalysisT::Result *,
          typename AnalysisGraphTraitsT =
              DefaultAnalysisGraphTraits<typename AnalysisT::Result &, GraphT>>
struct DOTGraphTraitsViewer
    : PassInfoMixin<DOTGraphTraitsViewer<AnalysisT, IsSimple, GraphT,
                                         AnalysisGraphTraitsT>> {
  DOTGraphTraitsViewer(StringRef GraphName) : Name(GraphName) {}

  /// Return true if this function should be processed.
  ///
  /// An implementation of this class my override this function to indicate that
  /// only certain functions should be viewed.
  ///
  /// @param Result The current analysis result for this function.
  virtual bool processFunction(Function &F,
                               const typename AnalysisT::Result &Result) {
    return true;
  }

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
    auto &Result = FAM.getResult<AnalysisT>(F);
    if (!processFunction(F, Result))
      return PreservedAnalyses::all();

    GraphT Graph = AnalysisGraphTraitsT::getGraph(Result);
    viewGraphForFunction(F, Graph, Name, IsSimple);

    return PreservedAnalyses::all();
  };

protected:
  /// Avoid compiler warning "has virtual functions but non-virtual destructor
  /// [-Wnon-virtual-dtor]" in derived classes.
  ///
  /// DOTGraphTraitsViewer is also used as a mixin for avoiding repeated
  /// implementation of viewer passes, ie there should be no
  /// runtime-polymorphisms/downcasting involving this class and hence no
  /// virtual destructor needed. Making this dtor protected stops accidental
  /// invocation when the derived class destructor should have been called.
  /// Those derived classes sould be marked final to avoid the warning.
  ~DOTGraphTraitsViewer() {}

private:
  StringRef Name;
};

template <typename GraphT>
void printGraphForFunction(Function &F, GraphT Graph, StringRef Name,
                           bool IsSimple) {
  std::string Filename = Name.str() + "." + F.getName().str() + ".dot";
  std::error_code EC;

  errs() << "Writing '" << Filename << "'...";

  raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
  std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);

  if (!EC)
    WriteGraph(File, Graph, IsSimple,
               GraphName + " for '" + F.getName() + "' function");
  else
    errs() << "  error opening file for writing!";
  errs() << "\n";
}

template <typename AnalysisT, bool IsSimple,
          typename GraphT = typename AnalysisT::Result *,
          typename AnalysisGraphTraitsT =
              DefaultAnalysisGraphTraits<typename AnalysisT::Result &, GraphT>>
struct DOTGraphTraitsPrinter
    : PassInfoMixin<DOTGraphTraitsPrinter<AnalysisT, IsSimple, GraphT,
                                          AnalysisGraphTraitsT>> {
  DOTGraphTraitsPrinter(StringRef GraphName) : Name(GraphName) {}

  /// Return true if this function should be processed.
  ///
  /// An implementation of this class my override this function to indicate that
  /// only certain functions should be viewed.
  ///
  /// @param Result The current analysis result for this function.
  virtual bool processFunction(Function &F,
                               const typename AnalysisT::Result &Result) {
    return true;
  }

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
    auto &Result = FAM.getResult<AnalysisT>(F);
    if (!processFunction(F, Result))
      return PreservedAnalyses::all();

    GraphT Graph = AnalysisGraphTraitsT::getGraph(Result);

    printGraphForFunction(F, Graph, Name, IsSimple);

    return PreservedAnalyses::all();
  };

protected:
  /// Avoid compiler warning "has virtual functions but non-virtual destructor
  /// [-Wnon-virtual-dtor]" in derived classes.
  ///
  /// DOTGraphTraitsPrinter is also used as a mixin for avoiding repeated
  /// implementation of printer passes, ie there should be no
  /// runtime-polymorphisms/downcasting involving this class and hence no
  /// virtual destructor needed. Making this dtor protected stops accidental
  /// invocation when the derived class destructor should have been called.
  /// Those derived classes sould be marked final to avoid the warning.
  ~DOTGraphTraitsPrinter() {}

private:
  StringRef Name;
};

/// 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 LegacyDefaultAnalysisGraphTraits {
  static GraphT getGraph(AnalysisT *A) { return A; }
};

template <typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
          typename AnalysisGraphTraitsT =
              LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsViewerWrapperPass : public FunctionPass {
public:
  DOTGraphTraitsViewerWrapperPass(StringRef GraphName, char &ID)
      : FunctionPass(ID), Name(GraphName) {}

  /// Return true if this function should be processed.
  ///
  /// An implementation of this class my override this function to indicate that
  /// only certain functions should be viewed.
  ///
  /// @param Analysis The current analysis result for this function.
  virtual bool processFunction(Function &F, AnalysisT &Analysis) {
    return true;
  }

  bool runOnFunction(Function &F) override {
    auto &Analysis = getAnalysis<AnalysisT>();

    if (!processFunction(F, Analysis))
      return false;

    GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
    viewGraphForFunction(F, Graph, Name, IsSimple);

    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 =
              LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsPrinterWrapperPass : public FunctionPass {
public:
  DOTGraphTraitsPrinterWrapperPass(StringRef GraphName, char &ID)
      : FunctionPass(ID), Name(GraphName) {}

  /// Return true if this function should be processed.
  ///
  /// An implementation of this class my override this function to indicate that
  /// only certain functions should be printed.
  ///
  /// @param Analysis The current analysis result for this function.
  virtual bool processFunction(Function &F, AnalysisT &Analysis) {
    return true;
  }

  bool runOnFunction(Function &F) override {
    auto &Analysis = getAnalysis<AnalysisT>();

    if (!processFunction(F, Analysis))
      return false;

    GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
    printGraphForFunction(F, Graph, Name, IsSimple);

    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 =
              LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsModuleViewerWrapperPass : public ModulePass {
public:
  DOTGraphTraitsModuleViewerWrapperPass(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);

    ViewGraph(Graph, Name, IsSimple, Title);

    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 =
              LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsModulePrinterWrapperPass : public ModulePass {
public:
  DOTGraphTraitsModulePrinterWrapperPass(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::error_code EC;

    errs() << "Writing '" << Filename << "'...";

    raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
    std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);

    if (!EC)
      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 GraphT>
void WriteDOTGraphToFile(Function &F, GraphT &&Graph,
                         std::string FileNamePrefix, bool IsSimple) {
  std::string Filename = FileNamePrefix + "." + F.getName().str() + ".dot";
  std::error_code EC;

  errs() << "Writing '" << Filename << "'...";

  raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
  std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
  std::string Title = GraphName + " for '" + F.getName().str() + "' function";

  if (!EC)
    WriteGraph(File, Graph, IsSimple, Title);
  else
    errs() << "  error opening file for writing!";
  errs() << "\n";
}

} // end namespace llvm

#endif
