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