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