Update typealias behavior
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-semantic-validator.c
CommitLineData
67905e42
MD
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
34f7b02c 35#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
67905e42
MD
36
37static
38int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node);
39
40static
41int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
42{
43 struct ctf_node *iter;
34f7b02c 44 int is_ctf_exp = 0, is_ctf_exp_left = 0;
67905e42
MD
45
46 switch (node->parent->type) {
47 case NODE_CTF_EXPRESSION:
34f7b02c 48 is_ctf_exp = 1;
67905e42
MD
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 */
34f7b02c
MD
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
67905e42 60 goto errperm;
34f7b02c 61 }
67905e42
MD
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:
34f7b02c 68 case NODE_ENUM:
67905e42 69 /*
34f7b02c
MD
70 * We are the length of a type declarator or the size of an enum
71 * container. We can only be a numeric constant.
67905e42
MD
72 */
73 switch (node->u.unary_expression.type) {
74 case UNARY_SIGNED_CONSTANT:
75 case UNARY_UNSIGNED_CONSTANT:
76 break;
77 default:
34f7b02c 78 fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
67905e42
MD
79 goto errperm;
80 }
81 break; /* OK */
82 case NODE_ENUMERATOR:
135d0e88 83 /* The enumerator's parent has validated its validity already. */
67905e42
MD
84 break; /* OK */
85
86 case NODE_UNARY_EXPRESSION:
87 /*
88 * We disallow nested unary expressions and "sbrac" unary
89 * expressions.
90 */
34f7b02c 91 fprintf(fd, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
67905e42
MD
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:
67905e42
MD
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:
135d0e88 116 /* We don't allow empty link except on the first node of the list */
34f7b02c 117 if (is_ctf_exp && _cds_list_first_entry(is_ctf_exp_left ?
135d0e88
MD
118 &node->parent->u.ctf_expression.left :
119 &node->parent->u.ctf_expression.right,
120 struct ctf_node,
34f7b02c
MD
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");
135d0e88 123 goto errperm;
34f7b02c 124 }
135d0e88 125 break; /* OK */
67905e42
MD
126 case UNARY_DOTLINK:
127 case UNARY_ARROWLINK:
128 /* We only allow -> and . links between children of ctf_expression. */
34f7b02c
MD
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");
135d0e88 131 goto errperm;
34f7b02c 132 }
135d0e88
MD
133 /*
134 * Only strings can be separated linked by . or ->.
135 * This includes "", '' and non-quoted identifiers.
136 */
34f7b02c
MD
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");
135d0e88 148 goto errperm;
34f7b02c 149 }
67905e42
MD
150 break;
151 case UNARY_DOTDOTDOT:
152 /* We only allow ... link between children of enumerator. */
34f7b02c
MD
153 if (node->parent->type != NODE_ENUMERATOR) {
154 fprintf(fd, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
135d0e88 155 goto errperm;
34f7b02c 156 }
67905e42
MD
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,
34f7b02c
MD
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 }
67905e42
MD
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
172errinval:
34f7b02c
MD
173 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
174 node_type(node->parent), node_type(node));
67905e42
MD
175 return -EINVAL; /* Incoherent structure */
176
177errperm:
34f7b02c
MD
178 fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
179 node_type(node->parent), node_type(node));
67905e42
MD
180 return -EPERM; /* Structure not allowed */
181}
182
183static
184int 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:
34f7b02c 193 case NODE_STRUCT_OR_VARIANT_DECLARATION:
67905e42
MD
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:
67905e42
MD
208 case NODE_VARIANT:
209 case NODE_STRUCT:
210 default:
211 goto errinval;
212 }
213 return 0;
214errinval:
34f7b02c
MD
215 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
216 node_type(node->parent), node_type(node));
67905e42
MD
217 return -EINVAL; /* Incoherent structure */
218}
219
220static
221int 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;
1ee8e81d 235 break; /* OK */
67905e42 236 case NODE_TYPEALIAS_TARGET:
1ee8e81d 237 break; /* OK */
67905e42 238 case NODE_TYPEALIAS_ALIAS:
1ee8e81d
MD
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:
67905e42
MD
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 if (node->u.type_declarator.u.nested.type_declarator) {
296 ret = _ctf_visitor_semantic_check(fd, depth + 1,
297 node->u.type_declarator.u.nested.type_declarator);
298 if (ret)
299 return ret;
300 }
301 if (node->u.type_declarator.u.nested.length) {
302 ret = _ctf_visitor_semantic_check(fd, depth + 1,
303 node->u.type_declarator.u.nested.length);
304 if (ret)
305 return ret;
306 }
307 if (node->u.type_declarator.bitfield_len) {
308 ret = _ctf_visitor_semantic_check(fd, depth + 1,
309 node->u.type_declarator.bitfield_len);
310 if (ret)
311 return ret;
312 }
313 break;
314 case TYPEDEC_UNKNOWN:
315 default:
316 fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
317 (int) node->u.type_declarator.type);
318 return -EINVAL;
319 }
320 depth--;
321 return 0;
322
323errinval:
34f7b02c
MD
324 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
325 node_type(node->parent), node_type(node));
67905e42
MD
326 return -EINVAL; /* Incoherent structure */
327
328errperm:
34f7b02c
MD
329 fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
330 node_type(node->parent), node_type(node));
67905e42
MD
331 return -EPERM; /* Structure not allowed */
332}
333
334static
335int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
336{
337 int ret = 0;
338 struct ctf_node *iter;
339
340 switch (node->type) {
341 case NODE_ROOT:
342 cds_list_for_each_entry(iter, &node->u.root._typedef,
343 siblings) {
344 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
345 if (ret)
346 return ret;
347 }
348 cds_list_for_each_entry(iter, &node->u.root.typealias,
349 siblings) {
350 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
351 if (ret)
352 return ret;
353 }
354 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
355 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
356 if (ret)
357 return ret;
358 }
359 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
360 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
361 if (ret)
362 return ret;
363 }
364 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
365 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
366 if (ret)
367 return ret;
368 }
369 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
370 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
371 if (ret)
372 return ret;
373 }
374 break;
375
376 case NODE_EVENT:
377 switch (node->parent->type) {
378 case NODE_ROOT:
379 break; /* OK */
380 default:
381 goto errinval;
382 }
383
384 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
385 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
386 if (ret)
387 return ret;
388 }
389 break;
390 case NODE_STREAM:
391 switch (node->parent->type) {
392 case NODE_ROOT:
393 break; /* OK */
394 default:
395 goto errinval;
396 }
397
398 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
399 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
400 if (ret)
401 return ret;
402 }
403 break;
404 case NODE_TRACE:
405 switch (node->parent->type) {
406 case NODE_ROOT:
407 break; /* OK */
408 default:
409 goto errinval;
410 }
411
412 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
413 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
414 if (ret)
415 return ret;
416 }
417 break;
418
419 case NODE_CTF_EXPRESSION:
420 switch (node->parent->type) {
421 case NODE_ROOT:
422 case NODE_EVENT:
423 case NODE_STREAM:
424 case NODE_TRACE:
425 case NODE_FLOATING_POINT:
426 case NODE_INTEGER:
427 case NODE_STRING:
428 break; /* OK */
429
430 case NODE_CTF_EXPRESSION:
431 case NODE_UNARY_EXPRESSION:
432 case NODE_TYPEDEF:
433 case NODE_TYPEALIAS_TARGET:
434 case NODE_TYPEALIAS_ALIAS:
435 case NODE_STRUCT_OR_VARIANT_DECLARATION:
436 case NODE_TYPEALIAS:
437 case NODE_TYPE_SPECIFIER:
438 case NODE_POINTER:
439 case NODE_TYPE_DECLARATOR:
440 case NODE_ENUMERATOR:
441 case NODE_ENUM:
442 case NODE_VARIANT:
443 case NODE_STRUCT:
444 default:
445 goto errinval;
446 }
447
448 depth++;
449 cds_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
450 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
451 if (ret)
452 return ret;
453 }
454 cds_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
455 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
456 if (ret)
457 return ret;
458 }
459 depth--;
460 break;
461 case NODE_UNARY_EXPRESSION:
462 return ctf_visitor_unary_expression(fd, depth, node);
463
464 case NODE_TYPEDEF:
465 switch (node->parent->type) {
466 case NODE_ROOT:
467 case NODE_EVENT:
468 case NODE_STREAM:
469 case NODE_TRACE:
470 case NODE_VARIANT:
471 case NODE_STRUCT:
472 break; /* OK */
473
474 case NODE_CTF_EXPRESSION:
475 case NODE_UNARY_EXPRESSION:
476 case NODE_TYPEDEF:
477 case NODE_TYPEALIAS_TARGET:
478 case NODE_TYPEALIAS_ALIAS:
479 case NODE_TYPEALIAS:
480 case NODE_STRUCT_OR_VARIANT_DECLARATION:
481 case NODE_TYPE_SPECIFIER:
482 case NODE_POINTER:
483 case NODE_TYPE_DECLARATOR:
484 case NODE_FLOATING_POINT:
485 case NODE_INTEGER:
486 case NODE_STRING:
487 case NODE_ENUMERATOR:
488 case NODE_ENUM:
489 default:
490 goto errinval;
491 }
492
493 depth++;
494 cds_list_for_each_entry(iter, &node->u._typedef.declaration_specifier, siblings) {
495 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
496 if (ret)
497 return ret;
498 }
499 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
500 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
501 if (ret)
502 return ret;
503 }
504 depth--;
505 break;
506 case NODE_TYPEALIAS_TARGET:
1ee8e81d
MD
507 {
508 int nr_declarators;
509
67905e42
MD
510 switch (node->parent->type) {
511 case NODE_TYPEALIAS:
512 break; /* OK */
513 default:
514 goto errinval;
515 }
516
517 depth++;
518 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
519 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
520 if (ret)
521 return ret;
522 }
1ee8e81d 523 nr_declarators = 0;
67905e42
MD
524 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
525 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
526 if (ret)
527 return ret;
1ee8e81d
MD
528 nr_declarators++;
529 }
530 if (nr_declarators > 1) {
531 fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
532
533 return -EINVAL;
67905e42
MD
534 }
535 depth--;
536 break;
1ee8e81d 537 }
67905e42 538 case NODE_TYPEALIAS_ALIAS:
1ee8e81d
MD
539 {
540 int nr_declarators;
541
67905e42
MD
542 switch (node->parent->type) {
543 case NODE_TYPEALIAS:
544 break; /* OK */
545 default:
546 goto errinval;
547 }
548
549 depth++;
550 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
551 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
552 if (ret)
553 return ret;
554 }
1ee8e81d 555 nr_declarators = 0;
67905e42
MD
556 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
557 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
558 if (ret)
559 return ret;
1ee8e81d
MD
560 nr_declarators++;
561 }
562 if (nr_declarators > 1) {
563 fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
564
565 return -EINVAL;
67905e42
MD
566 }
567 depth--;
568 break;
1ee8e81d 569 }
67905e42
MD
570 case NODE_TYPEALIAS:
571 switch (node->parent->type) {
572 case NODE_ROOT:
573 case NODE_EVENT:
574 case NODE_STREAM:
575 case NODE_TRACE:
576 case NODE_VARIANT:
577 case NODE_STRUCT:
578 break; /* OK */
579
580 case NODE_CTF_EXPRESSION:
581 case NODE_UNARY_EXPRESSION:
582 case NODE_TYPEDEF:
583 case NODE_TYPEALIAS_TARGET:
584 case NODE_TYPEALIAS_ALIAS:
585 case NODE_TYPEALIAS:
586 case NODE_STRUCT_OR_VARIANT_DECLARATION:
587 case NODE_TYPE_SPECIFIER:
588 case NODE_POINTER:
589 case NODE_TYPE_DECLARATOR:
590 case NODE_FLOATING_POINT:
591 case NODE_INTEGER:
592 case NODE_STRING:
593 case NODE_ENUMERATOR:
594 case NODE_ENUM:
595 default:
596 goto errinval;
597 }
598
599 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.target);
600 if (ret)
601 return ret;
602 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.alias);
603 if (ret)
604 return ret;
605 break;
606
607 case NODE_TYPE_SPECIFIER:
608 ret = ctf_visitor_type_specifier(fd, depth, node);
609 if (ret)
610 return ret;
611 break;
612 case NODE_POINTER:
613 switch (node->parent->type) {
614 case NODE_TYPE_DECLARATOR:
615 break; /* OK */
616 default:
617 goto errinval;
618 }
619 break;
620 case NODE_TYPE_DECLARATOR:
621 ret = ctf_visitor_type_declarator(fd, depth, node);
622 if (ret)
623 return ret;
624 break;
625
626 case NODE_FLOATING_POINT:
627 switch (node->parent->type) {
628 case NODE_CTF_EXPRESSION:
629 case NODE_TYPEDEF:
630 case NODE_TYPEALIAS_TARGET:
631 case NODE_TYPEALIAS_ALIAS:
632 case NODE_STRUCT_OR_VARIANT_DECLARATION:
633 break; /* OK */
634
635 case NODE_ROOT:
636 case NODE_EVENT:
637 case NODE_STREAM:
638 case NODE_TRACE:
639 case NODE_TYPEALIAS:
640 case NODE_TYPE_SPECIFIER:
641 case NODE_POINTER:
642 case NODE_TYPE_DECLARATOR:
643 case NODE_FLOATING_POINT:
644 case NODE_INTEGER:
645 case NODE_STRING:
646 case NODE_ENUMERATOR:
647 case NODE_ENUM:
648 case NODE_VARIANT:
649 case NODE_STRUCT:
650 default:
651 goto errinval;
652
653 case NODE_UNARY_EXPRESSION:
654 goto errperm;
655 }
656 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
657 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
658 if (ret)
659 return ret;
660 }
661 break;
662 case NODE_INTEGER:
663 switch (node->parent->type) {
664 case NODE_CTF_EXPRESSION:
665 case NODE_UNARY_EXPRESSION:
666 case NODE_TYPEDEF:
667 case NODE_TYPEALIAS_TARGET:
668 case NODE_TYPEALIAS_ALIAS:
669 case NODE_TYPE_DECLARATOR:
670 case NODE_ENUM:
671 case NODE_STRUCT_OR_VARIANT_DECLARATION:
672 break; /* OK */
673
674 case NODE_ROOT:
675 case NODE_EVENT:
676 case NODE_STREAM:
677 case NODE_TRACE:
678 case NODE_TYPEALIAS:
679 case NODE_TYPE_SPECIFIER:
680 case NODE_POINTER:
681 case NODE_FLOATING_POINT:
682 case NODE_INTEGER:
683 case NODE_STRING:
684 case NODE_ENUMERATOR:
685 case NODE_VARIANT:
686 case NODE_STRUCT:
687 default:
688 goto errinval;
689
690 }
691
692 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
693 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
694 if (ret)
695 return ret;
696 }
697 break;
698 case NODE_STRING:
699 switch (node->parent->type) {
700 case NODE_CTF_EXPRESSION:
701 case NODE_TYPEDEF:
702 case NODE_TYPEALIAS_TARGET:
703 case NODE_TYPEALIAS_ALIAS:
704 case NODE_STRUCT_OR_VARIANT_DECLARATION:
705 break; /* OK */
706
707 case NODE_ROOT:
708 case NODE_EVENT:
709 case NODE_STREAM:
710 case NODE_TRACE:
711 case NODE_TYPEALIAS:
712 case NODE_TYPE_SPECIFIER:
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_VARIANT:
721 case NODE_STRUCT:
722 default:
723 goto errinval;
724
725 case NODE_UNARY_EXPRESSION:
726 goto errperm;
727 }
728
729 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
730 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
731 if (ret)
732 return ret;
733 }
734 break;
735 case NODE_ENUMERATOR:
736 switch (node->parent->type) {
737 case NODE_ENUM:
738 break;
739 default:
740 goto errinval;
741 }
742 /*
743 * Enumerators are only allows to contain:
744 * numeric unary expression
745 * or num. unary exp. ... num. unary exp
746 */
747 {
748 int count = 0;
749
34f7b02c 750 cds_list_for_each_entry(iter, &node->u.enumerator.values,
67905e42
MD
751 siblings) {
752 switch (count++) {
753 case 0: if (iter->type != NODE_UNARY_EXPRESSION
754 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
755 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
34f7b02c
MD
756 || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) {
757 fprintf(fd, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
67905e42 758 goto errperm;
34f7b02c 759 }
67905e42
MD
760 break;
761 case 1: if (iter->type != NODE_UNARY_EXPRESSION
762 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
763 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
34f7b02c
MD
764 || iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
765 fprintf(fd, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
67905e42 766 goto errperm;
34f7b02c 767 }
67905e42
MD
768 break;
769 default:
770 goto errperm;
771 }
772 }
773 }
774
775 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
776 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
777 if (ret)
778 return ret;
779 }
780 break;
781 case NODE_ENUM:
782 switch (node->parent->type) {
783 case NODE_ROOT:
784 case NODE_EVENT:
785 case NODE_STREAM:
786 case NODE_TRACE:
787 case NODE_CTF_EXPRESSION:
788 case NODE_TYPEDEF:
789 case NODE_TYPEALIAS_TARGET:
790 case NODE_TYPEALIAS_ALIAS:
791 case NODE_TYPE_DECLARATOR:
792 case NODE_STRUCT_OR_VARIANT_DECLARATION:
793 break; /* OK */
794
795 case NODE_TYPEALIAS:
796 case NODE_TYPE_SPECIFIER:
797 case NODE_POINTER:
798 case NODE_FLOATING_POINT:
799 case NODE_INTEGER:
800 case NODE_STRING:
801 case NODE_ENUMERATOR:
802 case NODE_ENUM:
803 case NODE_VARIANT:
804 case NODE_STRUCT:
805 default:
806 goto errinval;
807
808 case NODE_UNARY_EXPRESSION:
809 goto errperm;
810 }
811
812 depth++;
813 if (node->u._enum.container_type) {
814 ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type);
815 if (ret)
816 return ret;
817 }
818
819 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
820 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
821 if (ret)
822 return ret;
823 }
824 depth--;
825 break;
826 case NODE_STRUCT_OR_VARIANT_DECLARATION:
827 switch (node->parent->type) {
828 case NODE_STRUCT:
829 case NODE_VARIANT:
830 break;
831 default:
832 goto errinval;
833 }
834 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
835 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
836 if (ret)
837 return ret;
838 }
839 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
840 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
841 if (ret)
842 return ret;
843 }
844 break;
845 case NODE_VARIANT:
846 switch (node->parent->type) {
847 case NODE_ROOT:
848 case NODE_EVENT:
849 case NODE_STREAM:
850 case NODE_TRACE:
851 case NODE_CTF_EXPRESSION:
852 case NODE_TYPEDEF:
853 case NODE_TYPEALIAS_TARGET:
854 case NODE_TYPEALIAS_ALIAS:
855 case NODE_STRUCT_OR_VARIANT_DECLARATION:
856 break; /* OK */
857
858 case NODE_TYPEALIAS:
859 case NODE_TYPE_SPECIFIER:
860 case NODE_POINTER:
861 case NODE_TYPE_DECLARATOR:
862 case NODE_FLOATING_POINT:
863 case NODE_INTEGER:
864 case NODE_STRING:
865 case NODE_ENUMERATOR:
866 case NODE_ENUM:
867 case NODE_VARIANT:
868 case NODE_STRUCT:
869 default:
870 goto errinval;
871
872 case NODE_UNARY_EXPRESSION:
873 goto errperm;
874 }
875 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
876 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
877 if (ret)
878 return ret;
879 }
880 break;
881
882 case NODE_STRUCT:
883 switch (node->parent->type) {
884 case NODE_ROOT:
885 case NODE_EVENT:
886 case NODE_STREAM:
887 case NODE_TRACE:
888 case NODE_CTF_EXPRESSION:
889 case NODE_TYPEDEF:
890 case NODE_TYPEALIAS_TARGET:
891 case NODE_TYPEALIAS_ALIAS:
892 case NODE_STRUCT_OR_VARIANT_DECLARATION:
893 break; /* OK */
894
895 case NODE_TYPEALIAS:
896 case NODE_TYPE_SPECIFIER:
897 case NODE_POINTER:
898 case NODE_TYPE_DECLARATOR:
899 case NODE_FLOATING_POINT:
900 case NODE_INTEGER:
901 case NODE_STRING:
902 case NODE_ENUMERATOR:
903 case NODE_ENUM:
904 case NODE_VARIANT:
905 case NODE_STRUCT:
906 default:
907 goto errinval;
908
909 case NODE_UNARY_EXPRESSION:
910 goto errperm;
911 }
912 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
913 ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
914 if (ret)
915 return ret;
916 }
917 break;
918
919 case NODE_UNKNOWN:
920 default:
921 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
922 (int) node->type);
923 return -EINVAL;
924 }
925 return ret;
926
927errinval:
34f7b02c
MD
928 fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
929 node_type(node->parent), node_type(node));
67905e42
MD
930 return -EINVAL; /* Incoherent structure */
931
932errperm:
34f7b02c
MD
933 fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
934 node_type(node->parent), node_type(node));
67905e42
MD
935 return -EPERM; /* Structure not allowed */
936}
937
938int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
939{
940 int ret = 0;
941
942 /*
943 * First make sure we create the parent links for all children. Let's
944 * take the safe route and recreate them at each validation, just in
945 * case the structure has changed.
946 */
34f7b02c 947 fprintf(fd, "CTF visitor: parent links creation... ");
67905e42
MD
948 ret = ctf_visitor_parent_links(fd, depth, node);
949 if (ret)
950 return ret;
34f7b02c
MD
951 fprintf(fd, "done.\n");
952 fprintf(fd, "CTF visitor: semantic check... ");
953 ret = _ctf_visitor_semantic_check(fd, depth, node);
954 if (ret)
955 return ret;
956 fprintf(fd, "done.\n");
957 return ret;
67905e42 958}
This page took 0.06157 seconds and 4 git commands to generate.