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-2026 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
253bool
254get_compass_pt_from_string (const char *str, enum compass_pt &out);
255
256/* port : ':' ID [ ':' compass_pt ]
257 | ':' compass_pt
258*/
259
260struct port : public ast_node
261{
262 port (id id_)
263 : m_id (std::make_unique<id> (std::move (id_))),
264 m_compass_pt (nullptr)
265 {
266 }
267
268 port (enum compass_pt compass_pt_)
269 : m_id (nullptr),
270 m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
271 {
272 }
273
274 port (id id_,
275 enum compass_pt compass_pt_)
276 : m_id (std::make_unique<id> (std::move (id_))),
277 m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
278 {
279 }
280
281 port (const port &other)
282 : m_id (nullptr),
283 m_compass_pt (nullptr)
284 {
285 if (other.m_id)
286 m_id = std::make_unique<id> (*other.m_id);
287 if (other.m_compass_pt)
288 m_compass_pt = std::make_unique<enum compass_pt> (*other.m_compass_pt);
289 }
290
291 void print (writer &w) const final override;
292
293 std::unique_ptr<id> m_id; // would be std::optional
294 std::unique_ptr<enum compass_pt> m_compass_pt; // would be std::optional
295};
296
297struct node_id : public ast_node
298{
299 node_id (id id_)
300 : m_id (id_),
301 m_port (nullptr)
302 {
303 }
304 node_id (id id_, port port_)
305 : m_id (id_),
306 m_port (std::make_unique<port> (std::move (port_)))
307 {
308 }
309 node_id (const node_id &other)
310 : m_id (other.m_id),
311 m_port (nullptr)
312 {
313 if (other.m_port)
314 m_port = std::make_unique<port> (*other.m_port);
315 }
316
318 {
319 m_id = other.m_id;
320 if (other.m_port)
321 m_port = std::make_unique<port> (*other.m_port);
322 else
323 m_port = nullptr;
324 return *this;
325 }
326
327 void print (writer &w) const final override;
328
330 std::unique_ptr<port> m_port; // would be std::optional
331};
332
333/* The full grammar for edge_stmt is:
334 edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
335 edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
336 This class support the subsets where all are "node_id", rather than
337 "subgraph", and doesn't yet support "port" giving effectively:
338 node_id (edgeop node_id)+ [ attr_list]
339 */
340
342{
343 edge_stmt (node_id src_id, node_id dst_id)
344 {
345 m_node_ids.push_back (std::move (src_id));
346 m_node_ids.push_back (std::move (dst_id));
347 }
348
349 void print (writer &w) const final override;
350
351 std::vector<node_id> m_node_ids; // should have 2 or more elements
352};
353
354/* [ subgraph [ ID ] ] '{' stmt_list '}' */
355
356struct subgraph : public stmt
357{
358 subgraph (id id_)
359 : m_id (id_)
360 {
361 }
362
363 void print (writer &w) const final override;
364
365 void add_stmt (std::unique_ptr<stmt> s)
366 {
367 m_stmt_list.add_stmt (std::move (s));
368 }
369 void add_attr (id key, id value)
370 {
371 m_stmt_list.add_stmt
372 (std::make_unique <kv_stmt> (kv_pair (std::move (key),
373 std::move (value))));
374 }
375
378};
379
380extern std::unique_ptr<xml::node>
382
383} // namespace dot
384
385/* A class for writing .dot output to a pretty_printer with
386 indentation to show nesting. */
387
388class graphviz_out : public dot::writer {
389 public:
391
392 void print (const char *fmt, ...)
394 void println (const char *fmt, ...)
396
397 void begin_tr ();
398 void end_tr ();
399
400 void begin_td ();
401 void end_td ();
402
403 void begin_trtd ();
404 void end_tdtr ();
405};
406
407#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:31
class edge_def * edge
Definition coretypes.h:369
Definition custom-sarif-properties/state-graphs.h:30
Definition custom-sarif-properties/state-graphs.h:33
Definition graphviz.cc:147
bool get_compass_pt_from_string(const char *str, enum compass_pt &out)
Definition graphviz.cc:357
compass_pt
Definition graphviz.h:248
@ s
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:557
Definition graphviz.h:26
if(N >=2) for(unsigned int i
void pp_character(pretty_printer *pp, int c)
Definition pretty-print.cc:2746
void pp_newline(pretty_printer *pp)
Definition pretty-print.cc:2737
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2764
#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
Definition graphviz.h:342
void print(writer &w) const final override
Definition graphviz.cc:469
std::vector< node_id > m_node_ids
Definition graphviz.h:351
edge_stmt(node_id src_id, node_id dst_id)
Definition graphviz.h:343
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:298
void print(writer &w) const final override
Definition graphviz.cc:411
node_id & operator=(const node_id &other)
Definition graphviz.h:317
node_id(id id_)
Definition graphviz.h:299
node_id(id id_, port port_)
Definition graphviz.h:304
std::unique_ptr< port > m_port
Definition graphviz.h:330
node_id(const node_id &other)
Definition graphviz.h:309
id m_id
Definition graphviz.h:329
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:261
port(id id_)
Definition graphviz.h:262
std::unique_ptr< enum compass_pt > m_compass_pt
Definition graphviz.h:294
port(id id_, enum compass_pt compass_pt_)
Definition graphviz.h:274
port(enum compass_pt compass_pt_)
Definition graphviz.h:268
void print(writer &w) const final override
Definition graphviz.cc:421
port(const port &other)
Definition graphviz.h:281
std::unique_ptr< id > m_id
Definition graphviz.h:293
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:357
subgraph(id id_)
Definition graphviz.h:358
void add_attr(id key, id value)
Definition graphviz.h:369
void add_stmt(std::unique_ptr< stmt > s)
Definition graphviz.h:365
id m_id
Definition graphviz.h:376
stmt_list m_stmt_list
Definition graphviz.h:377
void print(writer &w) const final override
Definition graphviz.cc:483
Definition ira-emit.cc:158
Definition shrink-wrap.cc:1086
Definition xml.h:37