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