ctf: use `bt2c::Logger` throughout `src.ctf.fs`, `src.ctf.lttng-live`
[babeltrace.git] / src / plugins / ctf / common / src / metadata / tsdl / visitor-semantic-validator.cpp
CommitLineData
e98a2d6e 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
e98a2d6e 3 *
0235b0db 4 * Copyright 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
e98a2d6e 5 *
0235b0db 6 * Common Trace Format Metadata Semantic Validator.
e98a2d6e
PP
7 */
8
c802cacb 9#include <errno.h>
0f5c5d5c 10#include <unistd.h>
c802cacb 11
c802cacb 12#include "logging.hpp"
41b60475 13
578e048b 14#include "common/list.h"
c802cacb 15
087cd0f5 16#include "ast.hpp"
e98a2d6e 17
4164020e 18#define _bt_list_first_entry(ptr, type, member) bt_list_entry((ptr)->next, type, member)
e98a2d6e 19
4164020e 20static int _ctf_visitor_semantic_check(int depth, struct ctf_node *node,
0f5c5d5c 21 const bt2c::Logger& logger);
e98a2d6e 22
0f5c5d5c 23static int ctf_visitor_unary_expression(int, struct ctf_node *node, const bt2c::Logger& logger)
e98a2d6e 24{
4164020e
SM
25 struct ctf_node *iter;
26 int is_ctf_exp = 0, is_ctf_exp_left = 0;
27
28 switch (node->parent->type) {
29 case NODE_CTF_EXPRESSION:
30 is_ctf_exp = 1;
31 bt_list_for_each_entry (iter, &node->parent->u.ctf_expression.left, siblings) {
32 if (iter == node) {
33 is_ctf_exp_left = 1;
34 /*
35 * We are a left child of a ctf expression.
36 * We are only allowed to be a string.
37 */
38 if (node->u.unary_expression.type != UNARY_STRING) {
0f5c5d5c
SM
39 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
40 logger, node->lineno,
4164020e
SM
41 "Left child of a CTF expression is only allowed to be a string.");
42 goto errperm;
43 }
44 break;
45 }
46 }
47 /* Right child of a ctf expression can be any type of unary exp. */
48 break; /* OK */
49 case NODE_TYPE_DECLARATOR:
50 /*
51 * We are the length of a type declarator.
52 */
53 switch (node->u.unary_expression.type) {
54 case UNARY_UNSIGNED_CONSTANT:
55 case UNARY_STRING:
56 break;
57 default:
0f5c5d5c
SM
58 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
59 logger, node->lineno,
4164020e
SM
60 "Children of field class declarator and `enum` can only be unsigned numeric constants or references to fields (e.g., `a.b.c`).");
61 goto errperm;
62 }
63 break; /* OK */
64
65 case NODE_STRUCT:
66 /*
67 * We are the size of a struct align attribute.
68 */
69 switch (node->u.unary_expression.type) {
70 case UNARY_UNSIGNED_CONSTANT:
71 break;
72 default:
0f5c5d5c
SM
73 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
74 logger, node->lineno,
4164020e
SM
75 "Structure alignment attribute can only be an unsigned numeric constant.");
76 goto errperm;
77 }
78 break;
79
80 case NODE_ENUMERATOR:
81 /* The enumerator's parent has validated its validity already. */
82 break; /* OK */
83
84 case NODE_UNARY_EXPRESSION:
85 /*
86 * We disallow nested unary expressions and "sbrac" unary
87 * expressions.
88 */
0f5c5d5c
SM
89 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
90 "Nested unary expressions not allowed (`()` and `[]`).");
4164020e
SM
91 goto errperm;
92
93 case NODE_ROOT:
94 case NODE_EVENT:
95 case NODE_STREAM:
96 case NODE_ENV:
97 case NODE_TRACE:
98 case NODE_CLOCK:
99 case NODE_CALLSITE:
100 case NODE_TYPEDEF:
101 case NODE_TYPEALIAS_TARGET:
102 case NODE_TYPEALIAS_ALIAS:
103 case NODE_TYPEALIAS:
104 case NODE_TYPE_SPECIFIER:
105 case NODE_POINTER:
106 case NODE_FLOATING_POINT:
107 case NODE_INTEGER:
108 case NODE_STRING:
109 case NODE_ENUM:
110 case NODE_STRUCT_OR_VARIANT_DECLARATION:
111 case NODE_VARIANT:
112 default:
113 goto errinval;
114 }
115
116 switch (node->u.unary_expression.link) {
117 case UNARY_LINK_UNKNOWN:
118 /* We don't allow empty link except on the first node of the list */
119 if (is_ctf_exp &&
120 _bt_list_first_entry(is_ctf_exp_left ? &node->parent->u.ctf_expression.left :
121 &node->parent->u.ctf_expression.right,
122 struct ctf_node, siblings) != node) {
0f5c5d5c
SM
123 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
124 logger, node->lineno,
4164020e
SM
125 "Empty link is not allowed except on first node of unary expression (need to separate nodes with `.` or `->`).");
126 goto errperm;
127 }
128 break; /* OK */
129 case UNARY_DOTLINK:
130 case UNARY_ARROWLINK:
131 /* We only allow -> and . links between children of ctf_expression. */
132 if (node->parent->type != NODE_CTF_EXPRESSION) {
0f5c5d5c
SM
133 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
134 logger, node->lineno,
135 "Links `.` and `->` are only allowed as children of CTF expression.");
4164020e
SM
136 goto errperm;
137 }
138 /*
139 * Only strings can be separated linked by . or ->.
140 * This includes "", '' and non-quoted identifiers.
141 */
142 if (node->u.unary_expression.type != UNARY_STRING) {
0f5c5d5c
SM
143 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
144 logger, node->lineno,
4164020e
SM
145 "Links `.` and `->` are only allowed to separate strings and identifiers.");
146 goto errperm;
147 }
148 /* We don't allow link on the first node of the list */
149 if (is_ctf_exp &&
150 _bt_list_first_entry(is_ctf_exp_left ? &node->parent->u.ctf_expression.left :
151 &node->parent->u.ctf_expression.right,
152 struct ctf_node, siblings) == node) {
0f5c5d5c
SM
153 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
154 logger, node->lineno,
4164020e
SM
155 "Links `.` and `->` are not allowed before first node of the unary expression list.");
156 goto errperm;
157 }
158 break;
159 case UNARY_DOTDOTDOT:
160 /* We only allow ... link between children of enumerator. */
161 if (node->parent->type != NODE_ENUMERATOR) {
0f5c5d5c
SM
162 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
163 "Link `...` is only allowed within enumerator.");
4164020e
SM
164 goto errperm;
165 }
166 /* We don't allow link on the first node of the list */
167 if (_bt_list_first_entry(&node->parent->u.enumerator.values, struct ctf_node, siblings) ==
168 node) {
0f5c5d5c
SM
169 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
170 logger, node->lineno,
4164020e
SM
171 "Link `...` is not allowed on the first node of the unary expression list.");
172 goto errperm;
173 }
174 break;
175 default:
0f5c5d5c
SM
176 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
177 "Unknown expression link type: type={}",
178 (int) node->u.unary_expression.link);
4164020e
SM
179 return -EINVAL;
180 }
181 return 0;
e98a2d6e
PP
182
183errinval:
0f5c5d5c
SM
184 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
185 logger, node->lineno, "Incoherent parent node's type: node-type={}, parent-node-type={}",
4164020e
SM
186 node_type(node), node_type(node->parent));
187 return -EINVAL; /* Incoherent structure */
e98a2d6e
PP
188
189errperm:
0f5c5d5c
SM
190 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
191 "Semantic error: node-type={}, parent-node-type={}",
192 node_type(node), node_type(node->parent));
4164020e 193 return -EPERM; /* Structure not allowed */
e98a2d6e
PP
194}
195
ecd7492f 196static int ctf_visitor_field_class_specifier_list(int, struct ctf_node *node,
0f5c5d5c 197 const bt2c::Logger& logger)
e98a2d6e 198{
4164020e
SM
199 switch (node->parent->type) {
200 case NODE_CTF_EXPRESSION:
201 case NODE_TYPE_DECLARATOR:
202 case NODE_TYPEDEF:
203 case NODE_TYPEALIAS_TARGET:
204 case NODE_TYPEALIAS_ALIAS:
205 case NODE_ENUM:
206 case NODE_STRUCT_OR_VARIANT_DECLARATION:
207 case NODE_ROOT:
208 break; /* OK */
209
210 case NODE_EVENT:
211 case NODE_STREAM:
212 case NODE_ENV:
213 case NODE_TRACE:
214 case NODE_CLOCK:
215 case NODE_CALLSITE:
216 case NODE_UNARY_EXPRESSION:
217 case NODE_TYPEALIAS:
218 case NODE_TYPE_SPECIFIER:
219 case NODE_TYPE_SPECIFIER_LIST:
220 case NODE_POINTER:
221 case NODE_FLOATING_POINT:
222 case NODE_INTEGER:
223 case NODE_STRING:
224 case NODE_ENUMERATOR:
225 case NODE_VARIANT:
226 case NODE_STRUCT:
227 default:
228 goto errinval;
229 }
230 return 0;
e98a2d6e 231errinval:
0f5c5d5c
SM
232 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
233 logger, node->lineno, "Incoherent parent node's type: node-type={}, parent-node-type={}",
4164020e
SM
234 node_type(node), node_type(node->parent));
235 return -EINVAL; /* Incoherent structure */
e98a2d6e
PP
236}
237
0f5c5d5c 238static int ctf_visitor_field_class_specifier(int, struct ctf_node *node, const bt2c::Logger& logger)
e98a2d6e 239{
4164020e
SM
240 switch (node->parent->type) {
241 case NODE_TYPE_SPECIFIER_LIST:
242 break; /* OK */
243
244 case NODE_CTF_EXPRESSION:
245 case NODE_TYPE_DECLARATOR:
246 case NODE_TYPEDEF:
247 case NODE_TYPEALIAS_TARGET:
248 case NODE_TYPEALIAS_ALIAS:
249 case NODE_ENUM:
250 case NODE_STRUCT_OR_VARIANT_DECLARATION:
251 case NODE_ROOT:
252 case NODE_EVENT:
253 case NODE_STREAM:
254 case NODE_ENV:
255 case NODE_TRACE:
256 case NODE_CLOCK:
257 case NODE_CALLSITE:
258 case NODE_UNARY_EXPRESSION:
259 case NODE_TYPEALIAS:
260 case NODE_TYPE_SPECIFIER:
261 case NODE_POINTER:
262 case NODE_FLOATING_POINT:
263 case NODE_INTEGER:
264 case NODE_STRING:
265 case NODE_ENUMERATOR:
266 case NODE_VARIANT:
267 case NODE_STRUCT:
268 default:
269 goto errinval;
270 }
271 return 0;
e98a2d6e 272errinval:
0f5c5d5c
SM
273 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
274 logger, node->lineno, "Incoherent parent node's type: node-type={}, parent-node-type={}",
4164020e
SM
275 node_type(node), node_type(node->parent));
276 return -EINVAL; /* Incoherent structure */
e98a2d6e
PP
277}
278
4164020e 279static int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node,
0f5c5d5c 280 const bt2c::Logger& logger)
e98a2d6e 281{
4164020e
SM
282 int ret = 0;
283 struct ctf_node *iter;
284
285 depth++;
286
287 switch (node->parent->type) {
288 case NODE_TYPE_DECLARATOR:
289 /*
290 * A nested field class declarator is not allowed to
291 * contain pointers.
292 */
293 if (!bt_list_empty(&node->u.field_class_declarator.pointers))
294 goto errperm;
295 break; /* OK */
296 case NODE_TYPEALIAS_TARGET:
297 break; /* OK */
298 case NODE_TYPEALIAS_ALIAS:
299 /*
300 * Only accept alias name containing:
301 * - identifier
302 * - identifier * (any number of pointers)
303 * NOT accepting alias names containing [] (would otherwise
304 * cause semantic clash for later declarations of
305 * arrays/sequences of elements, where elements could be
306 * arrays/sequences themselves (if allowed in field class alias).
307 * NOT accepting alias with identifier. The declarator should
308 * be either empty or contain pointer(s).
309 */
310 if (node->u.field_class_declarator.type == TYPEDEC_NESTED)
311 goto errperm;
312 bt_list_for_each_entry (iter,
313 &node->parent->u.field_class_alias_name.field_class_specifier_list
314 ->u.field_class_specifier_list.head,
315 siblings) {
316 switch (iter->u.field_class_specifier.type) {
317 case TYPESPEC_FLOATING_POINT:
318 case TYPESPEC_INTEGER:
319 case TYPESPEC_STRING:
320 case TYPESPEC_STRUCT:
321 case TYPESPEC_VARIANT:
322 case TYPESPEC_ENUM:
323 if (bt_list_empty(&node->u.field_class_declarator.pointers))
324 goto errperm;
325 break;
326 default:
327 break;
328 }
329 }
330 if (node->u.field_class_declarator.type == TYPEDEC_ID &&
331 node->u.field_class_declarator.u.id)
332 goto errperm;
333 break; /* OK */
334 case NODE_TYPEDEF:
335 case NODE_STRUCT_OR_VARIANT_DECLARATION:
336 break; /* OK */
337
338 case NODE_ROOT:
339 case NODE_EVENT:
340 case NODE_STREAM:
341 case NODE_ENV:
342 case NODE_TRACE:
343 case NODE_CLOCK:
344 case NODE_CALLSITE:
345 case NODE_CTF_EXPRESSION:
346 case NODE_UNARY_EXPRESSION:
347 case NODE_TYPEALIAS:
348 case NODE_TYPE_SPECIFIER:
349 case NODE_POINTER:
350 case NODE_FLOATING_POINT:
351 case NODE_INTEGER:
352 case NODE_STRING:
353 case NODE_ENUMERATOR:
354 case NODE_ENUM:
355 case NODE_VARIANT:
356 case NODE_STRUCT:
357 default:
358 goto errinval;
359 }
360
361 bt_list_for_each_entry (iter, &node->u.field_class_declarator.pointers, siblings) {
0f5c5d5c 362 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
363 if (ret)
364 return ret;
365 }
366
367 switch (node->u.field_class_declarator.type) {
368 case TYPEDEC_ID:
369 break;
370 case TYPEDEC_NESTED:
371 {
372 if (node->u.field_class_declarator.u.nested.field_class_declarator) {
373 ret = _ctf_visitor_semantic_check(
0f5c5d5c 374 depth + 1, node->u.field_class_declarator.u.nested.field_class_declarator, logger);
4164020e
SM
375 if (ret)
376 return ret;
377 }
378 if (!node->u.field_class_declarator.u.nested.abstract_array) {
379 bt_list_for_each_entry (iter, &node->u.field_class_declarator.u.nested.length,
380 siblings) {
381 if (iter->type != NODE_UNARY_EXPRESSION) {
0f5c5d5c
SM
382 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
383 logger, node->lineno, "Expecting unary expression as length: node-type={}",
4164020e
SM
384 node_type(iter));
385 return -EINVAL;
386 }
0f5c5d5c 387 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
388 if (ret)
389 return ret;
390 }
391 } else {
392 if (node->parent->type == NODE_TYPEALIAS_TARGET) {
0f5c5d5c
SM
393 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
394 logger, node->lineno,
4164020e
SM
395 "Abstract array declarator not permitted as target of field class alias.");
396 return -EINVAL;
397 }
398 }
399 if (node->u.field_class_declarator.bitfield_len) {
400 ret = _ctf_visitor_semantic_check(depth + 1,
0f5c5d5c 401 node->u.field_class_declarator.bitfield_len, logger);
4164020e
SM
402 if (ret)
403 return ret;
404 }
405 break;
406 }
407 case TYPEDEC_UNKNOWN:
408 default:
0f5c5d5c
SM
409 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
410 "Unknown field class declarator: type={}",
411 (int) node->u.field_class_declarator.type);
4164020e
SM
412 return -EINVAL;
413 }
414 depth--;
415 return 0;
e98a2d6e
PP
416
417errinval:
0f5c5d5c
SM
418 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
419 logger, node->lineno, "Incoherent parent node's type: node-type={}, parent-node-type={}",
4164020e
SM
420 node_type(node), node_type(node->parent));
421 return -EINVAL; /* Incoherent structure */
e98a2d6e
PP
422
423errperm:
0f5c5d5c
SM
424 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
425 "Semantic error: node-type={}, parent-node-type={}",
426 node_type(node), node_type(node->parent));
4164020e 427 return -EPERM; /* Structure not allowed */
e98a2d6e
PP
428}
429
0f5c5d5c 430static int _ctf_visitor_semantic_check(int depth, struct ctf_node *node, const bt2c::Logger& logger)
e98a2d6e 431{
4164020e
SM
432 int ret = 0;
433 struct ctf_node *iter;
434
435 if (node->visited)
436 return 0;
437
438 switch (node->type) {
439 case NODE_ROOT:
440 bt_list_for_each_entry (iter, &node->u.root.declaration_list, siblings) {
0f5c5d5c 441 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
442 if (ret)
443 return ret;
444 }
445 bt_list_for_each_entry (iter, &node->u.root.trace, siblings) {
0f5c5d5c 446 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
447 if (ret)
448 return ret;
449 }
450 bt_list_for_each_entry (iter, &node->u.root.stream, siblings) {
0f5c5d5c 451 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
452 if (ret)
453 return ret;
454 }
455 bt_list_for_each_entry (iter, &node->u.root.event, siblings) {
0f5c5d5c 456 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
457 if (ret)
458 return ret;
459 }
460 break;
461
462 case NODE_EVENT:
463 switch (node->parent->type) {
464 case NODE_ROOT:
465 break; /* OK */
466 default:
467 goto errinval;
468 }
469
470 bt_list_for_each_entry (iter, &node->u.event.declaration_list, siblings) {
0f5c5d5c 471 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
472 if (ret)
473 return ret;
474 }
475 break;
476 case NODE_STREAM:
477 switch (node->parent->type) {
478 case NODE_ROOT:
479 break; /* OK */
480 default:
481 goto errinval;
482 }
483
484 bt_list_for_each_entry (iter, &node->u.stream.declaration_list, siblings) {
0f5c5d5c 485 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
486 if (ret)
487 return ret;
488 }
489 break;
490 case NODE_ENV:
491 switch (node->parent->type) {
492 case NODE_ROOT:
493 break; /* OK */
494 default:
495 goto errinval;
496 }
497
498 bt_list_for_each_entry (iter, &node->u.env.declaration_list, siblings) {
0f5c5d5c 499 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
500 if (ret)
501 return ret;
502 }
503 break;
504 case NODE_TRACE:
505 switch (node->parent->type) {
506 case NODE_ROOT:
507 break; /* OK */
508 default:
509 goto errinval;
510 }
511
512 bt_list_for_each_entry (iter, &node->u.trace.declaration_list, siblings) {
0f5c5d5c 513 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
514 if (ret)
515 return ret;
516 }
517 break;
518 case NODE_CLOCK:
519 switch (node->parent->type) {
520 case NODE_ROOT:
521 break; /* OK */
522 default:
523 goto errinval;
524 }
525
526 bt_list_for_each_entry (iter, &node->u.clock.declaration_list, siblings) {
0f5c5d5c 527 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
528 if (ret)
529 return ret;
530 }
531 break;
532 case NODE_CALLSITE:
533 switch (node->parent->type) {
534 case NODE_ROOT:
535 break; /* OK */
536 default:
537 goto errinval;
538 }
539
540 bt_list_for_each_entry (iter, &node->u.callsite.declaration_list, siblings) {
0f5c5d5c 541 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
542 if (ret)
543 return ret;
544 }
545 break;
546
547 case NODE_CTF_EXPRESSION:
548 switch (node->parent->type) {
549 case NODE_ROOT:
550 case NODE_EVENT:
551 case NODE_STREAM:
552 case NODE_ENV:
553 case NODE_TRACE:
554 case NODE_CLOCK:
555 case NODE_CALLSITE:
556 case NODE_FLOATING_POINT:
557 case NODE_INTEGER:
558 case NODE_STRING:
559 break; /* OK */
560
561 case NODE_CTF_EXPRESSION:
562 case NODE_UNARY_EXPRESSION:
563 case NODE_TYPEDEF:
564 case NODE_TYPEALIAS_TARGET:
565 case NODE_TYPEALIAS_ALIAS:
566 case NODE_STRUCT_OR_VARIANT_DECLARATION:
567 case NODE_TYPEALIAS:
568 case NODE_TYPE_SPECIFIER:
569 case NODE_TYPE_SPECIFIER_LIST:
570 case NODE_POINTER:
571 case NODE_TYPE_DECLARATOR:
572 case NODE_ENUMERATOR:
573 case NODE_ENUM:
574 case NODE_VARIANT:
575 case NODE_STRUCT:
576 default:
577 goto errinval;
578 }
579
580 depth++;
581 bt_list_for_each_entry (iter, &node->u.ctf_expression.left, siblings) {
0f5c5d5c 582 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
583 if (ret)
584 return ret;
585 }
586 bt_list_for_each_entry (iter, &node->u.ctf_expression.right, siblings) {
0f5c5d5c 587 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
588 if (ret)
589 return ret;
590 }
591 depth--;
592 break;
593 case NODE_UNARY_EXPRESSION:
0f5c5d5c 594 return ctf_visitor_unary_expression(depth, node, logger);
4164020e
SM
595
596 case NODE_TYPEDEF:
597 switch (node->parent->type) {
598 case NODE_ROOT:
599 case NODE_EVENT:
600 case NODE_STREAM:
601 case NODE_TRACE:
602 case NODE_VARIANT:
603 case NODE_STRUCT:
604 break; /* OK */
605
606 case NODE_CTF_EXPRESSION:
607 case NODE_UNARY_EXPRESSION:
608 case NODE_TYPEDEF:
609 case NODE_TYPEALIAS_TARGET:
610 case NODE_TYPEALIAS_ALIAS:
611 case NODE_TYPEALIAS:
612 case NODE_STRUCT_OR_VARIANT_DECLARATION:
613 case NODE_TYPE_SPECIFIER:
614 case NODE_TYPE_SPECIFIER_LIST:
615 case NODE_POINTER:
616 case NODE_TYPE_DECLARATOR:
617 case NODE_FLOATING_POINT:
618 case NODE_INTEGER:
619 case NODE_STRING:
620 case NODE_ENUMERATOR:
621 case NODE_ENUM:
622 case NODE_CLOCK:
623 case NODE_CALLSITE:
624 case NODE_ENV:
625 default:
626 goto errinval;
627 }
628
629 depth++;
630 ret = _ctf_visitor_semantic_check(
0f5c5d5c 631 depth + 1, node->u.field_class_def.field_class_specifier_list, logger);
4164020e
SM
632 if (ret)
633 return ret;
634 bt_list_for_each_entry (iter, &node->u.field_class_def.field_class_declarators, siblings) {
0f5c5d5c 635 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
636 if (ret)
637 return ret;
638 }
639 depth--;
640 break;
641 case NODE_TYPEALIAS_TARGET:
642 {
643 int nr_declarators;
644
645 switch (node->parent->type) {
646 case NODE_TYPEALIAS:
647 break; /* OK */
648 default:
649 goto errinval;
650 }
651
652 depth++;
653 ret = _ctf_visitor_semantic_check(
0f5c5d5c 654 depth + 1, node->u.field_class_alias_target.field_class_specifier_list, logger);
4164020e
SM
655 if (ret)
656 return ret;
657 nr_declarators = 0;
658 bt_list_for_each_entry (iter, &node->u.field_class_alias_target.field_class_declarators,
659 siblings) {
0f5c5d5c 660 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
661 if (ret)
662 return ret;
663 nr_declarators++;
664 }
665 if (nr_declarators > 1) {
0f5c5d5c
SM
666 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
667 logger, node->lineno,
668 "Too many declarators in field class alias's name (maximum is 1): count={}",
4164020e
SM
669 nr_declarators);
670 return -EINVAL;
671 }
672 depth--;
673 break;
674 }
675 case NODE_TYPEALIAS_ALIAS:
676 {
677 int nr_declarators;
678
679 switch (node->parent->type) {
680 case NODE_TYPEALIAS:
681 break; /* OK */
682 default:
683 goto errinval;
684 }
685
686 depth++;
687 ret = _ctf_visitor_semantic_check(
0f5c5d5c 688 depth + 1, node->u.field_class_alias_name.field_class_specifier_list, logger);
4164020e
SM
689 if (ret)
690 return ret;
691 nr_declarators = 0;
692 bt_list_for_each_entry (iter, &node->u.field_class_alias_name.field_class_declarators,
693 siblings) {
0f5c5d5c 694 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
695 if (ret)
696 return ret;
697 nr_declarators++;
698 }
699 if (nr_declarators > 1) {
0f5c5d5c
SM
700 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
701 logger, node->lineno,
702 "Too many declarators in field class alias's name (maximum is 1): count={}",
4164020e
SM
703 nr_declarators);
704 return -EINVAL;
705 }
706 depth--;
707 break;
708 }
709 case NODE_TYPEALIAS:
710 switch (node->parent->type) {
711 case NODE_ROOT:
712 case NODE_EVENT:
713 case NODE_STREAM:
714 case NODE_TRACE:
715 case NODE_VARIANT:
716 case NODE_STRUCT:
717 break; /* OK */
718
719 case NODE_CTF_EXPRESSION:
720 case NODE_UNARY_EXPRESSION:
721 case NODE_TYPEDEF:
722 case NODE_TYPEALIAS_TARGET:
723 case NODE_TYPEALIAS_ALIAS:
724 case NODE_TYPEALIAS:
725 case NODE_STRUCT_OR_VARIANT_DECLARATION:
726 case NODE_TYPE_SPECIFIER:
727 case NODE_TYPE_SPECIFIER_LIST:
728 case NODE_POINTER:
729 case NODE_TYPE_DECLARATOR:
730 case NODE_FLOATING_POINT:
731 case NODE_INTEGER:
732 case NODE_STRING:
733 case NODE_ENUMERATOR:
734 case NODE_ENUM:
735 case NODE_CLOCK:
736 case NODE_CALLSITE:
737 case NODE_ENV:
738 default:
739 goto errinval;
740 }
741
0f5c5d5c 742 ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.target, logger);
4164020e
SM
743 if (ret)
744 return ret;
0f5c5d5c 745 ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.alias, logger);
4164020e
SM
746 if (ret)
747 return ret;
748 break;
749
750 case NODE_TYPE_SPECIFIER_LIST:
0f5c5d5c 751 ret = ctf_visitor_field_class_specifier_list(depth, node, logger);
4164020e
SM
752 if (ret)
753 return ret;
754 break;
755 case NODE_TYPE_SPECIFIER:
0f5c5d5c 756 ret = ctf_visitor_field_class_specifier(depth, node, logger);
4164020e
SM
757 if (ret)
758 return ret;
759 break;
760 case NODE_POINTER:
761 switch (node->parent->type) {
762 case NODE_TYPE_DECLARATOR:
763 break; /* OK */
764 default:
765 goto errinval;
766 }
767 break;
768 case NODE_TYPE_DECLARATOR:
0f5c5d5c 769 ret = ctf_visitor_field_class_declarator(depth, node, logger);
4164020e
SM
770 if (ret)
771 return ret;
772 break;
773
774 case NODE_FLOATING_POINT:
775 switch (node->parent->type) {
776 case NODE_TYPE_SPECIFIER:
777 break; /* OK */
778 default:
779 goto errinval;
780
781 case NODE_UNARY_EXPRESSION:
782 goto errperm;
783 }
784 bt_list_for_each_entry (iter, &node->u.floating_point.expressions, siblings) {
0f5c5d5c 785 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
786 if (ret)
787 return ret;
788 }
789 break;
790 case NODE_INTEGER:
791 switch (node->parent->type) {
792 case NODE_TYPE_SPECIFIER:
793 break; /* OK */
794 default:
795 goto errinval;
796 }
797
798 bt_list_for_each_entry (iter, &node->u.integer.expressions, siblings) {
0f5c5d5c 799 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
800 if (ret)
801 return ret;
802 }
803 break;
804 case NODE_STRING:
805 switch (node->parent->type) {
806 case NODE_TYPE_SPECIFIER:
807 break; /* OK */
808 default:
809 goto errinval;
810
811 case NODE_UNARY_EXPRESSION:
812 goto errperm;
813 }
814
815 bt_list_for_each_entry (iter, &node->u.string.expressions, siblings) {
0f5c5d5c 816 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
817 if (ret)
818 return ret;
819 }
820 break;
821 case NODE_ENUMERATOR:
822 switch (node->parent->type) {
823 case NODE_ENUM:
824 break;
825 default:
826 goto errinval;
827 }
828 /*
829 * Enumerators are only allows to contain:
830 * numeric unary expression
831 * or num. unary exp. ... num. unary exp
832 */
833 {
834 int count = 0;
835
836 bt_list_for_each_entry (iter, &node->u.enumerator.values, siblings) {
837 switch (count++) {
838 case 0:
839 if (iter->type != NODE_UNARY_EXPRESSION ||
840 (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT &&
841 iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) ||
842 iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) {
0f5c5d5c
SM
843 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
844 logger, iter->lineno,
845 "First unary expression of enumerator is unexpected.");
4164020e
SM
846 goto errperm;
847 }
848 break;
849 case 1:
850 if (iter->type != NODE_UNARY_EXPRESSION ||
851 (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT &&
852 iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) ||
853 iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
0f5c5d5c
SM
854 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
855 logger, iter->lineno,
856 "Second unary expression of enumerator is unexpected.");
4164020e
SM
857 goto errperm;
858 }
859 break;
860 default:
861 goto errperm;
862 }
863 }
864 }
865
866 bt_list_for_each_entry (iter, &node->u.enumerator.values, siblings) {
0f5c5d5c 867 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
868 if (ret)
869 return ret;
870 }
871 break;
872 case NODE_ENUM:
873 switch (node->parent->type) {
874 case NODE_TYPE_SPECIFIER:
875 break; /* OK */
876 default:
877 goto errinval;
878
879 case NODE_UNARY_EXPRESSION:
880 goto errperm;
881 }
882
883 depth++;
0f5c5d5c 884 ret = _ctf_visitor_semantic_check(depth + 1, node->u._enum.container_field_class, logger);
4164020e
SM
885 if (ret)
886 return ret;
887
888 bt_list_for_each_entry (iter, &node->u._enum.enumerator_list, siblings) {
0f5c5d5c 889 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
890 if (ret)
891 return ret;
892 }
893 depth--;
894 break;
895 case NODE_STRUCT_OR_VARIANT_DECLARATION:
896 switch (node->parent->type) {
897 case NODE_STRUCT:
898 case NODE_VARIANT:
899 break;
900 default:
901 goto errinval;
902 }
903 ret = _ctf_visitor_semantic_check(
0f5c5d5c 904 depth + 1, node->u.struct_or_variant_declaration.field_class_specifier_list, logger);
4164020e
SM
905 if (ret)
906 return ret;
907 bt_list_for_each_entry (
908 iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) {
0f5c5d5c 909 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
910 if (ret)
911 return ret;
912 }
913 break;
914 case NODE_VARIANT:
915 switch (node->parent->type) {
916 case NODE_TYPE_SPECIFIER:
917 break; /* OK */
918 default:
919 goto errinval;
920
921 case NODE_UNARY_EXPRESSION:
922 goto errperm;
923 }
924 bt_list_for_each_entry (iter, &node->u.variant.declaration_list, siblings) {
0f5c5d5c 925 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
926 if (ret)
927 return ret;
928 }
929 break;
930
931 case NODE_STRUCT:
932 switch (node->parent->type) {
933 case NODE_TYPE_SPECIFIER:
934 break; /* OK */
935 default:
936 goto errinval;
937
938 case NODE_UNARY_EXPRESSION:
939 goto errperm;
940 }
941 bt_list_for_each_entry (iter, &node->u._struct.declaration_list, siblings) {
0f5c5d5c 942 ret = _ctf_visitor_semantic_check(depth + 1, iter, logger);
4164020e
SM
943 if (ret)
944 return ret;
945 }
946 break;
947
948 case NODE_UNKNOWN:
949 default:
0f5c5d5c
SM
950 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno, "Unknown node type: type={}",
951 (int) node->type);
4164020e
SM
952 return -EINVAL;
953 }
954 return ret;
e98a2d6e
PP
955
956errinval:
0f5c5d5c
SM
957 _BT_CPPLOGE_APPEND_CAUSE_LINENO(
958 logger, node->lineno, "Incoherent parent node's type: node-type={}, parent-node-type={}",
4164020e
SM
959 node_type(node), node_type(node->parent));
960 return -EINVAL; /* Incoherent structure */
e98a2d6e
PP
961
962errperm:
0f5c5d5c
SM
963 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
964 "Semantic error: node-type={}, parent-node-type={}",
965 node_type(node), node_type(node->parent));
4164020e 966 return -EPERM; /* Structure not allowed */
e98a2d6e
PP
967}
968
0f5c5d5c 969int ctf_visitor_semantic_check(int depth, struct ctf_node *node, const bt2c::Logger& parentLogger)
e98a2d6e 970{
4164020e 971 int ret = 0;
0f5c5d5c 972 bt2c::Logger logger {parentLogger, "PLUGIN/CTF/META/SEMANTIC-VALIDATOR-VISITOR"};
4164020e
SM
973
974 /*
975 * First make sure we create the parent links for all children. Let's
976 * take the safe route and recreate them at each validation, just in
977 * case the structure has changed.
978 */
0f5c5d5c 979 ret = ctf_visitor_parent_links(depth, node, logger);
4164020e 980 if (ret) {
0f5c5d5c
SM
981 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
982 "Cannot create parent links in metadata's AST: "
983 "ret={}",
984 ret);
4164020e
SM
985 goto end;
986 }
987
0f5c5d5c 988 ret = _ctf_visitor_semantic_check(depth, node, logger);
4164020e 989 if (ret) {
0f5c5d5c
SM
990 _BT_CPPLOGE_APPEND_CAUSE_LINENO(logger, node->lineno,
991 "Cannot check metadata's AST semantics: "
992 "ret={}",
993 ret);
4164020e
SM
994 goto end;
995 }
41b60475 996
55314f2a 997end:
4164020e 998 return ret;
e98a2d6e 999}
This page took 0.19135 seconds and 4 git commands to generate.