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