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