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