fae2b711ec4069513a59fde8004184fa70728d17
[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 /* Fall-through */
236 case NODE_TYPEDEF:
237 case NODE_TYPEALIAS_TARGET:
238 case NODE_TYPEALIAS_ALIAS:
239 case NODE_STRUCT_OR_VARIANT_DECLARATION:
240 break; /* OK */
241
242 case NODE_ROOT:
243 case NODE_EVENT:
244 case NODE_STREAM:
245 case NODE_TRACE:
246 case NODE_CTF_EXPRESSION:
247 case NODE_UNARY_EXPRESSION:
248 case NODE_TYPEALIAS:
249 case NODE_TYPE_SPECIFIER:
250 case NODE_POINTER:
251 case NODE_FLOATING_POINT:
252 case NODE_INTEGER:
253 case NODE_STRING:
254 case NODE_ENUMERATOR:
255 case NODE_ENUM:
256 case NODE_VARIANT:
257 case NODE_STRUCT:
258 default:
259 goto errinval;
260 }
261
262 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
263 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
264 siblings) {
265 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
266 if (ret)
267 return ret;
268 }
269 }
270
271 switch (node->u.type_declarator.type) {
272 case TYPEDEC_ID:
273 break;
274 case TYPEDEC_NESTED:
275 if (node->u.type_declarator.u.nested.type_declarator) {
276 ret = _ctf_visitor_semantic_check(fd, depth + 1,
277 node->u.type_declarator.u.nested.type_declarator);
278 if (ret)
279 return ret;
280 }
281 if (node->u.type_declarator.u.nested.length) {
282 ret = _ctf_visitor_semantic_check(fd, depth + 1,
283 node->u.type_declarator.u.nested.length);
284 if (ret)
285 return ret;
286 }
287 if (node->u.type_declarator.bitfield_len) {
288 ret = _ctf_visitor_semantic_check(fd, depth + 1,
289 node->u.type_declarator.bitfield_len);
290 if (ret)
291 return ret;
292 }
293 break;
294 case TYPEDEC_UNKNOWN:
295 default:
296 fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
297 (int) node->u.type_declarator.type);
298 return -EINVAL;
299 }
300 depth--;
301 return 0;
302
303 errinval:
304 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
305 node_type(node->parent), node_type(node));
306 return -EINVAL; /* Incoherent structure */
307
308 errperm:
309 fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
310 node_type(node->parent), node_type(node));
311 return -EPERM; /* Structure not allowed */
312 }
313
314 static
315 int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
316 {
317 int ret = 0;
318 struct ctf_node *iter;
319
320 switch (node->type) {
321 case NODE_ROOT:
322 cds_list_for_each_entry(iter, &node->u.root._typedef,
323 siblings) {
324 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
325 if (ret)
326 return ret;
327 }
328 cds_list_for_each_entry(iter, &node->u.root.typealias,
329 siblings) {
330 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
331 if (ret)
332 return ret;
333 }
334 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
335 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
336 if (ret)
337 return ret;
338 }
339 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
340 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
341 if (ret)
342 return ret;
343 }
344 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
345 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
346 if (ret)
347 return ret;
348 }
349 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
350 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
351 if (ret)
352 return ret;
353 }
354 break;
355
356 case NODE_EVENT:
357 switch (node->parent->type) {
358 case NODE_ROOT:
359 break; /* OK */
360 default:
361 goto errinval;
362 }
363
364 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
365 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
366 if (ret)
367 return ret;
368 }
369 break;
370 case NODE_STREAM:
371 switch (node->parent->type) {
372 case NODE_ROOT:
373 break; /* OK */
374 default:
375 goto errinval;
376 }
377
378 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
379 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
380 if (ret)
381 return ret;
382 }
383 break;
384 case NODE_TRACE:
385 switch (node->parent->type) {
386 case NODE_ROOT:
387 break; /* OK */
388 default:
389 goto errinval;
390 }
391
392 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
393 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
394 if (ret)
395 return ret;
396 }
397 break;
398
399 case NODE_CTF_EXPRESSION:
400 switch (node->parent->type) {
401 case NODE_ROOT:
402 case NODE_EVENT:
403 case NODE_STREAM:
404 case NODE_TRACE:
405 case NODE_FLOATING_POINT:
406 case NODE_INTEGER:
407 case NODE_STRING:
408 break; /* OK */
409
410 case NODE_CTF_EXPRESSION:
411 case NODE_UNARY_EXPRESSION:
412 case NODE_TYPEDEF:
413 case NODE_TYPEALIAS_TARGET:
414 case NODE_TYPEALIAS_ALIAS:
415 case NODE_STRUCT_OR_VARIANT_DECLARATION:
416 case NODE_TYPEALIAS:
417 case NODE_TYPE_SPECIFIER:
418 case NODE_POINTER:
419 case NODE_TYPE_DECLARATOR:
420 case NODE_ENUMERATOR:
421 case NODE_ENUM:
422 case NODE_VARIANT:
423 case NODE_STRUCT:
424 default:
425 goto errinval;
426 }
427
428 depth++;
429 cds_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
430 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
431 if (ret)
432 return ret;
433 }
434 cds_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
435 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
436 if (ret)
437 return ret;
438 }
439 depth--;
440 break;
441 case NODE_UNARY_EXPRESSION:
442 return ctf_visitor_unary_expression(fd, depth, node);
443
444 case NODE_TYPEDEF:
445 switch (node->parent->type) {
446 case NODE_ROOT:
447 case NODE_EVENT:
448 case NODE_STREAM:
449 case NODE_TRACE:
450 case NODE_VARIANT:
451 case NODE_STRUCT:
452 break; /* OK */
453
454 case NODE_CTF_EXPRESSION:
455 case NODE_UNARY_EXPRESSION:
456 case NODE_TYPEDEF:
457 case NODE_TYPEALIAS_TARGET:
458 case NODE_TYPEALIAS_ALIAS:
459 case NODE_TYPEALIAS:
460 case NODE_STRUCT_OR_VARIANT_DECLARATION:
461 case NODE_TYPE_SPECIFIER:
462 case NODE_POINTER:
463 case NODE_TYPE_DECLARATOR:
464 case NODE_FLOATING_POINT:
465 case NODE_INTEGER:
466 case NODE_STRING:
467 case NODE_ENUMERATOR:
468 case NODE_ENUM:
469 default:
470 goto errinval;
471 }
472
473 depth++;
474 cds_list_for_each_entry(iter, &node->u._typedef.declaration_specifier, siblings) {
475 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
476 if (ret)
477 return ret;
478 }
479 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
480 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
481 if (ret)
482 return ret;
483 }
484 depth--;
485 break;
486 case NODE_TYPEALIAS_TARGET:
487 switch (node->parent->type) {
488 case NODE_TYPEALIAS:
489 break; /* OK */
490 default:
491 goto errinval;
492 }
493
494 depth++;
495 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
496 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
497 if (ret)
498 return ret;
499 }
500 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
501 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
502 if (ret)
503 return ret;
504 }
505 depth--;
506 break;
507 case NODE_TYPEALIAS_ALIAS:
508 switch (node->parent->type) {
509 case NODE_TYPEALIAS:
510 break; /* OK */
511 default:
512 goto errinval;
513 }
514
515 depth++;
516 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
517 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
518 if (ret)
519 return ret;
520 }
521 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
522 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
523 if (ret)
524 return ret;
525 }
526 depth--;
527 break;
528 case NODE_TYPEALIAS:
529 switch (node->parent->type) {
530 case NODE_ROOT:
531 case NODE_EVENT:
532 case NODE_STREAM:
533 case NODE_TRACE:
534 case NODE_VARIANT:
535 case NODE_STRUCT:
536 break; /* OK */
537
538 case NODE_CTF_EXPRESSION:
539 case NODE_UNARY_EXPRESSION:
540 case NODE_TYPEDEF:
541 case NODE_TYPEALIAS_TARGET:
542 case NODE_TYPEALIAS_ALIAS:
543 case NODE_TYPEALIAS:
544 case NODE_STRUCT_OR_VARIANT_DECLARATION:
545 case NODE_TYPE_SPECIFIER:
546 case NODE_POINTER:
547 case NODE_TYPE_DECLARATOR:
548 case NODE_FLOATING_POINT:
549 case NODE_INTEGER:
550 case NODE_STRING:
551 case NODE_ENUMERATOR:
552 case NODE_ENUM:
553 default:
554 goto errinval;
555 }
556
557 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.target);
558 if (ret)
559 return ret;
560 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.alias);
561 if (ret)
562 return ret;
563 break;
564
565 case NODE_TYPE_SPECIFIER:
566 ret = ctf_visitor_type_specifier(fd, depth, node);
567 if (ret)
568 return ret;
569 break;
570 case NODE_POINTER:
571 switch (node->parent->type) {
572 case NODE_TYPE_DECLARATOR:
573 break; /* OK */
574 default:
575 goto errinval;
576 }
577 break;
578 case NODE_TYPE_DECLARATOR:
579 ret = ctf_visitor_type_declarator(fd, depth, node);
580 if (ret)
581 return ret;
582 break;
583
584 case NODE_FLOATING_POINT:
585 switch (node->parent->type) {
586 case NODE_CTF_EXPRESSION:
587 case NODE_TYPEDEF:
588 case NODE_TYPEALIAS_TARGET:
589 case NODE_TYPEALIAS_ALIAS:
590 case NODE_STRUCT_OR_VARIANT_DECLARATION:
591 break; /* OK */
592
593 case NODE_ROOT:
594 case NODE_EVENT:
595 case NODE_STREAM:
596 case NODE_TRACE:
597 case NODE_TYPEALIAS:
598 case NODE_TYPE_SPECIFIER:
599 case NODE_POINTER:
600 case NODE_TYPE_DECLARATOR:
601 case NODE_FLOATING_POINT:
602 case NODE_INTEGER:
603 case NODE_STRING:
604 case NODE_ENUMERATOR:
605 case NODE_ENUM:
606 case NODE_VARIANT:
607 case NODE_STRUCT:
608 default:
609 goto errinval;
610
611 case NODE_UNARY_EXPRESSION:
612 goto errperm;
613 }
614 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
615 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
616 if (ret)
617 return ret;
618 }
619 break;
620 case NODE_INTEGER:
621 switch (node->parent->type) {
622 case NODE_CTF_EXPRESSION:
623 case NODE_UNARY_EXPRESSION:
624 case NODE_TYPEDEF:
625 case NODE_TYPEALIAS_TARGET:
626 case NODE_TYPEALIAS_ALIAS:
627 case NODE_TYPE_DECLARATOR:
628 case NODE_ENUM:
629 case NODE_STRUCT_OR_VARIANT_DECLARATION:
630 break; /* OK */
631
632 case NODE_ROOT:
633 case NODE_EVENT:
634 case NODE_STREAM:
635 case NODE_TRACE:
636 case NODE_TYPEALIAS:
637 case NODE_TYPE_SPECIFIER:
638 case NODE_POINTER:
639 case NODE_FLOATING_POINT:
640 case NODE_INTEGER:
641 case NODE_STRING:
642 case NODE_ENUMERATOR:
643 case NODE_VARIANT:
644 case NODE_STRUCT:
645 default:
646 goto errinval;
647
648 }
649
650 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
651 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
652 if (ret)
653 return ret;
654 }
655 break;
656 case NODE_STRING:
657 switch (node->parent->type) {
658 case NODE_CTF_EXPRESSION:
659 case NODE_TYPEDEF:
660 case NODE_TYPEALIAS_TARGET:
661 case NODE_TYPEALIAS_ALIAS:
662 case NODE_STRUCT_OR_VARIANT_DECLARATION:
663 break; /* OK */
664
665 case NODE_ROOT:
666 case NODE_EVENT:
667 case NODE_STREAM:
668 case NODE_TRACE:
669 case NODE_TYPEALIAS:
670 case NODE_TYPE_SPECIFIER:
671 case NODE_POINTER:
672 case NODE_TYPE_DECLARATOR:
673 case NODE_FLOATING_POINT:
674 case NODE_INTEGER:
675 case NODE_STRING:
676 case NODE_ENUMERATOR:
677 case NODE_ENUM:
678 case NODE_VARIANT:
679 case NODE_STRUCT:
680 default:
681 goto errinval;
682
683 case NODE_UNARY_EXPRESSION:
684 goto errperm;
685 }
686
687 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
688 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
689 if (ret)
690 return ret;
691 }
692 break;
693 case NODE_ENUMERATOR:
694 switch (node->parent->type) {
695 case NODE_ENUM:
696 break;
697 default:
698 goto errinval;
699 }
700 /*
701 * Enumerators are only allows to contain:
702 * numeric unary expression
703 * or num. unary exp. ... num. unary exp
704 */
705 {
706 int count = 0;
707
708 cds_list_for_each_entry(iter, &node->u.enumerator.values,
709 siblings) {
710 switch (count++) {
711 case 0: if (iter->type != NODE_UNARY_EXPRESSION
712 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
713 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
714 || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) {
715 fprintf(fd, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
716 goto errperm;
717 }
718 break;
719 case 1: if (iter->type != NODE_UNARY_EXPRESSION
720 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
721 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
722 || iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
723 fprintf(fd, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
724 goto errperm;
725 }
726 break;
727 default:
728 goto errperm;
729 }
730 }
731 }
732
733 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
734 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
735 if (ret)
736 return ret;
737 }
738 break;
739 case NODE_ENUM:
740 switch (node->parent->type) {
741 case NODE_ROOT:
742 case NODE_EVENT:
743 case NODE_STREAM:
744 case NODE_TRACE:
745 case NODE_CTF_EXPRESSION:
746 case NODE_TYPEDEF:
747 case NODE_TYPEALIAS_TARGET:
748 case NODE_TYPEALIAS_ALIAS:
749 case NODE_TYPE_DECLARATOR:
750 case NODE_STRUCT_OR_VARIANT_DECLARATION:
751 break; /* OK */
752
753 case NODE_TYPEALIAS:
754 case NODE_TYPE_SPECIFIER:
755 case NODE_POINTER:
756 case NODE_FLOATING_POINT:
757 case NODE_INTEGER:
758 case NODE_STRING:
759 case NODE_ENUMERATOR:
760 case NODE_ENUM:
761 case NODE_VARIANT:
762 case NODE_STRUCT:
763 default:
764 goto errinval;
765
766 case NODE_UNARY_EXPRESSION:
767 goto errperm;
768 }
769
770 depth++;
771 if (node->u._enum.container_type) {
772 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type);
773 if (ret)
774 return ret;
775 }
776
777 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
778 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
779 if (ret)
780 return ret;
781 }
782 depth--;
783 break;
784 case NODE_STRUCT_OR_VARIANT_DECLARATION:
785 switch (node->parent->type) {
786 case NODE_STRUCT:
787 case NODE_VARIANT:
788 break;
789 default:
790 goto errinval;
791 }
792 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
793 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
794 if (ret)
795 return ret;
796 }
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_ROOT:
806 case NODE_EVENT:
807 case NODE_STREAM:
808 case NODE_TRACE:
809 case NODE_CTF_EXPRESSION:
810 case NODE_TYPEDEF:
811 case NODE_TYPEALIAS_TARGET:
812 case NODE_TYPEALIAS_ALIAS:
813 case NODE_STRUCT_OR_VARIANT_DECLARATION:
814 break; /* OK */
815
816 case NODE_TYPEALIAS:
817 case NODE_TYPE_SPECIFIER:
818 case NODE_POINTER:
819 case NODE_TYPE_DECLARATOR:
820 case NODE_FLOATING_POINT:
821 case NODE_INTEGER:
822 case NODE_STRING:
823 case NODE_ENUMERATOR:
824 case NODE_ENUM:
825 case NODE_VARIANT:
826 case NODE_STRUCT:
827 default:
828 goto errinval;
829
830 case NODE_UNARY_EXPRESSION:
831 goto errperm;
832 }
833 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
834 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
835 if (ret)
836 return ret;
837 }
838 break;
839
840 case NODE_STRUCT:
841 switch (node->parent->type) {
842 case NODE_ROOT:
843 case NODE_EVENT:
844 case NODE_STREAM:
845 case NODE_TRACE:
846 case NODE_CTF_EXPRESSION:
847 case NODE_TYPEDEF:
848 case NODE_TYPEALIAS_TARGET:
849 case NODE_TYPEALIAS_ALIAS:
850 case NODE_STRUCT_OR_VARIANT_DECLARATION:
851 break; /* OK */
852
853 case NODE_TYPEALIAS:
854 case NODE_TYPE_SPECIFIER:
855 case NODE_POINTER:
856 case NODE_TYPE_DECLARATOR:
857 case NODE_FLOATING_POINT:
858 case NODE_INTEGER:
859 case NODE_STRING:
860 case NODE_ENUMERATOR:
861 case NODE_ENUM:
862 case NODE_VARIANT:
863 case NODE_STRUCT:
864 default:
865 goto errinval;
866
867 case NODE_UNARY_EXPRESSION:
868 goto errperm;
869 }
870 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
871 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
872 if (ret)
873 return ret;
874 }
875 break;
876
877 case NODE_UNKNOWN:
878 default:
879 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
880 (int) node->type);
881 return -EINVAL;
882 }
883 return ret;
884
885 errinval:
886 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
887 node_type(node->parent), node_type(node));
888 return -EINVAL; /* Incoherent structure */
889
890 errperm:
891 fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
892 node_type(node->parent), node_type(node));
893 return -EPERM; /* Structure not allowed */
894 }
895
896 int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
897 {
898 int ret = 0;
899
900 /*
901 * First make sure we create the parent links for all children. Let's
902 * take the safe route and recreate them at each validation, just in
903 * case the structure has changed.
904 */
905 fprintf(fd, "CTF visitor: parent links creation... ");
906 ret = ctf_visitor_parent_links(fd, depth, node);
907 if (ret)
908 return ret;
909 fprintf(fd, "done.\n");
910 fprintf(fd, "CTF visitor: semantic check... ");
911 ret = _ctf_visitor_semantic_check(fd, depth, node);
912 if (ret)
913 return ret;
914 fprintf(fd, "done.\n");
915 return ret;
916 }
This page took 0.046606 seconds and 3 git commands to generate.