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