ctf: use unique_ptr to manage ctf_visitor_generate_ir lifetime
[babeltrace.git] / src / plugins / ctf / common / src / metadata / tsdl / ast.hpp
CommitLineData
e98a2d6e 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
e98a2d6e 3 *
0235b0db 4 * Copyright 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
e98a2d6e
PP
5 */
6
0235b0db
MJ
7#ifndef _CTF_AST_H
8#define _CTF_AST_H
9
708dab6b
SM
10#include <memory>
11
c802cacb 12#include <glib.h>
e98a2d6e
PP
13#include <stdint.h>
14#include <stdio.h>
c802cacb 15
3fadfbc0 16#include <babeltrace2/babeltrace.h>
c802cacb 17
1a6da3f9 18#include "common/assert.h"
c802cacb 19#include "common/list.h"
0f5c5d5c 20#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
e98a2d6e 21
087cd0f5 22#include "ctf-meta.hpp"
c802cacb 23#include "decoder.hpp"
a2a54545 24
e98a2d6e
PP
25// the parameter name (of the reentrant 'yyparse' function)
26// data is a pointer to a 'SParserParam' structure
27//#define YYPARSE_PARAM scanner
28
29struct ctf_node;
30struct ctf_parser;
1e649dff
PP
31struct ctf_visitor_generate_ir;
32
4164020e
SM
33#define EINCOMPLETE 1000
34
35#define FOREACH_CTF_NODES(F) \
36 F(NODE_UNKNOWN) \
37 F(NODE_ROOT) \
38 F(NODE_ERROR) \
39 F(NODE_EVENT) \
40 F(NODE_STREAM) \
41 F(NODE_ENV) \
42 F(NODE_TRACE) \
43 F(NODE_CLOCK) \
44 F(NODE_CALLSITE) \
45 F(NODE_CTF_EXPRESSION) \
46 F(NODE_UNARY_EXPRESSION) \
47 F(NODE_TYPEDEF) \
48 F(NODE_TYPEALIAS_TARGET) \
49 F(NODE_TYPEALIAS_ALIAS) \
50 F(NODE_TYPEALIAS) \
51 F(NODE_TYPE_SPECIFIER) \
52 F(NODE_TYPE_SPECIFIER_LIST) \
53 F(NODE_POINTER) \
54 F(NODE_TYPE_DECLARATOR) \
55 F(NODE_FLOATING_POINT) \
56 F(NODE_INTEGER) \
57 F(NODE_STRING) \
58 F(NODE_ENUMERATOR) \
59 F(NODE_ENUM) \
60 F(NODE_STRUCT_OR_VARIANT_DECLARATION) \
61 F(NODE_VARIANT) \
62 F(NODE_STRUCT)
63
64enum node_type
65{
66#define ENTRY(S) S,
67 FOREACH_CTF_NODES(ENTRY)
e98a2d6e 68#undef ENTRY
087cd0f5
SM
69};
70
0f5c5d5c
SM
71inline const char *format_as(enum node_type type) noexcept
72{
73 switch (type) {
74#define ENTRY(S) \
75case S: \
76 return G_STRINGIFY(S);
77
78 FOREACH_CTF_NODES(ENTRY)
79#undef ENTRY
80 }
81
82 bt_common_abort();
83}
84
4164020e
SM
85enum ctf_unary
86{
87 UNARY_UNKNOWN = 0,
88 UNARY_STRING,
89 UNARY_SIGNED_CONSTANT,
90 UNARY_UNSIGNED_CONSTANT,
91 UNARY_SBRAC,
087cd0f5
SM
92};
93
0f5c5d5c
SM
94inline const char *format_as(ctf_unary value) noexcept
95{
96 switch (value) {
97 case UNARY_UNKNOWN:
98 return "UNARY_UNKNOWN";
99
100 case UNARY_STRING:
101 return "UNARY_STRING";
102
103 case UNARY_SIGNED_CONSTANT:
104 return "UNARY_SIGNED_CONSTANT";
105
106 case UNARY_UNSIGNED_CONSTANT:
107 return "UNARY_UNSIGNED_CONSTANT";
108
109 case UNARY_SBRAC:
110 return "UNARY_SBRAC";
111 }
112
113 bt_common_abort();
114}
115
4164020e
SM
116enum ctf_unary_link
117{
118 UNARY_LINK_UNKNOWN = 0,
119 UNARY_DOTLINK,
120 UNARY_ARROWLINK,
121 UNARY_DOTDOTDOT,
087cd0f5
SM
122};
123
4164020e
SM
124enum ctf_typedec
125{
126 TYPEDEC_UNKNOWN = 0,
127 TYPEDEC_ID, /* identifier */
128 TYPEDEC_NESTED, /* (), array or sequence */
087cd0f5
SM
129};
130
0f5c5d5c
SM
131inline const char *format_as(ctf_typedec value) noexcept
132{
133 switch (value) {
134 case TYPEDEC_UNKNOWN:
135 return "TYPEDEC_UNKNOWN";
136
137 case TYPEDEC_ID:
138 return "TYPEDEC_ID";
139
140 case TYPEDEC_NESTED:
141 return "TYPEDEC_NESTED";
142 }
143
144 bt_common_abort();
145}
146
4164020e
SM
147enum ctf_typespec
148{
149 TYPESPEC_UNKNOWN = 0,
150 TYPESPEC_VOID,
151 TYPESPEC_CHAR,
152 TYPESPEC_SHORT,
153 TYPESPEC_INT,
154 TYPESPEC_LONG,
155 TYPESPEC_FLOAT,
156 TYPESPEC_DOUBLE,
157 TYPESPEC_SIGNED,
158 TYPESPEC_UNSIGNED,
159 TYPESPEC_BOOL,
160 TYPESPEC_COMPLEX,
161 TYPESPEC_IMAGINARY,
162 TYPESPEC_CONST,
163 TYPESPEC_ID_TYPE,
164 TYPESPEC_FLOATING_POINT,
165 TYPESPEC_INTEGER,
166 TYPESPEC_STRING,
167 TYPESPEC_STRUCT,
168 TYPESPEC_VARIANT,
169 TYPESPEC_ENUM,
e98a2d6e
PP
170};
171
0f5c5d5c
SM
172inline const char *format_as(ctf_typespec value) noexcept
173{
174 switch (value) {
175 case TYPESPEC_UNKNOWN:
176 return "TYPESPEC_UNKNOWN";
177
178 case TYPESPEC_VOID:
179 return "TYPESPEC_VOID";
180
181 case TYPESPEC_CHAR:
182 return "TYPESPEC_CHAR";
183
184 case TYPESPEC_SHORT:
185 return "TYPESPEC_SHORT";
186
187 case TYPESPEC_INT:
188 return "TYPESPEC_INT";
189
190 case TYPESPEC_LONG:
191 return "TYPESPEC_LONG";
192
193 case TYPESPEC_FLOAT:
194 return "TYPESPEC_FLOAT";
195
196 case TYPESPEC_DOUBLE:
197 return "TYPESPEC_DOUBLE";
198
199 case TYPESPEC_SIGNED:
200 return "TYPESPEC_SIGNED";
201
202 case TYPESPEC_UNSIGNED:
203 return "TYPESPEC_UNSIGNED";
204
205 case TYPESPEC_BOOL:
206 return "TYPESPEC_BOOL";
207
208 case TYPESPEC_COMPLEX:
209 return "TYPESPEC_COMPLEX";
210
211 case TYPESPEC_IMAGINARY:
212 return "TYPESPEC_IMAGINARY";
213
214 case TYPESPEC_CONST:
215 return "TYPESPEC_CONST";
216
217 case TYPESPEC_ID_TYPE:
218 return "TYPESPEC_ID_TYPE";
219
220 case TYPESPEC_FLOATING_POINT:
221 return "TYPESPEC_FLOATING_POINT";
222
223 case TYPESPEC_INTEGER:
224 return "TYPESPEC_INTEGER";
225
226 case TYPESPEC_STRING:
227 return "TYPESPEC_STRING";
228
229 case TYPESPEC_STRUCT:
230 return "TYPESPEC_STRUCT";
231
232 case TYPESPEC_VARIANT:
233 return "TYPESPEC_VARIANT";
234
235 case TYPESPEC_ENUM:
236 return "TYPESPEC_ENUM";
237 }
238
239 bt_common_abort();
240}
241
4164020e
SM
242struct ctf_node
243{
244 /*
245 * Parent node is only set on demand by specific visitor.
246 */
247 struct ctf_node *parent;
248 struct bt_list_head siblings;
249 struct bt_list_head tmp_head;
250 unsigned int lineno;
251 /*
252 * We mark nodes visited in the generate-ir phase (last
253 * phase). We only mark the 1-depth level nodes as visited
254 * (never the root node, and not their sub-nodes). This allows
255 * skipping already visited nodes when doing incremental
256 * metadata append.
257 */
258 int visited;
259
260 enum node_type type;
261 union
262 {
263 struct
264 {
265 } unknown;
266 struct
267 {
268 /*
269 * Children nodes are ctf_expression, field_class_def,
270 * field_class_alias and field_class_specifier_list.
271 */
272 struct bt_list_head declaration_list;
273 struct bt_list_head trace;
274 struct bt_list_head env;
275 struct bt_list_head stream;
276 struct bt_list_head event;
277 struct bt_list_head clock;
278 struct bt_list_head callsite;
279 } root;
280 struct
281 {
282 /*
283 * Children nodes are ctf_expression, field_class_def,
284 * field_class_alias and field_class_specifier_list.
285 */
286 struct bt_list_head declaration_list;
287 } event;
288 struct
289 {
290 /*
291 * Children nodes are ctf_expression, field_class_def,
292 * field_class_alias and field_class_specifier_list.
293 */
294 struct bt_list_head declaration_list;
295 } stream;
296 struct
297 {
298 /*
299 * Children nodes are ctf_expression, field_class_def,
300 * field_class_alias and field_class_specifier_list.
301 */
302 struct bt_list_head declaration_list;
303 } env;
304 struct
305 {
306 /*
307 * Children nodes are ctf_expression, field_class_def,
308 * field_class_alias and field_class_specifier_list.
309 */
310 struct bt_list_head declaration_list;
311 } trace;
312 struct
313 {
314 /*
315 * Children nodes are ctf_expression, field_class_def,
316 * field_class_alias and field_class_specifier_list.
317 */
318 struct bt_list_head declaration_list;
319 } clock;
320 struct
321 {
322 /*
323 * Children nodes are ctf_expression, field_class_def,
324 * field_class_alias and field_class_specifier_list.
325 */
326 struct bt_list_head declaration_list;
327 } callsite;
328 struct
329 {
330 struct bt_list_head left; /* Should be string */
331 struct bt_list_head right; /* Unary exp. or type */
332 } ctf_expression;
333 struct
334 {
335 ctf_unary type;
336 union
337 {
338 /*
339 * string for identifier, id_type, keywords,
340 * string literals and character constants.
341 */
342 char *string;
343 int64_t signed_constant;
344 uint64_t unsigned_constant;
345 struct ctf_node *sbrac_exp;
346 } u;
347 ctf_unary_link link;
348 } unary_expression;
349 struct
350 {
351 struct ctf_node *field_class_specifier_list;
352 struct bt_list_head field_class_declarators;
353 } field_class_def;
354 /* new type is "alias", existing type "target" */
355 struct
356 {
357 struct ctf_node *field_class_specifier_list;
358 struct bt_list_head field_class_declarators;
359 } field_class_alias_target;
360 struct
361 {
362 struct ctf_node *field_class_specifier_list;
363 struct bt_list_head field_class_declarators;
364 } field_class_alias_name;
365 struct
366 {
367 struct ctf_node *target;
368 struct ctf_node *alias;
369 } field_class_alias;
370 struct
371 {
372 ctf_typespec type;
373 /* For struct, variant and enum */
374 struct ctf_node *node;
375 const char *id_type;
376 } field_class_specifier;
377 struct
378 {
379 /* list of field_class_specifier */
380 struct bt_list_head head;
381 } field_class_specifier_list;
382 struct
383 {
384 unsigned int const_qualifier;
385 } pointer;
386 struct
387 {
388 struct bt_list_head pointers;
389 ctf_typedec type;
390 union
391 {
392 char *id;
393 struct
394 {
395 /* typedec has no pointer list */
396 struct ctf_node *field_class_declarator;
397 /*
398 * unary expression (value) or
399 * field_class_specifier_list.
400 */
401 struct bt_list_head length;
402 /* for abstract type declarator */
403 unsigned int abstract_array;
404 } nested;
405 } u;
406 struct ctf_node *bitfield_len;
407 } field_class_declarator;
408 struct
409 {
410 /* Children nodes are ctf_expression. */
411 struct bt_list_head expressions;
412 } floating_point;
413 struct
414 {
415 /* Children nodes are ctf_expression. */
416 struct bt_list_head expressions;
417 } integer;
418 struct
419 {
420 /* Children nodes are ctf_expression. */
421 struct bt_list_head expressions;
422 } string;
423 struct
424 {
425 char *id;
426 /*
427 * Range list or single value node. Contains unary
428 * expressions.
429 */
430 struct bt_list_head values;
431 } enumerator;
432 struct
433 {
434 char *enum_id;
435 /*
436 * Either NULL, or points to unary expression or
437 * field_class_specifier_list.
438 */
439 struct ctf_node *container_field_class;
440 struct bt_list_head enumerator_list;
441 int has_body;
442 } _enum;
443 struct
444 {
445 struct ctf_node *field_class_specifier_list;
446 struct bt_list_head field_class_declarators;
447 } struct_or_variant_declaration;
448 struct
449 {
450 char *name;
451 char *choice;
452 /*
453 * list of field_class_def, field_class_alias and
454 * declarations
455 */
456 struct bt_list_head declaration_list;
457 int has_body;
458 } variant;
459 struct
460 {
461 char *name;
462 /*
463 * list of field_class_def, field_class_alias and
464 * declarations
465 */
466 struct bt_list_head declaration_list;
467 int has_body;
468 struct bt_list_head min_align; /* align() attribute */
469 } _struct;
470 } u;
e98a2d6e
PP
471};
472
4164020e
SM
473struct ctf_ast
474{
475 struct ctf_node root;
e98a2d6e
PP
476};
477
478const char *node_type(struct ctf_node *node);
479
708dab6b
SM
480struct ctf_visitor_generate_ir_deleter
481{
482 void operator()(struct ctf_visitor_generate_ir *visitor);
483};
484
0f80c86b
SM
485struct ctf_visitor_generate_ir
486{
708dab6b
SM
487 using UP = std::unique_ptr<ctf_visitor_generate_ir, ctf_visitor_generate_ir_deleter>;
488
0f80c86b
SM
489 explicit ctf_visitor_generate_ir(ctf_metadata_decoder_config decoderConfig,
490 bt2c::Logger loggerParam) :
491 decoder_config {std::move(decoderConfig)},
492 logger {std::move(loggerParam)}
493 {
494 }
495
496 /* Trace IR trace class being filled (owned by this) */
497 bt_trace_class *trace_class = nullptr;
498
499 /* CTF meta trace being filled (owned by this) */
500 struct ctf_trace_class *ctf_tc = nullptr;
501
502 /* Current declaration scope (top of the stack) (owned by this) */
503 struct ctx_decl_scope *current_scope = nullptr;
504
505 /* True if trace declaration is visited */
506 bool is_trace_visited = false;
507
508 /* True if this is an LTTng trace */
509 bool is_lttng = false;
510
511 /* Config passed by the user */
512 struct ctf_metadata_decoder_config decoder_config;
513
514 bt2c::Logger logger;
515};
516
708dab6b 517ctf_visitor_generate_ir::UP
4164020e 518ctf_visitor_generate_ir_create(const struct ctf_metadata_decoder_config *config);
1e649dff 519
4164020e 520bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(struct ctf_visitor_generate_ir *visitor);
44c440bc 521
4164020e
SM
522struct ctf_trace_class *
523ctf_visitor_generate_ir_borrow_ctf_trace_class(struct ctf_visitor_generate_ir *visitor);
e98a2d6e 524
1e649dff 525int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
4164020e 526 struct ctf_node *node);
e98a2d6e 527
0f5c5d5c 528int ctf_visitor_semantic_check(int depth, struct ctf_node *node, const bt2c::Logger& logger);
e98a2d6e 529
0f5c5d5c 530int ctf_visitor_parent_links(int depth, struct ctf_node *node, const bt2c::Logger& logger);
e98a2d6e 531
4164020e 532static inline char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head)
1a6da3f9 533{
4164020e
SM
534 int i = 0;
535 GString *str;
536 struct ctf_node *node;
537
538 str = g_string_new(NULL);
539 BT_ASSERT(str);
540
541 bt_list_for_each_entry (node, head, siblings) {
542 char *src_string;
543
544 if (node->type != NODE_UNARY_EXPRESSION || node->u.unary_expression.type != UNARY_STRING ||
545 !((node->u.unary_expression.link != UNARY_LINK_UNKNOWN) ^ (i == 0))) {
546 goto error;
547 }
548
549 switch (node->u.unary_expression.link) {
550 case UNARY_DOTLINK:
551 g_string_append(str, ".");
552 break;
553 case UNARY_ARROWLINK:
554 g_string_append(str, "->");
555 break;
556 case UNARY_DOTDOTDOT:
557 g_string_append(str, "...");
558 break;
559 default:
560 break;
561 }
562
563 src_string = node->u.unary_expression.u.string;
564 g_string_append(str, src_string);
565 i++;
566 }
567
568 /* Destroys the container, returns the underlying string */
569 return g_string_free(str, FALSE);
1a6da3f9
PP
570
571error:
4164020e
SM
572 /* This always returns NULL */
573 return g_string_free(str, TRUE);
1a6da3f9
PP
574}
575
ecd7492f 576#ifndef BT_COMP_LOG_CUR_LVL
5bcd9f04 577# define BT_AST_LOG_LEVEL_UNUSED_ATTR __attribute__((unused))
ecd7492f 578#else
5bcd9f04 579# define BT_AST_LOG_LEVEL_UNUSED_ATTR
ecd7492f
MJ
580#endif
581
582static inline int ctf_ast_get_unary_uuid(struct bt_list_head *head, bt_uuid_t uuid,
0f5c5d5c 583 const bt2c::Logger& logger)
1a6da3f9 584{
4164020e
SM
585 int i = 0;
586 int ret = 0;
587 struct ctf_node *node;
588
589 bt_list_for_each_entry (node, head, siblings) {
590 int uexpr_type = node->u.unary_expression.type;
591 int uexpr_link = node->u.unary_expression.link;
592 const char *src_string;
593
594 if (node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_STRING ||
595 uexpr_link != UNARY_LINK_UNKNOWN || i != 0) {
596 ret = -EINVAL;
597 goto end;
598 }
599
600 src_string = node->u.unary_expression.u.string;
601 ret = bt_uuid_from_str(src_string, uuid);
602 if (ret) {
0f5c5d5c 603 BT_CPPLOGE_APPEND_CAUSE_SPEC(logger, "Cannot parse UUID: uuid=\"{}\"", src_string);
4164020e
SM
604 goto end;
605 }
606 }
1a6da3f9
PP
607
608end:
4164020e 609 return ret;
1a6da3f9
PP
610}
611
e98a2d6e 612#endif /* _CTF_AST_H */
This page took 0.141473 seconds and 4 git commands to generate.