.gitignore: add some missing files
[babeltrace.git] / src / plugins / ctf / common / src / metadata / tsdl / ast.hpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 */
6
7 #ifndef BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_TSDL_AST_HPP
8 #define BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_TSDL_AST_HPP
9
10 #include <memory>
11
12 #include <glib.h>
13 #include <stdint.h>
14 #include <stdio.h>
15
16 #include <babeltrace2/babeltrace.h>
17
18 #include "common/assert.h"
19 #include "common/list.h"
20 #include "cpp-common/bt2c/logging.hpp"
21 #include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
22
23 #include "ctf-meta.hpp"
24
25 // the parameter name (of the reentrant 'yyparse' function)
26 // data is a pointer to a 'SParserParam' structure
27 //#define YYPARSE_PARAM scanner
28
29 struct ctf_node;
30 struct ctf_parser;
31 struct ctf_visitor_generate_ir;
32
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
64 enum node_type
65 {
66 #define ENTRY(S) S,
67 FOREACH_CTF_NODES(ENTRY)
68 #undef ENTRY
69 };
70
71 inline const char *format_as(enum node_type type) noexcept
72 {
73 switch (type) {
74 #define ENTRY(S) \
75 case S: \
76 return G_STRINGIFY(S);
77
78 FOREACH_CTF_NODES(ENTRY)
79 #undef ENTRY
80 }
81
82 bt_common_abort();
83 }
84
85 enum ctf_unary
86 {
87 UNARY_UNKNOWN = 0,
88 UNARY_STRING,
89 UNARY_SIGNED_CONSTANT,
90 UNARY_UNSIGNED_CONSTANT,
91 UNARY_SBRAC,
92 };
93
94 inline 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
116 enum ctf_unary_link
117 {
118 UNARY_LINK_UNKNOWN = 0,
119 UNARY_DOTLINK,
120 UNARY_ARROWLINK,
121 UNARY_DOTDOTDOT,
122 };
123
124 enum ctf_typedec
125 {
126 TYPEDEC_UNKNOWN = 0,
127 TYPEDEC_ID, /* identifier */
128 TYPEDEC_NESTED, /* (), array or sequence */
129 };
130
131 inline 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
147 enum 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,
170 };
171
172 inline 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
242 struct 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;
471 };
472
473 struct ctf_ast
474 {
475 struct ctf_node root;
476 };
477
478 const char *node_type(struct ctf_node *node);
479
480 struct ctf_visitor_generate_ir
481 {
482 using UP = std::unique_ptr<ctf_visitor_generate_ir>;
483
484 explicit ctf_visitor_generate_ir(const bt2c::Logger& parentLogger) :
485 logger {parentLogger, "PLUGIN/CTF/VISITOR-GENERATE-IR"}
486 {
487 }
488
489 ~ctf_visitor_generate_ir();
490
491 bt2c::Logger logger;
492
493 /* CTF meta trace being filled (owned by this) */
494 struct ctf_trace_class *ctf_tc = nullptr;
495
496 /* Current declaration scope (top of the stack) (owned by this) */
497 struct ctx_decl_scope *current_scope = nullptr;
498
499 /* True if trace declaration is visited */
500 bool is_trace_visited = false;
501
502 /* True if this is an LTTng trace */
503 bool is_lttng = false;
504 };
505
506 ctf_visitor_generate_ir::UP ctf_visitor_generate_ir_create(const bt2c::Logger& parentLogger);
507
508 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
509 struct ctf_node *node);
510
511 int ctf_visitor_semantic_check(int depth, struct ctf_node *node, const bt2c::Logger& logger);
512
513 int ctf_visitor_parent_links(int depth, struct ctf_node *node, const bt2c::Logger& logger);
514
515 static inline char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head)
516 {
517 int i = 0;
518 GString *str;
519 struct ctf_node *node;
520
521 str = g_string_new(NULL);
522 BT_ASSERT(str);
523
524 bt_list_for_each_entry (node, head, siblings) {
525 char *src_string;
526
527 if (node->type != NODE_UNARY_EXPRESSION || node->u.unary_expression.type != UNARY_STRING ||
528 !((node->u.unary_expression.link != UNARY_LINK_UNKNOWN) ^ (i == 0))) {
529 goto error;
530 }
531
532 switch (node->u.unary_expression.link) {
533 case UNARY_DOTLINK:
534 g_string_append(str, ".");
535 break;
536 case UNARY_ARROWLINK:
537 g_string_append(str, "->");
538 break;
539 case UNARY_DOTDOTDOT:
540 g_string_append(str, "...");
541 break;
542 default:
543 break;
544 }
545
546 src_string = node->u.unary_expression.u.string;
547 g_string_append(str, src_string);
548 i++;
549 }
550
551 /* Destroys the container, returns the underlying string */
552 return g_string_free(str, FALSE);
553
554 error:
555 /* This always returns NULL */
556 return g_string_free(str, TRUE);
557 }
558
559 static inline int ctf_ast_get_unary_uuid(struct bt_list_head *head, bt_uuid_t uuid,
560 const bt2c::Logger& logger)
561 {
562 int i = 0;
563 int ret = 0;
564 struct ctf_node *node;
565
566 bt_list_for_each_entry (node, head, siblings) {
567 int uexpr_type = node->u.unary_expression.type;
568 int uexpr_link = node->u.unary_expression.link;
569 const char *src_string;
570
571 if (node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_STRING ||
572 uexpr_link != UNARY_LINK_UNKNOWN || i != 0) {
573 ret = -EINVAL;
574 goto end;
575 }
576
577 src_string = node->u.unary_expression.u.string;
578 ret = bt_uuid_from_c_str(src_string, uuid);
579 if (ret) {
580 BT_CPPLOGE_APPEND_CAUSE_SPEC(logger, "Cannot parse UUID: uuid=\"{}\"", src_string);
581 goto end;
582 }
583 }
584
585 end:
586 return ret;
587 }
588
589 #endif /* BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_TSDL_AST_HPP */
This page took 0.045268 seconds and 5 git commands to generate.