10b57cec5SDimitry Andric //===-- llvm/Support/DOTGraphTraits.h - Customize .dot output ---*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines a template class that can be used to customize dot output 100b57cec5SDimitry Andric // graphs generated by the GraphWriter.h file. The default implementation of 110b57cec5SDimitry Andric // this file will produce a simple, but not very polished graph. By 120b57cec5SDimitry Andric // specializing this template, lots of customization opportunities are possible. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H 170b57cec5SDimitry Andric #define LLVM_SUPPORT_DOTGRAPHTRAITS_H 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #include <string> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric /// DefaultDOTGraphTraits - This class provides the default implementations of 240b57cec5SDimitry Andric /// all of the DOTGraphTraits methods. If a specialization does not need to 250b57cec5SDimitry Andric /// override all methods here it should inherit so that it can get the default 260b57cec5SDimitry Andric /// implementations. 270b57cec5SDimitry Andric /// 280b57cec5SDimitry Andric struct DefaultDOTGraphTraits { 290b57cec5SDimitry Andric private: 300b57cec5SDimitry Andric bool IsSimple; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric protected: isSimpleDefaultDOTGraphTraits330b57cec5SDimitry Andric bool isSimple() { 340b57cec5SDimitry Andric return IsSimple; 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric public: IsSimpleDefaultDOTGraphTraits380b57cec5SDimitry Andric explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {} 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric /// getGraphName - Return the label for the graph as a whole. Printed at the 410b57cec5SDimitry Andric /// top of the graph. 420b57cec5SDimitry Andric /// 430b57cec5SDimitry Andric template<typename GraphType> getGraphNameDefaultDOTGraphTraits440b57cec5SDimitry Andric static std::string getGraphName(const GraphType &) { return ""; } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric /// getGraphProperties - Return any custom properties that should be included 470b57cec5SDimitry Andric /// in the top level graph structure for dot. 480b57cec5SDimitry Andric /// 490b57cec5SDimitry Andric template<typename GraphType> getGraphPropertiesDefaultDOTGraphTraits500b57cec5SDimitry Andric static std::string getGraphProperties(const GraphType &) { 510b57cec5SDimitry Andric return ""; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric /// renderGraphFromBottomUp - If this function returns true, the graph is 550b57cec5SDimitry Andric /// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work 560b57cec5SDimitry Andric /// though. renderGraphFromBottomUpDefaultDOTGraphTraits570b57cec5SDimitry Andric static bool renderGraphFromBottomUp() { 580b57cec5SDimitry Andric return false; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric /// isNodeHidden - If the function returns true, the given node is not 620b57cec5SDimitry Andric /// displayed in the graph. 63e8d8bef9SDimitry Andric template <typename GraphType> isNodeHiddenDefaultDOTGraphTraits64e8d8bef9SDimitry Andric static bool isNodeHidden(const void *, const GraphType &) { 650b57cec5SDimitry Andric return false; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 68349cc55cSDimitry Andric // renderNodesUsingHTML - If the function returns true, nodes will be 69349cc55cSDimitry Andric // rendered using HTML-like labels which allows colors, etc in the nodes 70349cc55cSDimitry Andric // and the edge source labels. renderNodesUsingHTMLDefaultDOTGraphTraits71349cc55cSDimitry Andric static bool renderNodesUsingHTML() { return false; } 72349cc55cSDimitry Andric 730b57cec5SDimitry Andric /// getNodeLabel - Given a node and a pointer to the top level graph, return 740b57cec5SDimitry Andric /// the label to print in the node. 750b57cec5SDimitry Andric template<typename GraphType> getNodeLabelDefaultDOTGraphTraits760b57cec5SDimitry Andric std::string getNodeLabel(const void *, const GraphType &) { 770b57cec5SDimitry Andric return ""; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric // getNodeIdentifierLabel - Returns a string representing the 810b57cec5SDimitry Andric // address or other unique identifier of the node. (Only used if 820b57cec5SDimitry Andric // non-empty.) 830b57cec5SDimitry Andric template <typename GraphType> getNodeIdentifierLabelDefaultDOTGraphTraits840b57cec5SDimitry Andric static std::string getNodeIdentifierLabel(const void *, const GraphType &) { 850b57cec5SDimitry Andric return ""; 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric template<typename GraphType> getNodeDescriptionDefaultDOTGraphTraits890b57cec5SDimitry Andric static std::string getNodeDescription(const void *, const GraphType &) { 900b57cec5SDimitry Andric return ""; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric /// If you want to specify custom node attributes, this is the place to do so 940b57cec5SDimitry Andric /// 950b57cec5SDimitry Andric template<typename GraphType> getNodeAttributesDefaultDOTGraphTraits960b57cec5SDimitry Andric static std::string getNodeAttributes(const void *, 970b57cec5SDimitry Andric const GraphType &) { 980b57cec5SDimitry Andric return ""; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric /// If you want to override the dot attributes printed for a particular edge, 1020b57cec5SDimitry Andric /// override this method. 1030b57cec5SDimitry Andric template<typename EdgeIter, typename GraphType> getEdgeAttributesDefaultDOTGraphTraits1040b57cec5SDimitry Andric static std::string getEdgeAttributes(const void *, EdgeIter, 1050b57cec5SDimitry Andric const GraphType &) { 1060b57cec5SDimitry Andric return ""; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric /// getEdgeSourceLabel - If you want to label the edge source itself, 1100b57cec5SDimitry Andric /// implement this method. 1110b57cec5SDimitry Andric template<typename EdgeIter> getEdgeSourceLabelDefaultDOTGraphTraits1120b57cec5SDimitry Andric static std::string getEdgeSourceLabel(const void *, EdgeIter) { 1130b57cec5SDimitry Andric return ""; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /// edgeTargetsEdgeSource - This method returns true if this outgoing edge 1170b57cec5SDimitry Andric /// should actually target another edge source, not a node. If this method is 1180b57cec5SDimitry Andric /// implemented, getEdgeTarget should be implemented. 1190b57cec5SDimitry Andric template<typename EdgeIter> edgeTargetsEdgeSourceDefaultDOTGraphTraits1200b57cec5SDimitry Andric static bool edgeTargetsEdgeSource(const void *, EdgeIter) { 1210b57cec5SDimitry Andric return false; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is 1250b57cec5SDimitry Andric /// called to determine which outgoing edge of Node is the target of this 1260b57cec5SDimitry Andric /// edge. 1270b57cec5SDimitry Andric template<typename EdgeIter> getEdgeTargetDefaultDOTGraphTraits1280b57cec5SDimitry Andric static EdgeIter getEdgeTarget(const void *, EdgeIter I) { 1290b57cec5SDimitry Andric return I; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric /// hasEdgeDestLabels - If this function returns true, the graph is able 1330b57cec5SDimitry Andric /// to provide labels for edge destinations. hasEdgeDestLabelsDefaultDOTGraphTraits1340b57cec5SDimitry Andric static bool hasEdgeDestLabels() { 1350b57cec5SDimitry Andric return false; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the 1390b57cec5SDimitry Andric /// number of incoming edge labels the given node has. numEdgeDestLabelsDefaultDOTGraphTraits1400b57cec5SDimitry Andric static unsigned numEdgeDestLabels(const void *) { 1410b57cec5SDimitry Andric return 0; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the 1450b57cec5SDimitry Andric /// incoming edge label with the given index in the given node. getEdgeDestLabelDefaultDOTGraphTraits1460b57cec5SDimitry Andric static std::string getEdgeDestLabel(const void *, unsigned) { 1470b57cec5SDimitry Andric return ""; 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric /// addCustomGraphFeatures - If a graph is made up of more than just 1510b57cec5SDimitry Andric /// straight-forward nodes and edges, this is the place to put all of the 1520b57cec5SDimitry Andric /// custom stuff necessary. The GraphWriter object, instantiated with your 1530b57cec5SDimitry Andric /// GraphType is passed in as an argument. You may call arbitrary methods on 1540b57cec5SDimitry Andric /// it to add things to the output graph. 1550b57cec5SDimitry Andric /// 1560b57cec5SDimitry Andric template<typename GraphType, typename GraphWriter> addCustomGraphFeaturesDefaultDOTGraphTraits1570b57cec5SDimitry Andric static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {} 1580b57cec5SDimitry Andric }; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// DOTGraphTraits - Template class that can be specialized to customize how 1620b57cec5SDimitry Andric /// graphs are converted to 'dot' graphs. When specializing, you may inherit 1630b57cec5SDimitry Andric /// from DefaultDOTGraphTraits if you don't need to override everything. 1640b57cec5SDimitry Andric /// 1650b57cec5SDimitry Andric template <typename Ty> 1660b57cec5SDimitry Andric struct DOTGraphTraits : public DefaultDOTGraphTraits { DefaultDOTGraphTraitsDOTGraphTraits1670b57cec5SDimitry Andric DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {} 1680b57cec5SDimitry Andric }; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric } // End llvm namespace 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric #endif 173