GCC Middle and Back End API Reference
graphviz.h
Go to the documentation of this file.
1/* Helper code for graphviz output.
2 Copyright (C) 2019-2025 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_GRAPHVIZ_H
22#define GCC_GRAPHVIZ_H
23
24#include "pretty-print.h" /* for ATTRIBUTE_GCC_PPDIAG. */
25
26namespace xml { class node; }
27
28namespace dot {
29
30/* A class for writing .dot output to a pretty_printer with
31 indentation to show nesting. */
32
33class writer {
34public:
36
37 void indent () { m_indent++; }
38 void outdent () { m_indent--; }
39
40 void write_indent ();
41
42 void write_character (char ch)
43 {
44 pp_character (&m_pp, ch);
45 }
46 void write_string (const char *str)
47 {
48 pp_string (&m_pp, str);
49 }
51 {
53 }
54
55 pretty_printer *get_pp () const { return &m_pp; }
56
57 private:
60};
61
62// An AST for the dot language
63// See https://graphviz.org/doc/info/lang.html
64
65// Forward decls
66
67struct id;
68struct node_id;
69struct port;
70struct kv_pair;
71struct graph;
72struct attr_list;
73struct stmt_list;
74struct stmt;
75 struct node_stmt;
76 struct attr_stmt;
77 struct kv_stmt;
78 struct edge_stmt;
79 struct subgraph;
80
81// Decls
82
84{
85 virtual ~ast_node () {}
86 virtual void print (writer &w) const = 0;
87
88 void dump () const;
89};
90
91struct id : public ast_node
92{
93 enum class kind
94 {
98 };
99
100 id (std::string str);
101
102 /* For HTML labels: see https://graphviz.org/doc/info/shapes.html#html */
103 id (const xml::node &n);
104
105 void print (writer &w) const final override;
106
107 static bool is_identifier_p (const char *);
108
109 std::string m_str;
111};
112
113/* ID '=' ID */
114
116{
117 kv_pair (id key, id value)
118 : m_key (std::move (key)),
119 m_value (std::move (value))
120 {
121 }
122
123 void print (writer &w) const final override;
124
127};
128
129/* attr_list: '[' [ a_list ] ']' [ attr_list ] */
130
131struct attr_list : public ast_node
132{
133 void print (writer &w) const;
134 void add (id key, id value)
135 {
136 m_kvs.push_back ({std::move (key), std::move (value)});
137 }
138
139 std::vector<kv_pair> m_kvs;
140};
141
142/* stmt_list : [ stmt [ ';' ] stmt_list ] */
143
144struct stmt_list : public ast_node
145{
146 void print (writer &w) const final override;
147 void add_stmt (std::unique_ptr<stmt> s)
148 {
149 m_stmts.push_back (std::move (s));
150 }
151 void add_edge (node_id src_id, node_id dst_id);
152 void add_attr (id key, id value);
153
154 std::vector<std::unique_ptr<stmt>> m_stmts;
155};
156
157/* graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}' */
158
159struct graph : public ast_node
160{
162 : m_id (nullptr)
163 {
164 }
165
166 graph (id id_)
167 : m_id (std::make_unique<id> (std::move (id_)))
168 {
169 }
170
171 void print (writer &w) const final override;
172
173 void add_stmt (std::unique_ptr<stmt> s)
174 {
175 m_stmt_list.add_stmt (std::move (s));
176 }
177
178 std::unique_ptr<id> m_id; // optional
180};
181
182/* Abstract base class.
183 stmt : node_stmt
184 | edge_stmt
185 | attr_stmt
186 | ID '=' ID ("kv_stmt")
187 | subgraph */
188
189struct stmt
190{
191 virtual ~stmt () {}
192 virtual void print (writer &w) const = 0;
193};
194
196{
197 void set_attr (id key, id value)
198 {
199 m_attrs.add (std::move (key), std::move (value));
200 }
201 void set_label (dot::id label);
202
204};
205
207{
208 node_stmt (id id_)
209 : m_id (id_)
210 {
211 }
212
213 void print (writer &w) const final override;
214
216};
217
219{
220 enum class kind { graph, node, edge };
221
222 attr_stmt (enum kind kind_)
223 : m_kind (kind_)
224 {
225 }
226
227 void print (writer &w) const final override;
228
230};
231
232/* "ID '=' ID" as a stmt. */
233
234struct kv_stmt : public stmt
235{
237 : m_kv (std::move (kv))
238 {}
239
240 void print (writer &w) const final override;
241
243};
244
245/* node_id : ID [ port ] */
246
247enum class compass_pt
248{
249 n, ne, e, se, s, sw, w, nw, c
250 /* "_" clashes with intl macro */
251};
252
253/* port : ':' ID [ ':' compass_pt ]
254 | ':' compass_pt
255*/
256
257struct port : public ast_node
258{
259 port (id id_)
260 : m_id (std::make_unique<id> (std::move (id_))),
261 m_compass_pt (nullptr)
262 {
263 }
264
265 port (enum compass_pt compass_pt_)
266 : m_id (nullptr),
267 m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
268 {
269 }
270
271 port (id id_,
272 enum compass_pt compass_pt_)
273 : m_id (std::make_unique<id> (std::move (id_))),
274 m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
275 {
276 }
277
278 port (const port &other)
279 : m_id (nullptr),
280 m_compass_pt (nullptr)
281 {
282 if (other.m_id)
283 m_id = std::make_unique<id> (*other.m_id);
284 if (other.m_compass_pt)
285 m_compass_pt = std::make_unique<enum compass_pt> (*other.m_compass_pt);
286 }
287
288 void print (writer &w) const final override;
289
290 std::unique_ptr<id> m_id; // would be std::optional
291 std::unique_ptr<enum compass_pt> m_compass_pt; // would be std::optional
292};
293
294struct node_id : public ast_node
295{
296 node_id (id id_)
297 : m_id (id_),
298 m_port (nullptr)
299 {
300 }
301 node_id (id id_, port port_)
302 : m_id (id_),
303 m_port (std::make_unique<port> (std::move (port_)))
304 {
305 }
306 node_id (const node_id &other)
307 : m_id (other.m_id),
308 m_port (nullptr)
309 {
310 if (other.m_port)
311 m_port = std::make_unique<port> (*other.m_port);
312 }
313
315 {
316 m_id = other.m_id;
317 if (other.m_port)
318 m_port = std::make_unique<port> (*other.m_port);
319 else
320 m_port = nullptr;
321 return *this;
322 }
323
324 void print (writer &w) const final override;
325
327 std::unique_ptr<port> m_port; // would be std::optional
328};
329
330/* The full grammar for edge_stmt is:
331 edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
332 edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
333 This class support the subsets where all are "node_id", rather than
334 "subgraph", and doesn't yet support "port" giving effectively:
335 node_id (edgeop node_id)+ [ attr_list]
336 */
337
339{
340 edge_stmt (node_id src_id, node_id dst_id)
341 {
342 m_node_ids.push_back (std::move (src_id));
343 m_node_ids.push_back (std::move (dst_id));
344 }
345
346 void print (writer &w) const final override;
347
348 std::vector<node_id> m_node_ids; // should have 2 or more elements
349};
350
351/* [ subgraph [ ID ] ] '{' stmt_list '}' */
352
353struct subgraph : public stmt
354{
355 subgraph (id id_)
356 : m_id (id_)
357 {
358 }
359
360 void print (writer &w) const final override;
361
362 void add_stmt (std::unique_ptr<stmt> s)
363 {
364 m_stmt_list.add_stmt (std::move (s));
365 }
366 void add_attr (id key, id value)
367 {
368 m_stmt_list.add_stmt
369 (std::make_unique <kv_stmt> (kv_pair (std::move (key),
370 std::move (value))));
371 }
372
375};
376
377extern std::unique_ptr<xml::node>
379
380} // namespace dot
381
382/* A class for writing .dot output to a pretty_printer with
383 indentation to show nesting. */
384
385class graphviz_out : public dot::writer {
386 public:
388
389 void print (const char *fmt, ...)
391 void println (const char *fmt, ...)
393
394 void begin_tr ();
395 void end_tr ();
396
397 void begin_td ();
398 void end_td ();
399
400 void begin_trtd ();
401 void end_tdtr ();
402};
403
404#endif /* GCC_GRAPHVIZ_H */
Definition graphviz.h:33
pretty_printer * get_pp() const
Definition graphviz.h:55
pretty_printer & m_pp
Definition graphviz.h:58
void write_string(const char *str)
Definition graphviz.h:46
void indent()
Definition graphviz.h:37
int m_indent
Definition graphviz.h:59
void write_indent()
Definition graphviz.cc:42
void write_character(char ch)
Definition graphviz.h:42
void write_newline()
Definition graphviz.h:50
writer(pretty_printer &pp)
Definition graphviz.cc:33
void outdent()
Definition graphviz.h:38
void void void begin_tr()
Definition graphviz.cc:91
void print(const char *fmt,...) ATTRIBUTE_GCC_PPDIAG(2
Definition graphviz.cc:57
void end_tdtr()
Definition graphviz.cc:141
graphviz_out(pretty_printer *pp)
Definition graphviz.cc:48
void end_td()
Definition graphviz.cc:121
void void println(const char *fmt,...) ATTRIBUTE_GCC_PPDIAG(2
Definition graphviz.cc:72
void begin_td()
Definition graphviz.cc:111
void begin_trtd()
Definition graphviz.cc:131
void end_tr()
Definition graphviz.cc:101
Definition pretty-print.h:241
gcc::context * g
Definition context.cc:29
@ value
Definition logical-location.h:59
Definition diagnostic-digraphs.h:33
compass_pt
Definition graphviz.h:248
@ s
Definition graphviz.h:249
@ sw
Definition graphviz.h:249
@ c
Definition graphviz.h:249
@ nw
Definition graphviz.h:249
@ n
Definition graphviz.h:249
@ ne
Definition graphviz.h:249
@ e
Definition graphviz.h:249
@ se
Definition graphviz.h:249
@ w
Definition graphviz.h:249
std::unique_ptr< xml::node > make_svg_from_graph(const graph &g)
Definition graphviz.cc:505
Definition diagnostic-path.h:28
if(N >=2) for(unsigned int i
void pp_character(pretty_printer *pp, int c)
Definition pretty-print.cc:2620
void pp_newline(pretty_printer *pp)
Definition pretty-print.cc:2611
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2638
#define ATTRIBUTE_GCC_PPDIAG(m, n)
Definition pretty-print.h:582
Definition graphviz.h:84
virtual void print(writer &w) const =0
virtual ~ast_node()
Definition graphviz.h:85
void dump() const
Definition graphviz.cc:154
Definition graphviz.h:132
void add(id key, id value)
Definition graphviz.h:134
void print(writer &w) const
Definition graphviz.cc:241
std::vector< kv_pair > m_kvs
Definition graphviz.h:139
Definition graphviz.h:219
enum kind m_kind
Definition graphviz.h:229
void print(writer &w) const final override
Definition graphviz.cc:329
attr_stmt(enum kind kind_)
Definition graphviz.h:222
kind
Definition graphviz.h:220
@ edge
Definition graphviz.h:220
@ node
Definition graphviz.h:220
@ graph
Definition graphviz.h:220
Definition graphviz.h:339
void print(writer &w) const final override
Definition graphviz.cc:417
std::vector< node_id > m_node_ids
Definition graphviz.h:348
edge_stmt(node_id src_id, node_id dst_id)
Definition graphviz.h:340
Definition graphviz.h:160
graph(id id_)
Definition graphviz.h:166
graph()
Definition graphviz.h:161
std::unique_ptr< id > m_id
Definition graphviz.h:178
stmt_list m_stmt_list
Definition graphviz.h:179
void add_stmt(std::unique_ptr< stmt > s)
Definition graphviz.h:173
void print(writer &w) const final override
Definition graphviz.cc:288
Definition graphviz.h:92
void print(writer &w) const final override
Definition graphviz.cc:183
enum kind m_kind
Definition graphviz.h:110
static bool is_identifier_p(const char *)
Definition graphviz.cc:214
id(std::string str)
Definition graphviz.cc:166
kind
Definition graphviz.h:94
@ quoted
Definition graphviz.h:96
@ identifier
Definition graphviz.h:95
@ html
Definition graphviz.h:97
std::string m_str
Definition graphviz.h:109
Definition graphviz.h:116
kv_pair(id key, id value)
Definition graphviz.h:117
void print(writer &w) const final override
Definition graphviz.cc:231
id m_value
Definition graphviz.h:126
id m_key
Definition graphviz.h:125
Definition graphviz.h:235
kv_pair m_kv
Definition graphviz.h:242
void print(writer &w) const final override
Definition graphviz.cc:351
kv_stmt(kv_pair kv)
Definition graphviz.h:236
Definition graphviz.h:295
void print(writer &w) const final override
Definition graphviz.cc:359
node_id & operator=(const node_id &other)
Definition graphviz.h:314
node_id(id id_)
Definition graphviz.h:296
node_id(id id_, port port_)
Definition graphviz.h:301
std::unique_ptr< port > m_port
Definition graphviz.h:327
node_id(const node_id &other)
Definition graphviz.h:306
id m_id
Definition graphviz.h:326
Definition graphviz.h:207
id m_id
Definition graphviz.h:215
node_stmt(id id_)
Definition graphviz.h:208
void print(writer &w) const final override
Definition graphviz.cc:320
Definition graphviz.h:258
port(id id_)
Definition graphviz.h:259
std::unique_ptr< enum compass_pt > m_compass_pt
Definition graphviz.h:291
port(id id_, enum compass_pt compass_pt_)
Definition graphviz.h:271
port(enum compass_pt compass_pt_)
Definition graphviz.h:265
void print(writer &w) const final override
Definition graphviz.cc:369
port(const port &other)
Definition graphviz.h:278
std::unique_ptr< id > m_id
Definition graphviz.h:290
Definition graphviz.h:145
void add_attr(id key, id value)
Definition graphviz.cc:278
std::vector< std::unique_ptr< stmt > > m_stmts
Definition graphviz.h:154
void add_edge(node_id src_id, node_id dst_id)
Definition graphviz.cc:270
void add_stmt(std::unique_ptr< stmt > s)
Definition graphviz.h:147
void print(writer &w) const final override
Definition graphviz.cc:258
Definition graphviz.h:196
void set_label(dot::id label)
Definition graphviz.cc:312
void set_attr(id key, id value)
Definition graphviz.h:197
attr_list m_attrs
Definition graphviz.h:203
Definition graphviz.h:190
virtual ~stmt()
Definition graphviz.h:191
virtual void print(writer &w) const =0
Definition graphviz.h:354
subgraph(id id_)
Definition graphviz.h:355
void add_attr(id key, id value)
Definition graphviz.h:366
void add_stmt(std::unique_ptr< stmt > s)
Definition graphviz.h:362
id m_id
Definition graphviz.h:373
stmt_list m_stmt_list
Definition graphviz.h:374
void print(writer &w) const final override
Definition graphviz.cc:431
Definition ira-emit.cc:158
Definition xml.h:37