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