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