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