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