AST semantic validation: add unary exp tests
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-semantic-validator.c
1 /*
2 * ctf-visitor-semantic-validator.c
3 *
4 * Common Trace Format Metadata Semantic Validator.
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <glib.h>
25 #include <inttypes.h>
26 #include <errno.h>
27 #include <babeltrace/list.h>
28 #include "ctf-scanner.h"
29 #include "ctf-parser.h"
30 #include "ctf-ast.h"
31
32 #define _cds_list_first_entry(ptr, type, member) \
33 cds_list_entry((ptr)->next, type, member)
34
35 #define printf_dbg(fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
36
37 static
38 int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node);
39
40 static
41 int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
42 {
43 struct ctf_node *iter;
44 int is_ctf_exp_left = 0;
45
46 switch (node->parent->type) {
47 case NODE_CTF_EXPRESSION:
48 cds_list_for_each_entry(iter, &node->parent->u.ctf_expression.left,
49 siblings) {
50 if (iter == node) {
51 is_ctf_exp_left = 1;
52 /*
53 * We are a left child of a ctf expression.
54 * We are only allowed to be a string.
55 */
56 if (node->u.unary_expression.type != UNARY_STRING)
57 goto errperm;
58 break;
59 }
60 }
61 /* Right child of a ctf expression can be any type of unary exp. */
62 break; /* OK */
63 case NODE_TYPE_DECLARATOR:
64 /*
65 * We are the length of a type declarator. We can only be
66 * a numeric constant.
67 */
68 switch (node->u.unary_expression.type) {
69 case UNARY_SIGNED_CONSTANT:
70 case UNARY_UNSIGNED_CONSTANT:
71 break;
72 default:
73 goto errperm;
74 }
75 break; /* OK */
76 case NODE_ENUMERATOR:
77 /* The enumerator's parent has validated its validity already. */
78 break; /* OK */
79
80 case NODE_UNARY_EXPRESSION:
81 /*
82 * We disallow nested unary expressions and "sbrac" unary
83 * expressions.
84 */
85 goto errperm;
86
87 case NODE_ROOT:
88 case NODE_EVENT:
89 case NODE_STREAM:
90 case NODE_TRACE:
91 case NODE_TYPEDEF:
92 case NODE_TYPEALIAS_TARGET:
93 case NODE_TYPEALIAS_ALIAS:
94 case NODE_TYPEALIAS:
95 case NODE_TYPE_SPECIFIER:
96 case NODE_POINTER:
97 case NODE_FLOATING_POINT:
98 case NODE_INTEGER:
99 case NODE_ENUM:
100 case NODE_STRING:
101 case NODE_STRUCT_OR_VARIANT_DECLARATION:
102 case NODE_VARIANT:
103 case NODE_STRUCT:
104 default:
105 goto errinval;
106 }
107
108 switch (node->u.unary_expression.link) {
109 case UNARY_LINK_UNKNOWN:
110 /* We don't allow empty link except on the first node of the list */
111 if (_cds_list_first_entry(is_ctf_exp_left ?
112 &node->parent->u.ctf_expression.left :
113 &node->parent->u.ctf_expression.right,
114 struct ctf_node,
115 siblings) != node)
116 goto errperm;
117 break; /* OK */
118 case UNARY_DOTLINK:
119 case UNARY_ARROWLINK:
120 /* We only allow -> and . links between children of ctf_expression. */
121 if (node->parent->type != NODE_CTF_EXPRESSION)
122 goto errperm;
123 /* We don't allow link on the first node of the list */
124 if (_cds_list_first_entry(is_ctf_exp_left ?
125 &node->parent->u.ctf_expression.left :
126 &node->parent->u.ctf_expression.right,
127 struct ctf_node,
128 siblings) == node)
129 goto errperm;
130 /*
131 * Only strings can be separated linked by . or ->.
132 * This includes "", '' and non-quoted identifiers.
133 */
134 if (node->u.unary_expression.type != UNARY_STRING)
135 goto errperm;
136 break;
137 case UNARY_DOTDOTDOT:
138 /* We only allow ... link between children of enumerator. */
139 if (node->parent->type != NODE_ENUMERATOR)
140 goto errperm;
141 /* We don't allow link on the first node of the list */
142 if (_cds_list_first_entry(&node->parent->u.enumerator.values,
143 struct ctf_node,
144 siblings) == node)
145 return -EPERM;
146 break;
147 default:
148 fprintf(fd, "[error] %s: unknown expression link type %d\n", __func__,
149 (int) node->u.unary_expression.link);
150 return -EINVAL;
151 }
152 return 0;
153
154 errinval:
155 fprintf(fd, "[error] %s: incoherent parent type %d for node type %d\n", __func__,
156 (int) node->parent->type, (int) node->type);
157 return -EINVAL; /* Incoherent structure */
158
159 errperm:
160 return -EPERM; /* Structure not allowed */
161 }
162
163 static
164 int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node)
165 {
166 switch (node->parent->type) {
167 case NODE_CTF_EXPRESSION:
168 case NODE_TYPE_DECLARATOR:
169 case NODE_TYPEDEF:
170 case NODE_TYPEALIAS_TARGET:
171 case NODE_TYPEALIAS_ALIAS:
172 case NODE_ENUM:
173 break; /* OK */
174
175 case NODE_ROOT:
176 case NODE_EVENT:
177 case NODE_STREAM:
178 case NODE_TRACE:
179 case NODE_UNARY_EXPRESSION:
180 case NODE_TYPEALIAS:
181 case NODE_TYPE_SPECIFIER:
182 case NODE_POINTER:
183 case NODE_FLOATING_POINT:
184 case NODE_INTEGER:
185 case NODE_STRING:
186 case NODE_ENUMERATOR:
187 case NODE_STRUCT_OR_VARIANT_DECLARATION:
188 case NODE_VARIANT:
189 case NODE_STRUCT:
190 default:
191 goto errinval;
192 }
193 return 0;
194 errinval:
195 fprintf(fd, "[error] %s: incoherent parent type %d for node type %d\n", __func__,
196 (int) node->parent->type, (int) node->type);
197 return -EINVAL; /* Incoherent structure */
198 }
199
200 static
201 int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
202 {
203 int ret = 0;
204 struct ctf_node *iter;
205
206 depth++;
207
208 switch (node->parent->type) {
209 case NODE_TYPE_DECLARATOR:
210 /*
211 * A nested type declarator is not allowed to contain pointers.
212 */
213 if (!cds_list_empty(&node->u.type_declarator.pointers))
214 goto errperm;
215 /* Fall-through */
216 case NODE_TYPEDEF:
217 case NODE_TYPEALIAS_TARGET:
218 case NODE_TYPEALIAS_ALIAS:
219 case NODE_STRUCT_OR_VARIANT_DECLARATION:
220 break; /* OK */
221
222 case NODE_ROOT:
223 case NODE_EVENT:
224 case NODE_STREAM:
225 case NODE_TRACE:
226 case NODE_CTF_EXPRESSION:
227 case NODE_UNARY_EXPRESSION:
228 case NODE_TYPEALIAS:
229 case NODE_TYPE_SPECIFIER:
230 case NODE_POINTER:
231 case NODE_FLOATING_POINT:
232 case NODE_INTEGER:
233 case NODE_STRING:
234 case NODE_ENUMERATOR:
235 case NODE_ENUM:
236 case NODE_VARIANT:
237 case NODE_STRUCT:
238 default:
239 goto errinval;
240 }
241
242 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
243 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
244 siblings) {
245 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
246 if (ret)
247 return ret;
248 }
249 }
250
251 switch (node->u.type_declarator.type) {
252 case TYPEDEC_ID:
253 break;
254 case TYPEDEC_NESTED:
255 if (node->u.type_declarator.u.nested.type_declarator) {
256 ret = _ctf_visitor_semantic_check(fd, depth + 1,
257 node->u.type_declarator.u.nested.type_declarator);
258 if (ret)
259 return ret;
260 }
261 if (node->u.type_declarator.u.nested.length) {
262 ret = _ctf_visitor_semantic_check(fd, depth + 1,
263 node->u.type_declarator.u.nested.length);
264 if (ret)
265 return ret;
266 }
267 if (node->u.type_declarator.bitfield_len) {
268 ret = _ctf_visitor_semantic_check(fd, depth + 1,
269 node->u.type_declarator.bitfield_len);
270 if (ret)
271 return ret;
272 }
273 break;
274 case TYPEDEC_UNKNOWN:
275 default:
276 fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
277 (int) node->u.type_declarator.type);
278 return -EINVAL;
279 }
280 depth--;
281 return 0;
282
283 errinval:
284 fprintf(fd, "[error] %s: incoherent parent type %d for node type %d\n", __func__,
285 (int) node->parent->type, (int) node->type);
286 return -EINVAL; /* Incoherent structure */
287
288 errperm:
289 return -EPERM; /* Structure not allowed */
290 }
291
292 static
293 int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
294 {
295 int ret = 0;
296 struct ctf_node *iter;
297
298 switch (node->type) {
299 case NODE_ROOT:
300 cds_list_for_each_entry(iter, &node->u.root._typedef,
301 siblings) {
302 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
303 if (ret)
304 return ret;
305 }
306 cds_list_for_each_entry(iter, &node->u.root.typealias,
307 siblings) {
308 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
309 if (ret)
310 return ret;
311 }
312 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
313 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
314 if (ret)
315 return ret;
316 }
317 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
318 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
319 if (ret)
320 return ret;
321 }
322 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
323 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
324 if (ret)
325 return ret;
326 }
327 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
328 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
329 if (ret)
330 return ret;
331 }
332 break;
333
334 case NODE_EVENT:
335 switch (node->parent->type) {
336 case NODE_ROOT:
337 break; /* OK */
338 default:
339 goto errinval;
340 }
341
342 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
343 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
344 if (ret)
345 return ret;
346 }
347 break;
348 case NODE_STREAM:
349 switch (node->parent->type) {
350 case NODE_ROOT:
351 break; /* OK */
352 default:
353 goto errinval;
354 }
355
356 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
357 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
358 if (ret)
359 return ret;
360 }
361 break;
362 case NODE_TRACE:
363 switch (node->parent->type) {
364 case NODE_ROOT:
365 break; /* OK */
366 default:
367 goto errinval;
368 }
369
370 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
371 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
372 if (ret)
373 return ret;
374 }
375 break;
376
377 case NODE_CTF_EXPRESSION:
378 switch (node->parent->type) {
379 case NODE_ROOT:
380 case NODE_EVENT:
381 case NODE_STREAM:
382 case NODE_TRACE:
383 case NODE_FLOATING_POINT:
384 case NODE_INTEGER:
385 case NODE_STRING:
386 break; /* OK */
387
388 case NODE_CTF_EXPRESSION:
389 case NODE_UNARY_EXPRESSION:
390 case NODE_TYPEDEF:
391 case NODE_TYPEALIAS_TARGET:
392 case NODE_TYPEALIAS_ALIAS:
393 case NODE_STRUCT_OR_VARIANT_DECLARATION:
394 case NODE_TYPEALIAS:
395 case NODE_TYPE_SPECIFIER:
396 case NODE_POINTER:
397 case NODE_TYPE_DECLARATOR:
398 case NODE_ENUMERATOR:
399 case NODE_ENUM:
400 case NODE_VARIANT:
401 case NODE_STRUCT:
402 default:
403 goto errinval;
404 }
405
406 depth++;
407 cds_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
408 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
409 if (ret)
410 return ret;
411 }
412 cds_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
413 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
414 if (ret)
415 return ret;
416 }
417 depth--;
418 break;
419 case NODE_UNARY_EXPRESSION:
420 return ctf_visitor_unary_expression(fd, depth, node);
421
422 case NODE_TYPEDEF:
423 switch (node->parent->type) {
424 case NODE_ROOT:
425 case NODE_EVENT:
426 case NODE_STREAM:
427 case NODE_TRACE:
428 case NODE_VARIANT:
429 case NODE_STRUCT:
430 break; /* OK */
431
432 case NODE_CTF_EXPRESSION:
433 case NODE_UNARY_EXPRESSION:
434 case NODE_TYPEDEF:
435 case NODE_TYPEALIAS_TARGET:
436 case NODE_TYPEALIAS_ALIAS:
437 case NODE_TYPEALIAS:
438 case NODE_STRUCT_OR_VARIANT_DECLARATION:
439 case NODE_TYPE_SPECIFIER:
440 case NODE_POINTER:
441 case NODE_TYPE_DECLARATOR:
442 case NODE_FLOATING_POINT:
443 case NODE_INTEGER:
444 case NODE_STRING:
445 case NODE_ENUMERATOR:
446 case NODE_ENUM:
447 default:
448 goto errinval;
449 }
450
451 depth++;
452 cds_list_for_each_entry(iter, &node->u._typedef.declaration_specifier, siblings) {
453 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
454 if (ret)
455 return ret;
456 }
457 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
458 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
459 if (ret)
460 return ret;
461 }
462 depth--;
463 break;
464 case NODE_TYPEALIAS_TARGET:
465 switch (node->parent->type) {
466 case NODE_TYPEALIAS:
467 break; /* OK */
468 default:
469 goto errinval;
470 }
471
472 depth++;
473 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
474 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
475 if (ret)
476 return ret;
477 }
478 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
479 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
480 if (ret)
481 return ret;
482 }
483 depth--;
484 break;
485 case NODE_TYPEALIAS_ALIAS:
486 switch (node->parent->type) {
487 case NODE_TYPEALIAS:
488 break; /* OK */
489 default:
490 goto errinval;
491 }
492
493 depth++;
494 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
495 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
496 if (ret)
497 return ret;
498 }
499 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
500 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
501 if (ret)
502 return ret;
503 }
504 depth--;
505 break;
506 case NODE_TYPEALIAS:
507 switch (node->parent->type) {
508 case NODE_ROOT:
509 case NODE_EVENT:
510 case NODE_STREAM:
511 case NODE_TRACE:
512 case NODE_VARIANT:
513 case NODE_STRUCT:
514 break; /* OK */
515
516 case NODE_CTF_EXPRESSION:
517 case NODE_UNARY_EXPRESSION:
518 case NODE_TYPEDEF:
519 case NODE_TYPEALIAS_TARGET:
520 case NODE_TYPEALIAS_ALIAS:
521 case NODE_TYPEALIAS:
522 case NODE_STRUCT_OR_VARIANT_DECLARATION:
523 case NODE_TYPE_SPECIFIER:
524 case NODE_POINTER:
525 case NODE_TYPE_DECLARATOR:
526 case NODE_FLOATING_POINT:
527 case NODE_INTEGER:
528 case NODE_STRING:
529 case NODE_ENUMERATOR:
530 case NODE_ENUM:
531 default:
532 goto errinval;
533 }
534
535 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.target);
536 if (ret)
537 return ret;
538 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.alias);
539 if (ret)
540 return ret;
541 break;
542
543 case NODE_TYPE_SPECIFIER:
544 ret = ctf_visitor_type_specifier(fd, depth, node);
545 if (ret)
546 return ret;
547 break;
548 case NODE_POINTER:
549 switch (node->parent->type) {
550 case NODE_TYPE_DECLARATOR:
551 break; /* OK */
552 default:
553 goto errinval;
554 }
555 break;
556 case NODE_TYPE_DECLARATOR:
557 ret = ctf_visitor_type_declarator(fd, depth, node);
558 if (ret)
559 return ret;
560 break;
561
562 case NODE_FLOATING_POINT:
563 switch (node->parent->type) {
564 case NODE_CTF_EXPRESSION:
565 case NODE_TYPEDEF:
566 case NODE_TYPEALIAS_TARGET:
567 case NODE_TYPEALIAS_ALIAS:
568 case NODE_STRUCT_OR_VARIANT_DECLARATION:
569 break; /* OK */
570
571 case NODE_ROOT:
572 case NODE_EVENT:
573 case NODE_STREAM:
574 case NODE_TRACE:
575 case NODE_TYPEALIAS:
576 case NODE_TYPE_SPECIFIER:
577 case NODE_POINTER:
578 case NODE_TYPE_DECLARATOR:
579 case NODE_FLOATING_POINT:
580 case NODE_INTEGER:
581 case NODE_STRING:
582 case NODE_ENUMERATOR:
583 case NODE_ENUM:
584 case NODE_VARIANT:
585 case NODE_STRUCT:
586 default:
587 goto errinval;
588
589 case NODE_UNARY_EXPRESSION:
590 goto errperm;
591 }
592 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
593 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
594 if (ret)
595 return ret;
596 }
597 break;
598 case NODE_INTEGER:
599 switch (node->parent->type) {
600 case NODE_CTF_EXPRESSION:
601 case NODE_UNARY_EXPRESSION:
602 case NODE_TYPEDEF:
603 case NODE_TYPEALIAS_TARGET:
604 case NODE_TYPEALIAS_ALIAS:
605 case NODE_TYPE_DECLARATOR:
606 case NODE_ENUM:
607 case NODE_STRUCT_OR_VARIANT_DECLARATION:
608 break; /* OK */
609
610 case NODE_ROOT:
611 case NODE_EVENT:
612 case NODE_STREAM:
613 case NODE_TRACE:
614 case NODE_TYPEALIAS:
615 case NODE_TYPE_SPECIFIER:
616 case NODE_POINTER:
617 case NODE_FLOATING_POINT:
618 case NODE_INTEGER:
619 case NODE_STRING:
620 case NODE_ENUMERATOR:
621 case NODE_VARIANT:
622 case NODE_STRUCT:
623 default:
624 goto errinval;
625
626 }
627
628 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
629 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
630 if (ret)
631 return ret;
632 }
633 break;
634 case NODE_STRING:
635 switch (node->parent->type) {
636 case NODE_CTF_EXPRESSION:
637 case NODE_TYPEDEF:
638 case NODE_TYPEALIAS_TARGET:
639 case NODE_TYPEALIAS_ALIAS:
640 case NODE_STRUCT_OR_VARIANT_DECLARATION:
641 break; /* OK */
642
643 case NODE_ROOT:
644 case NODE_EVENT:
645 case NODE_STREAM:
646 case NODE_TRACE:
647 case NODE_TYPEALIAS:
648 case NODE_TYPE_SPECIFIER:
649 case NODE_POINTER:
650 case NODE_TYPE_DECLARATOR:
651 case NODE_FLOATING_POINT:
652 case NODE_INTEGER:
653 case NODE_STRING:
654 case NODE_ENUMERATOR:
655 case NODE_ENUM:
656 case NODE_VARIANT:
657 case NODE_STRUCT:
658 default:
659 goto errinval;
660
661 case NODE_UNARY_EXPRESSION:
662 goto errperm;
663 }
664
665 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
666 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
667 if (ret)
668 return ret;
669 }
670 break;
671 case NODE_ENUMERATOR:
672 switch (node->parent->type) {
673 case NODE_ENUM:
674 break;
675 default:
676 goto errinval;
677 }
678 /*
679 * Enumerators are only allows to contain:
680 * numeric unary expression
681 * or num. unary exp. ... num. unary exp
682 */
683 {
684 int count = 0;
685
686 cds_list_for_each_entry(iter, &node->parent->u.enumerator.values,
687 siblings) {
688 switch (count++) {
689 case 0: if (iter->type != NODE_UNARY_EXPRESSION
690 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
691 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
692 || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN)
693 goto errperm;
694 break;
695 case 1: if (iter->type != NODE_UNARY_EXPRESSION
696 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
697 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
698 || iter->u.unary_expression.link != UNARY_DOTDOTDOT)
699 goto errperm;
700 break;
701 default:
702 goto errperm;
703 }
704 }
705 }
706
707 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
708 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
709 if (ret)
710 return ret;
711 }
712 break;
713 case NODE_ENUM:
714 switch (node->parent->type) {
715 case NODE_ROOT:
716 case NODE_EVENT:
717 case NODE_STREAM:
718 case NODE_TRACE:
719 case NODE_CTF_EXPRESSION:
720 case NODE_TYPEDEF:
721 case NODE_TYPEALIAS_TARGET:
722 case NODE_TYPEALIAS_ALIAS:
723 case NODE_TYPE_DECLARATOR:
724 case NODE_STRUCT_OR_VARIANT_DECLARATION:
725 break; /* OK */
726
727 case NODE_TYPEALIAS:
728 case NODE_TYPE_SPECIFIER:
729 case NODE_POINTER:
730 case NODE_FLOATING_POINT:
731 case NODE_INTEGER:
732 case NODE_STRING:
733 case NODE_ENUMERATOR:
734 case NODE_ENUM:
735 case NODE_VARIANT:
736 case NODE_STRUCT:
737 default:
738 goto errinval;
739
740 case NODE_UNARY_EXPRESSION:
741 goto errperm;
742 }
743
744 depth++;
745 if (node->u._enum.container_type) {
746 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type);
747 if (ret)
748 return ret;
749 }
750
751 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
752 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
753 if (ret)
754 return ret;
755 }
756 depth--;
757 break;
758 case NODE_STRUCT_OR_VARIANT_DECLARATION:
759 switch (node->parent->type) {
760 case NODE_STRUCT:
761 case NODE_VARIANT:
762 break;
763 default:
764 goto errinval;
765 }
766 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
767 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
768 if (ret)
769 return ret;
770 }
771 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
772 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
773 if (ret)
774 return ret;
775 }
776 break;
777 case NODE_VARIANT:
778 switch (node->parent->type) {
779 case NODE_ROOT:
780 case NODE_EVENT:
781 case NODE_STREAM:
782 case NODE_TRACE:
783 case NODE_CTF_EXPRESSION:
784 case NODE_TYPEDEF:
785 case NODE_TYPEALIAS_TARGET:
786 case NODE_TYPEALIAS_ALIAS:
787 case NODE_STRUCT_OR_VARIANT_DECLARATION:
788 break; /* OK */
789
790 case NODE_TYPEALIAS:
791 case NODE_TYPE_SPECIFIER:
792 case NODE_POINTER:
793 case NODE_TYPE_DECLARATOR:
794 case NODE_FLOATING_POINT:
795 case NODE_INTEGER:
796 case NODE_STRING:
797 case NODE_ENUMERATOR:
798 case NODE_ENUM:
799 case NODE_VARIANT:
800 case NODE_STRUCT:
801 default:
802 goto errinval;
803
804 case NODE_UNARY_EXPRESSION:
805 goto errperm;
806 }
807 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
808 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
809 if (ret)
810 return ret;
811 }
812 break;
813
814 case NODE_STRUCT:
815 switch (node->parent->type) {
816 case NODE_ROOT:
817 case NODE_EVENT:
818 case NODE_STREAM:
819 case NODE_TRACE:
820 case NODE_CTF_EXPRESSION:
821 case NODE_TYPEDEF:
822 case NODE_TYPEALIAS_TARGET:
823 case NODE_TYPEALIAS_ALIAS:
824 case NODE_STRUCT_OR_VARIANT_DECLARATION:
825 break; /* OK */
826
827 case NODE_TYPEALIAS:
828 case NODE_TYPE_SPECIFIER:
829 case NODE_POINTER:
830 case NODE_TYPE_DECLARATOR:
831 case NODE_FLOATING_POINT:
832 case NODE_INTEGER:
833 case NODE_STRING:
834 case NODE_ENUMERATOR:
835 case NODE_ENUM:
836 case NODE_VARIANT:
837 case NODE_STRUCT:
838 default:
839 goto errinval;
840
841 case NODE_UNARY_EXPRESSION:
842 goto errperm;
843 }
844 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
845 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
846 if (ret)
847 return ret;
848 }
849 break;
850
851 case NODE_UNKNOWN:
852 default:
853 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
854 (int) node->type);
855 return -EINVAL;
856 }
857 return ret;
858
859 errinval:
860 fprintf(fd, "[error] %s: incoherent parent type %d for node type %d\n", __func__,
861 (int) node->parent->type, (int) node->type);
862 return -EINVAL; /* Incoherent structure */
863
864 errperm:
865 return -EPERM; /* Structure not allowed */
866 }
867
868 int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
869 {
870 int ret = 0;
871
872 /*
873 * First make sure we create the parent links for all children. Let's
874 * take the safe route and recreate them at each validation, just in
875 * case the structure has changed.
876 */
877 ret = ctf_visitor_parent_links(fd, depth, node);
878 if (ret)
879 return ret;
880 return _ctf_visitor_semantic_check(fd, depth, node);
881 }
This page took 0.048025 seconds and 5 git commands to generate.