Jlm
Loading...
Searching...
No Matches
GraphWriter.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#ifndef JLM_UTIL_GRAPHWRITER_HPP
7#define JLM_UTIL_GRAPHWRITER_HPP
8
9#include <jlm/util/common.hpp>
10
11#include <cstdint>
12#include <memory>
13#include <optional>
14#include <type_traits>
15#include <unordered_map>
16#include <variant>
17#include <vector>
18
19namespace jlm::util::graph
20{
21
22enum class OutputFormat
23{
24 Dot, // prints the graphs in the GraphViz dot format
25 Json, // prints a json object containing all the graphs
26 ASCII, // Textual output format that makes edges implicit when possible
27};
28
30{
31 SpaceSeparatedList, // printed on the form attr=value other="value 2"
32 HTMLAttributes, // adds extra restrictions on attribute names
33 JSON // outputs a comma separated list of "name": "value" pairs
34};
35
36class Writer;
37class Node;
38class Edge;
39class Port;
40class Graph;
41
43{
44public:
45 virtual ~GraphElement() = default;
46
51
52 GraphElement(const GraphElement & other) = delete;
53
54 GraphElement(GraphElement && other) = delete;
55
57 operator=(const GraphElement & other) = delete;
58
60 operator=(GraphElement && other) = delete;
61
67 [[nodiscard]] virtual const char *
68 GetIdPrefix() const = 0;
69
75 void
76 PrintFullId(std::ostream & out) const;
77
84 [[nodiscard]] std::string
85 GetFullId() const;
86
90 [[nodiscard]] virtual Graph &
91 GetGraph() = 0;
92
93 [[nodiscard]] const Graph &
94 GetGraph() const;
95
102 void
103 SetLabel(std::string label);
104
109 void
110 AppendToLabel(std::string_view text, std::string_view sep = "\n");
111
115 [[nodiscard]] bool
116 HasLabel() const;
117
121 [[nodiscard]] const std::string &
122 GetLabel() const;
123
127 [[nodiscard]] std::string_view
128 GetLabelOr(std::string_view otherwise) const;
129
134 [[nodiscard]] size_t
135 GetUniqueIdSuffix() const;
136
146 template<typename T>
147 void
148 SetProgramObject(const T & object)
149 {
150 SetProgramObjectUintptr(reinterpret_cast<uintptr_t>(&object));
151 }
152
156 void
158
162 [[nodiscard]] bool
163 HasProgramObject() const noexcept;
164
168 [[nodiscard]] uintptr_t
169 GetProgramObject() const noexcept;
170
176 void
177 SetAttribute(const std::string & attribute, std::string value);
178
186 void
187 SetAttributeObject(const std::string & attribute, uintptr_t object);
188
192 template<typename T>
193 void
194 SetAttributeObject(const std::string & attribute, const T & object)
195 {
196 static_assert(!std::is_pointer_v<T>, "Sending a reference to a pointer is likely a bug");
197 SetAttributeObject(attribute, reinterpret_cast<uintptr_t>(&object));
198 }
199
207 void
208 SetAttributeGraphElement(const std::string & attribute, const GraphElement & element);
209
213 [[nodiscard]] bool
214 HasAttribute(const std::string & attribute) const;
215
220 [[nodiscard]] std::optional<std::string_view>
221 GetAttributeString(const std::string & attribute) const;
222
228 [[nodiscard]] std::optional<uintptr_t>
229 GetAttributeObject(const std::string & attribute) const;
230
237 [[nodiscard]] const GraphElement *
238 GetAttributeGraphElement(const std::string & attribute) const;
239
244 bool
245 RemoveAttribute(const std::string & attribute);
246
250 virtual void
251 Finalize();
252
256 [[nodiscard]] bool
257 IsFinalized() const;
258
264 void
265 OutputAttributes(std::ostream & out, AttributeOutputFormat format) const;
266
283 void
284 outputJsonObjectOpening(std::ostream & out, size_t indent, bool & firstField) const;
285
286private:
287 // The types an attribute can have. Its value can be a string, a reference to a
288 // GraphElement, or a reference to a program object.
289 using AttributeValue = std::variant<std::string, const GraphElement *, uintptr_t>;
290
291 void
292 SetProgramObjectUintptr(uintptr_t object);
293
294 void
295 OutputAttribute(std::ostream & out, const std::string & name, AttributeOutputFormat format) const;
296
297 // A human-readable piece of text that should be rendered with the element
298 std::string Label_;
299
300 // A number added to the end of the id stub to make it globally unique
301 std::optional<size_t> UniqueIdSuffix_;
302
303 // The object in the program this graph object corresponds to, or 0 if none
304 uintptr_t ProgramObject_;
305
306 // All other attributes
307 std::unordered_map<std::string, AttributeValue> AttributeMap_;
308};
309
313class Port : public GraphElement
314{
315 friend Edge;
316
317protected:
318 Port();
319
320public:
321 ~Port() override = default;
322
323 virtual Node &
324 GetNode() = 0;
325
326 Graph &
327 GetGraph() override;
328
332 [[nodiscard]] virtual bool
333 CanBeEdgeHead() const;
334
338 [[nodiscard]] virtual bool
339 CanBeEdgeTail() const;
340
344 [[nodiscard]] const std::vector<Edge *> &
345 GetConnections() const;
346
350 [[nodiscard]] bool
351 HasOutgoingEdges() const;
352
356 [[nodiscard]] bool
357 HasIncomingEdges() const;
358
364 virtual void
365 SetFillColor(std::string color) = 0;
366
371 virtual void
372 OutputDotPortId(std::ostream & out) const = 0;
373
380 void
381 OutputIncomingEdgesASCII(std::ostream & out) const;
382
383private:
388 void
389 OnEdgeAdded(Edge & edge);
390
391 std::vector<Edge *> Connections_;
392};
393
398class Node : public Port
399{
400 friend Graph;
401
402protected:
403 explicit Node(Graph & graph);
404
405public:
406 ~Node() override = default;
407
408 const char *
409 GetIdPrefix() const override;
410
411 Node &
412 GetNode() override;
413
417 Graph &
418 GetGraph() override;
419
424 virtual void
425 SetShape(std::string shape);
426
431 struct Shape
432 {
433 static inline const char * const Rectangle = "rect";
434 static inline const char * const Circle = "circle";
435 static inline const char * const Oval = "oval";
436 static inline const char * const Point = "point";
437 static inline const char * const Plain = "plain";
438 static inline const char * const Plaintext = "plaintext";
439 static inline const char * const Triangle = "triangle";
440 static inline const char * const DoubleCircle = "doublecircle";
441 };
442
443 void
444 SetFillColor(std::string color) override;
445
446 void
447 OutputDotPortId(std::ostream & out) const override;
448
454 virtual void
455 OutputSubgraphs(std::ostream & out, OutputFormat format, size_t indent) const;
456
462 virtual void
463 OutputASCII(std::ostream & out, size_t indent) const;
464
469 virtual void
470 OutputDot(std::ostream & out, size_t indent) const;
471
476 virtual void
477 outputJson(std::ostream & out, size_t indent) const;
478
479private:
481};
482
483class InOutNode;
484class InputPort;
485class OutputPort;
486
490class InputPort final : public Port
491{
492 friend InOutNode;
493
494 explicit InputPort(InOutNode & node);
495
496public:
497 ~InputPort() override = default;
498
499 const char *
500 GetIdPrefix() const override;
501
502 Node &
503 GetNode() override;
504
505 bool
506 CanBeEdgeTail() const override;
507
508 void
509 SetFillColor(std::string color) override;
510
511 void
512 OutputDotPortId(std::ostream & out) const override;
513
514 void
515 outputJson(std::ostream & out, size_t indent) const;
516
517private:
519};
520
524class OutputPort final : public Port
525{
526 friend InOutNode;
527
528 explicit OutputPort(InOutNode & node);
529
530public:
531 ~OutputPort() override = default;
532
533 const char *
534 GetIdPrefix() const override;
535
536 Node &
537 GetNode() override;
538
539 bool
540 CanBeEdgeHead() const override;
541
542 void
543 SetFillColor(std::string color) override;
544
545 void
546 OutputDotPortId(std::ostream & out) const override;
547
548 void
549 outputJson(std::ostream & out, size_t indent) const;
550
551private:
553};
554
560class InOutNode final : public Node
561{
562 friend Graph;
563
564 InOutNode(Graph & graph, size_t inputPorts, size_t outputPorts);
565
566public:
567 ~InOutNode() override = default;
568
572 void SetShape(std::string) override;
573
574 InputPort &
576
577 size_t
578 NumInputPorts() const;
579
580 InputPort &
581 GetInputPort(size_t index);
582
583 OutputPort &
585
586 size_t
587 NumOutputPorts() const;
588
589 OutputPort &
590 GetOutputPort(size_t index);
591
596 Graph &
598
602 size_t
603 NumSubgraphs() const;
604
608 Graph &
609 GetSubgraph(size_t index);
610
619 void
620 SetHtmlTableAttribute(std::string name, std::string value);
621
622 void
623 SetFillColor(std::string color) override;
624
625 void
626 Finalize() override;
627
628 void
629 OutputSubgraphs(std::ostream & out, OutputFormat format, size_t indent) const override;
630
631 void
632 OutputASCII(std::ostream & out, size_t indent) const override;
633
634 void
635 OutputDot(std::ostream & out, size_t indent) const override;
636
637 void
638 outputJson(std::ostream & out, size_t indent) const override;
639
640private:
641 // Attributes that need to be placed on the HTML table in the dot output, and not on the node.
642 std::unordered_map<std::string, std::string> HtmlTableAttributes_;
643
644 std::vector<std::unique_ptr<InputPort>> InputPorts_;
645 std::vector<std::unique_ptr<OutputPort>> OutputPorts_;
646 std::vector<Graph *> SubGraphs_;
647};
648
653class ArgumentNode : public Node
654{
655 friend Graph;
656
657 explicit ArgumentNode(Graph & graph);
658
659public:
660 ~ArgumentNode() override = default;
661
662 const char *
663 GetIdPrefix() const override;
664
665 bool
666 CanBeEdgeHead() const override;
667
672 void
673 SetOutsideSource(const Port & outsideSource);
674
675protected:
676 void
677 OutputASCII(std::ostream & out, size_t indent) const override;
678
679private:
680 // Optional reference to a Port outside of this graph from which this argument came
682};
683
688class ResultNode : public Node
689{
690 friend Graph;
691
692 explicit ResultNode(Graph & graph);
693
694public:
695 ~ResultNode() override = default;
696
697 const char *
698 GetIdPrefix() const override;
699
700 bool
701 CanBeEdgeTail() const override;
702
707 void
708 SetOutsideDestination(const Port & outsideSource);
709
710protected:
711 void
712 OutputASCII(std::ostream & out, size_t indent) const override;
713
714private:
715 // Optional reference to a Port outside of this graph representing where the result ends up
717};
718
719class Edge : public GraphElement
720{
721 friend Graph;
722
723 Edge(Port & from, Port & to, bool directed);
724
725public:
726 ~Edge() override = default;
727
728 const char *
729 GetIdPrefix() const override;
730
731 Graph &
732 GetGraph() override;
733
738 [[nodiscard]] Port &
739 GetFrom();
740
745 [[nodiscard]] Port &
746 GetTo();
747
751 [[nodiscard]] bool
752 IsDirected() const;
753
757 [[nodiscard]] Port &
758 GetOtherEnd(const Port & end);
759
764 void
765 SetStyle(std::string style);
766
770 struct Style
771 {
772 static inline const char * const Solid = "solid";
773 static inline const char * const Dashed = "dashed";
774 static inline const char * const Dotted = "dotted";
775 static inline const char * const Invisible = "invis";
776 static inline const char * const Bold = "bold";
777 static inline const char * const Tapered = "tapered";
778 };
779
788 void
789 SetArrowHead(std::string arrow);
790
796 void
797 SetArrowTail(std::string arrow);
798
805 std::string_view
806 getDirection() const;
807
811 void
812 OutputDot(std::ostream & out, size_t indent) const;
813
817 void
818 outputJson(std::ostream & out, size_t indent) const;
819
820private:
824};
825
826class Graph : public GraphElement
827{
828 friend Writer;
830
831 explicit Graph(Writer & writer);
832
833 Graph(Writer & writer, Node & parentNode);
834
835public:
836 ~Graph() override = default;
837
838 const char *
839 GetIdPrefix() const override;
840
841 Graph &
842 GetGraph() override;
843
844 [[nodiscard]] Writer &
845 GetWriter();
846
847 [[nodiscard]] const Writer &
848 GetWriter() const;
849
853 [[nodiscard]] bool
854 IsSubgraph() const;
855
860 [[nodiscard]] Node &
861 CreateNode();
862
869 [[nodiscard]] InOutNode &
870 CreateInOutNode(size_t inputPorts, size_t outputPorts);
871
875 [[nodiscard]] size_t
876 NumNodes() const noexcept;
877
883 [[nodiscard]] Node &
884 GetNode(size_t index);
885
890 [[nodiscard]] ArgumentNode &
892
896 [[nodiscard]] size_t
897 NumArgumentNodes() const noexcept;
898
903 [[nodiscard]] Node &
904 GetArgumentNode(size_t index);
905
910 [[nodiscard]] ResultNode &
912
916 [[nodiscard]] size_t
917 NumResultNodes() const noexcept;
918
923 [[nodiscard]] Node &
924 GetResultNode(size_t index);
925
934 Edge &
935 CreateEdge(Port & from, Port & to, bool directed);
936
942 Edge &
944 {
945 return CreateEdge(from, to, true);
946 }
947
954 Edge &
956 {
957 return CreateEdge(a, b, false);
958 }
959
963 [[nodiscard]] size_t
964 NumEdges() const noexcept;
965
970 [[nodiscard]] Edge &
971 GetEdge(size_t index);
972
979 [[nodiscard]] Edge *
980 GetEdgeBetween(Port & a, Port & b);
981
988 [[nodiscard]] GraphElement *
989 GetElementFromProgramObject(uintptr_t object) const;
990
991 template<typename T>
992 [[nodiscard]] GraphElement *
993 GetElementFromProgramObject(const T & object) const
994 {
995 // Check that object is not a reference to a pointer.
996 // If the user truly wants to use the address of a pointer, they can cast it to uintptr_t.
997 static_assert(!std::is_pointer_v<T>);
998 return GetElementFromProgramObject(reinterpret_cast<uintptr_t>(&object));
999 }
1000
1008 template<typename Element, typename ProgramObject>
1009 Element &
1010 GetFromProgramObject(const ProgramObject & object) const
1011 {
1012 static_assert(std::is_base_of_v<GraphElement, Element>);
1013 GraphElement * element = GetElementFromProgramObject(object);
1014 auto result = dynamic_cast<Element *>(element);
1015 JLM_ASSERT(result);
1016 return *result;
1017 }
1018
1023 void
1024 Finalize() override;
1025
1033 void
1034 Output(std::ostream & out, OutputFormat format, size_t indent) const;
1035
1036private:
1037 void
1038 OutputASCII(std::ostream & out, size_t indent) const;
1039
1040 void
1041 OutputDot(std::ostream & out, size_t indent) const;
1042
1043 void
1044 outputJson(std::ostream & out, size_t indent) const;
1045
1051 void
1053
1058 void
1059 RemoveProgramObjectMapping(uintptr_t object);
1060
1061 // The GraphWriter this graph was created by, and belongs to
1063
1064 // If this graph is a subgraph, this is its parent node in the parent graph.
1065 // For top level graphs, this field is nullptr
1067
1068 // The set of nodes in the graph. Finalizing the graph may re-order this list.
1069 std::vector<std::unique_ptr<Node>> Nodes_;
1070
1071 // Argument nodes and result nodes are kept in separate lists
1072 std::vector<std::unique_ptr<ArgumentNode>> ArgumentNodes_;
1073 std::vector<std::unique_ptr<ResultNode>> ResultNodes_;
1074
1075 std::vector<std::unique_ptr<Edge>> Edges_;
1076
1077 // A mapping from pointers to program objects, to the GraphElement representing the program object
1078 std::unordered_map<uintptr_t, GraphElement *> ProgramObjectMapping_;
1079};
1080
1086{
1087public:
1088 ~Writer() = default;
1089
1090 Writer() = default;
1091
1092 Writer(const Writer & other) = delete;
1093
1094 Writer(Writer && other) = delete;
1095
1096 Writer &
1097 operator=(const Writer & other) = delete;
1098
1099 Writer &
1100 operator=(Writer && other) = delete;
1101
1106 [[nodiscard]] Graph &
1107 CreateGraph();
1108
1112 [[nodiscard]] size_t
1113 NumGraphs() const noexcept;
1114
1118 [[nodiscard]] Graph &
1119 GetGraph(size_t index);
1120
1125 [[nodiscard]] GraphElement *
1126 GetElementFromProgramObject(uintptr_t object) const;
1127
1128 template<typename T>
1129 [[nodiscard]] GraphElement *
1130 GetElementFromProgramObject(const T & object) const
1131 {
1132 // Check that object is not a reference to a pointer.
1133 // If the user truly wants to use the address of a pointer, they can cast it to uintptr_t.
1134 static_assert(!std::is_pointer_v<T>);
1135 return GetElementFromProgramObject(reinterpret_cast<uintptr_t>(&object));
1136 }
1137
1142 void
1143 Finalize();
1144
1150 void
1151 outputAllGraphs(std::ostream & out, OutputFormat format);
1152
1153private:
1154 [[nodiscard]] Graph &
1155 CreateSubGraph(Node & parentNode);
1156
1157 friend Graph &
1159
1164 [[nodiscard]] size_t
1165 GetNextUniqueIdStubSuffix(const char * idStub);
1166
1167 friend void
1169
1170 // All graphs being worked on by the GraphWriter
1171 // Edges can not go across graphs.
1172 // IDs are however unique across graphs allowing semantic connections.
1173 std::vector<std::unique_ptr<Graph>> Graphs_;
1174
1175 // Tracks the next integer to be used when assigning a unique suffix to a given id stub
1176 std::unordered_map<std::string, size_t> NextUniqueIdStubSuffix_;
1177};
1178
1183namespace Colors
1184{
1185inline const char * const Black = "#000000";
1186inline const char * const Blue = "#0000FF";
1187inline const char * const Coral = "#FF7F50";
1188inline const char * const CornflowerBlue = "#6495ED";
1189inline const char * const Firebrick = " #B22222";
1190inline const char * const Gold = "#FFD700";
1191inline const char * const Gray = "#BEBEBE";
1192inline const char * const Green = "#00FF00";
1193inline const char * const Orange = "#FFA500";
1194inline const char * const Purple = "#A020F0";
1195inline const char * const Red = "#FF0000";
1196inline const char * const Brown = "#8B4513"; // X11's Saddle Brown
1197inline const char * const SkyBlue = "#87CEEB";
1198inline const char * const White = "#FFFFFF";
1199inline const char * const Yellow = "#FFFF00";
1200}
1201
1202}
1203#endif // JLM_UTIL_GRAPHWRITER_HPP
bool CanBeEdgeHead() const override
void SetOutsideSource(const Port &outsideSource)
const char * GetIdPrefix() const override
~ArgumentNode() override=default
void OutputASCII(std::ostream &out, size_t indent) const override
void SetStyle(std::string style)
void SetArrowTail(std::string arrow)
Port & GetOtherEnd(const Port &end)
const char * GetIdPrefix() const override
Graph & GetGraph() override
std::string_view getDirection() const
void OutputDot(std::ostream &out, size_t indent) const
void SetArrowHead(std::string arrow)
~Edge() override=default
void outputJson(std::ostream &out, size_t indent) const
void outputJsonObjectOpening(std::ostream &out, size_t indent, bool &firstField) const
void SetProgramObject(const T &object)
void SetLabel(std::string label)
uintptr_t GetProgramObject() const noexcept
std::string GetFullId() const
void SetAttributeObject(const std::string &attribute, uintptr_t object)
virtual ~GraphElement()=default
virtual Graph & GetGraph()=0
std::variant< std::string, const GraphElement *, uintptr_t > AttributeValue
void AppendToLabel(std::string_view text, std::string_view sep="\n")
GraphElement & operator=(GraphElement &&other)=delete
void SetAttribute(const std::string &attribute, std::string value)
std::string_view GetLabelOr(std::string_view otherwise) const
GraphElement(const GraphElement &other)=delete
const std::string & GetLabel() const
void PrintFullId(std::ostream &out) const
bool RemoveAttribute(const std::string &attribute)
GraphElement(GraphElement &&other)=delete
GraphElement & operator=(const GraphElement &other)=delete
virtual const char * GetIdPrefix() const =0
std::optional< uintptr_t > GetAttributeObject(const std::string &attribute) const
std::unordered_map< std::string, AttributeValue > AttributeMap_
void OutputAttribute(std::ostream &out, const std::string &name, AttributeOutputFormat format) const
void OutputAttributes(std::ostream &out, AttributeOutputFormat format) const
bool HasAttribute(const std::string &attribute) const
const GraphElement * GetAttributeGraphElement(const std::string &attribute) const
std::optional< size_t > UniqueIdSuffix_
std::optional< std::string_view > GetAttributeString(const std::string &attribute) const
void SetProgramObjectUintptr(uintptr_t object)
void SetAttributeGraphElement(const std::string &attribute, const GraphElement &element)
bool HasProgramObject() const noexcept
std::vector< std::unique_ptr< ArgumentNode > > ArgumentNodes_
ArgumentNode & CreateArgumentNode()
Node & GetNode(size_t index)
void Output(std::ostream &out, OutputFormat format, size_t indent) const
GraphElement * GetElementFromProgramObject(uintptr_t object) const
std::unordered_map< uintptr_t, GraphElement * > ProgramObjectMapping_
Node & GetResultNode(size_t index)
Edge & GetEdge(size_t index)
Edge * GetEdgeBetween(Port &a, Port &b)
Edge & CreateDirectedEdge(Port &from, Port &to)
void OutputASCII(std::ostream &out, size_t indent) const
const char * GetIdPrefix() const override
void RemoveProgramObjectMapping(uintptr_t object)
std::vector< std::unique_ptr< Edge > > Edges_
Graph & GetGraph() override
ResultNode & CreateResultNode()
size_t NumResultNodes() const noexcept
std::vector< std::unique_ptr< ResultNode > > ResultNodes_
void OutputDot(std::ostream &out, size_t indent) const
size_t NumEdges() const noexcept
size_t NumNodes() const noexcept
Node & GetArgumentNode(size_t index)
Edge & CreateUndirectedEdge(Port &a, Port &b)
InOutNode & CreateInOutNode(size_t inputPorts, size_t outputPorts)
size_t NumArgumentNodes() const noexcept
void outputJson(std::ostream &out, size_t indent) const
std::vector< std::unique_ptr< Node > > Nodes_
Edge & CreateEdge(Port &from, Port &to, bool directed)
void MapProgramObjectToElement(GraphElement &element)
Element & GetFromProgramObject(const ProgramObject &object) const
~Graph() override=default
void OutputSubgraphs(std::ostream &out, OutputFormat format, size_t indent) const override
std::unordered_map< std::string, std::string > HtmlTableAttributes_
std::vector< std::unique_ptr< OutputPort > > OutputPorts_
void OutputDot(std::ostream &out, size_t indent) const override
void outputJson(std::ostream &out, size_t indent) const override
void SetFillColor(std::string color) override
OutputPort & GetOutputPort(size_t index)
std::vector< Graph * > SubGraphs_
std::vector< std::unique_ptr< InputPort > > InputPorts_
void SetShape(std::string) override
InputPort & GetInputPort(size_t index)
~InOutNode() override=default
Graph & GetSubgraph(size_t index)
void OutputASCII(std::ostream &out, size_t indent) const override
void SetHtmlTableAttribute(std::string name, std::string value)
const char * GetIdPrefix() const override
bool CanBeEdgeTail() const override
void SetFillColor(std::string color) override
~InputPort() override=default
void outputJson(std::ostream &out, size_t indent) const
void OutputDotPortId(std::ostream &out) const override
Node & GetNode() override
~Node() override=default
const char * GetIdPrefix() const override
Graph & GetGraph() override
virtual void OutputDot(std::ostream &out, size_t indent) const
virtual void OutputSubgraphs(std::ostream &out, OutputFormat format, size_t indent) const
void OutputDotPortId(std::ostream &out) const override
virtual void OutputASCII(std::ostream &out, size_t indent) const
virtual void outputJson(std::ostream &out, size_t indent) const
virtual void SetShape(std::string shape)
void SetFillColor(std::string color) override
void SetFillColor(std::string color) override
void outputJson(std::ostream &out, size_t indent) const
~OutputPort() override=default
bool CanBeEdgeHead() const override
void OutputDotPortId(std::ostream &out) const override
const char * GetIdPrefix() const override
const std::vector< Edge * > & GetConnections() const
virtual bool CanBeEdgeTail() const
virtual bool CanBeEdgeHead() const
virtual Node & GetNode()=0
virtual void SetFillColor(std::string color)=0
std::vector< Edge * > Connections_
bool HasIncomingEdges() const
~Port() override=default
void OutputIncomingEdgesASCII(std::ostream &out) const
Graph & GetGraph() override
void OnEdgeAdded(Edge &edge)
bool HasOutgoingEdges() const
virtual void OutputDotPortId(std::ostream &out) const =0
void SetOutsideDestination(const Port &outsideSource)
void OutputASCII(std::ostream &out, size_t indent) const override
const char * GetIdPrefix() const override
~ResultNode() override=default
bool CanBeEdgeTail() const override
GraphElement * GetElementFromProgramObject(uintptr_t object) const
size_t GetNextUniqueIdStubSuffix(const char *idStub)
std::unordered_map< std::string, size_t > NextUniqueIdStubSuffix_
Writer(Writer &&other)=delete
Writer & operator=(Writer &&other)=delete
size_t NumGraphs() const noexcept
Graph & CreateSubGraph(Node &parentNode)
std::vector< std::unique_ptr< Graph > > Graphs_
void outputAllGraphs(std::ostream &out, OutputFormat format)
Writer(const Writer &other)=delete
Graph & GetGraph(size_t index)
Writer & operator=(const Writer &other)=delete
#define JLM_ASSERT(x)
Definition common.hpp:16
const char *const Purple
const char *const White
const char *const Firebrick
const char *const Brown
const char *const Yellow
const char *const Black
const char *const CornflowerBlue
const char *const Green
const char *const Orange
const char *const Coral
const char *const SkyBlue
static const char *const Dashed
static const char *const Bold
static const char *const Invisible
static const char *const Tapered
static const char *const Solid
static const char *const Dotted
static const char *const Plain
static const char *const Plaintext
static const char *const Point
static const char *const Triangle
static const char *const Rectangle
static const char *const Oval
static const char *const DoubleCircle
static const char *const Circle