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