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