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