#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include "llvm/Support/DOTGraphTraits.h" #include "revng/MFP/Graph.h" #include "revng/Support/DOTGraphTraits.h" namespace llvm { class Instruction; } template struct llvm::DOTGraphTraits *> { static_assert(MFP::SerializableLatticeElement); using GraphType = const MFP::Graph *; using UnderlyingGraphType = MFI::GraphType; using UnderlyingDOTGraphTraits = llvm::DOTGraphTraits; using NodeRef = llvm::GraphTraits::NodeRef; DOTGraphTraits() = default; DOTGraphTraits(bool IsSimple) {} static std::string getGraphName(const GraphType &G) { return UnderlyingDOTGraphTraits::getGraphName(G->underlying()); } static std::string getGraphProperties(const GraphType &G) { return UnderlyingDOTGraphTraits::getGraphProperties(G->underlying()); } static bool renderGraphFromBottomUp() { return UnderlyingDOTGraphTraits::renderGraphFromBottomUp(); } static bool isNodeHidden(const NodeRef &Arg, const GraphType &G) { return UnderlyingDOTGraphTraits::isNodeHidden(Arg, G->underlying()); } static bool renderNodesUsingHTML() { return UnderlyingDOTGraphTraits::renderNodesUsingHTML(); } std::string getNodeLabel(const NodeRef &Arg, const GraphType &G) { std::string Result; bool UseHTML = renderNodesUsingHTML(); std::string Newline = UseHTML ? HTMLNewline : "\\l"; { llvm::raw_string_ostream Stream(Result); auto AnalysisResult = G->results().at(Arg); // Dump underlying graph node label Stream << UnderlyingDOTGraphTraits::getNodeLabel(Arg, G->underlying()); Stream << Newline << Newline; auto Dump = [&Newline](const auto &ToDump, StringRef Name) { std::string Result; { llvm::raw_string_ostream Stream(Result); Stream << Name.str() << " value:" << "\n"; MFP::dump(Stream, 1, ToDump); } replaceAll(Result, "\n", Newline); return Result; }; // Dump initial value if (UseHTML) Stream << ""; Stream << Dump(AnalysisResult.InValue, "Initial"); Stream << Newline; Stream << Dump(AnalysisResult.OutValue, "Final"); Stream << Newline; if (UseHTML) Stream << ""; } return Result; } static std::string getNodeIdentifierLabel(const NodeRef &Arg, const GraphType &G) { return UnderlyingDOTGraphTraits::getNodeIdentifierLabel(Arg, G->underlying()); } static std::string getNodeDescription(const NodeRef &Arg, const GraphType &G) { return UnderlyingDOTGraphTraits::getNodeDescription(Arg, G->underlying()); } static std::string getNodeAttributes(const NodeRef &Arg, const GraphType &G) { return UnderlyingDOTGraphTraits::getNodeAttributes(Arg, G->underlying()); } template static std::string getEdgeAttributes(const NodeRef &Arg, EdgeIter It, GraphType G) { return UnderlyingDOTGraphTraits::getEdgeAttributes(Arg, It, G->underlying()); } template static std::string getEdgeSourceLabel(const NodeRef &Arg, EdgeIter It) { return UnderlyingDOTGraphTraits::getEdgeSourceLabel(Arg, It); } template static bool edgeTargetsEdgeSource(const NodeRef &Arg, EdgeIter It) { return UnderlyingDOTGraphTraits::edgeTargetsEdgeSource(Arg, It); } template static EdgeIter getEdgeTarget(const NodeRef &Arg, EdgeIter It) { return UnderlyingDOTGraphTraits::getEdgeTarget(Arg, It); } static bool hasEdgeDestLabels() { return UnderlyingDOTGraphTraits::hasEdgeDestLabels(); } static unsigned numEdgeDestLabels(const NodeRef &Arg) { return UnderlyingDOTGraphTraits::numEdgeDestLabels(Arg); } static std::string getEdgeDestLabel(const NodeRef &Arg1, unsigned Arg2) { return UnderlyingDOTGraphTraits::getEdgeDestLabel(Arg1, Arg2); } template static void addCustomGraphFeatures(GraphType G, GraphWriter &Writer) { UnderlyingDOTGraphTraits::addCustomGraphFeatures(G->underlying(), Writer); } }; template struct llvm::DOTGraphTraits *> : llvm::DOTGraphTraits *> {};