2 * ctf-visitor-semantic-validator.c
4 * Common Trace Format Metadata Semantic Validator.
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
27 #include <babeltrace/babeltrace.h>
28 #include <babeltrace/list.h>
29 #include "ctf-scanner.h"
30 #include "ctf-parser.h"
33 #define _cds_list_first_entry(ptr, type, member) \
34 cds_list_entry((ptr)->next, type, member)
36 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
39 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
);
42 int ctf_visitor_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
44 struct ctf_node
*iter
;
45 int is_ctf_exp
= 0, is_ctf_exp_left
= 0;
47 switch (node
->parent
->type
) {
48 case NODE_CTF_EXPRESSION
:
50 cds_list_for_each_entry(iter
, &node
->parent
->u
.ctf_expression
.left
,
55 * We are a left child of a ctf expression.
56 * We are only allowed to be a string.
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");
66 /* Right child of a ctf expression can be any type of unary exp. */
68 case NODE_TYPE_DECLARATOR
:
70 * We are the length of a type declarator.
72 switch (node
->u
.unary_expression
.type
) {
73 case UNARY_UNSIGNED_CONSTANT
:
76 fprintf(fd
, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants)\n");
83 * We are the size of a struct align attribute.
85 switch (node
->u
.unary_expression
.type
) {
86 case UNARY_UNSIGNED_CONSTANT
:
89 fprintf(fd
, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
95 /* The enumerator's parent has validated its validity already. */
98 case NODE_UNARY_EXPRESSION
:
100 * We disallow nested unary expressions and "sbrac" unary
103 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
111 case NODE_TYPEALIAS_TARGET
:
112 case NODE_TYPEALIAS_ALIAS
:
114 case NODE_TYPE_SPECIFIER
:
116 case NODE_FLOATING_POINT
:
120 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
126 switch (node
->u
.unary_expression
.link
) {
127 case UNARY_LINK_UNKNOWN
:
128 /* We don't allow empty link except on the first node of the list */
129 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
130 &node
->parent
->u
.ctf_expression
.left
:
131 &node
->parent
->u
.ctf_expression
.right
,
134 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
139 case UNARY_ARROWLINK
:
140 /* We only allow -> and . links between children of ctf_expression. */
141 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
142 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
146 * Only strings can be separated linked by . or ->.
147 * This includes "", '' and non-quoted identifiers.
149 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
150 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
153 /* We don't allow link on the first node of the list */
154 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
155 &node
->parent
->u
.ctf_expression
.left
:
156 &node
->parent
->u
.ctf_expression
.right
,
159 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
163 case UNARY_DOTDOTDOT
:
164 /* We only allow ... link between children of enumerator. */
165 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
166 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
169 /* We don't allow link on the first node of the list */
170 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
173 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
178 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
179 (int) node
->u
.unary_expression
.link
);
185 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
186 node_type(node
->parent
), node_type(node
));
187 return -EINVAL
; /* Incoherent structure */
190 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
191 node_type(node
->parent
), node_type(node
));
192 return -EPERM
; /* Structure not allowed */
196 int ctf_visitor_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
198 switch (node
->parent
->type
) {
199 case NODE_CTF_EXPRESSION
:
200 case NODE_TYPE_DECLARATOR
:
202 case NODE_TYPEALIAS_TARGET
:
203 case NODE_TYPEALIAS_ALIAS
:
205 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
212 case NODE_UNARY_EXPRESSION
:
214 case NODE_TYPE_SPECIFIER
:
215 case NODE_TYPE_SPECIFIER_LIST
:
217 case NODE_FLOATING_POINT
:
220 case NODE_ENUMERATOR
:
228 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
229 node_type(node
->parent
), node_type(node
));
230 return -EINVAL
; /* Incoherent structure */
234 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
236 switch (node
->parent
->type
) {
237 case NODE_TYPE_SPECIFIER_LIST
:
240 case NODE_CTF_EXPRESSION
:
241 case NODE_TYPE_DECLARATOR
:
243 case NODE_TYPEALIAS_TARGET
:
244 case NODE_TYPEALIAS_ALIAS
:
246 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
251 case NODE_UNARY_EXPRESSION
:
253 case NODE_TYPE_SPECIFIER
:
255 case NODE_FLOATING_POINT
:
258 case NODE_ENUMERATOR
:
266 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
267 node_type(node
->parent
), node_type(node
));
268 return -EINVAL
; /* Incoherent structure */
272 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
275 struct ctf_node
*iter
;
279 switch (node
->parent
->type
) {
280 case NODE_TYPE_DECLARATOR
:
282 * A nested type declarator is not allowed to contain pointers.
284 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
287 case NODE_TYPEALIAS_TARGET
:
289 case NODE_TYPEALIAS_ALIAS
:
291 * Only accept alias name containing:
293 * - identifier * (any number of pointers)
294 * NOT accepting alias names containing [] (would otherwise
295 * cause semantic clash for later declarations of
296 * arrays/sequences of elements, where elements could be
297 * arrays/sequences themselves (if allowed in typealias).
298 * NOT accepting alias with identifier. The declarator should
299 * be either empty or contain pointer(s).
301 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
303 switch (node
->u
.type_declarator
.type
) {
304 case TYPESPEC_FLOATING_POINT
:
305 case TYPESPEC_INTEGER
:
306 case TYPESPEC_STRING
:
307 case TYPESPEC_STRUCT
:
308 case TYPESPEC_VARIANT
:
310 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
316 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
317 node
->u
.type_declarator
.u
.id
!= NULL
)
321 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
328 case NODE_CTF_EXPRESSION
:
329 case NODE_UNARY_EXPRESSION
:
331 case NODE_TYPE_SPECIFIER
:
333 case NODE_FLOATING_POINT
:
336 case NODE_ENUMERATOR
:
344 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
345 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
347 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
353 switch (node
->u
.type_declarator
.type
) {
358 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
359 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
360 node
->u
.type_declarator
.u
.nested
.type_declarator
);
364 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
365 node
->u
.type_declarator
.u
.nested
.length
);
368 if (node
->u
.type_declarator
.bitfield_len
) {
369 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
370 node
->u
.type_declarator
.bitfield_len
);
376 case TYPEDEC_UNKNOWN
:
378 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
379 (int) node
->u
.type_declarator
.type
);
386 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
387 node_type(node
->parent
), node_type(node
));
388 return -EINVAL
; /* Incoherent structure */
391 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
392 node_type(node
->parent
), node_type(node
));
393 return -EPERM
; /* Structure not allowed */
397 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
400 struct ctf_node
*iter
;
402 switch (node
->type
) {
404 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
405 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
409 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
410 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
414 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
415 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
419 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
420 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
427 switch (node
->parent
->type
) {
434 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
435 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
441 switch (node
->parent
->type
) {
448 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
449 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
455 switch (node
->parent
->type
) {
462 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
463 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
469 case NODE_CTF_EXPRESSION
:
470 switch (node
->parent
->type
) {
475 case NODE_FLOATING_POINT
:
480 case NODE_CTF_EXPRESSION
:
481 case NODE_UNARY_EXPRESSION
:
483 case NODE_TYPEALIAS_TARGET
:
484 case NODE_TYPEALIAS_ALIAS
:
485 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
487 case NODE_TYPE_SPECIFIER
:
488 case NODE_TYPE_SPECIFIER_LIST
:
490 case NODE_TYPE_DECLARATOR
:
491 case NODE_ENUMERATOR
:
500 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
501 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
505 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
506 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
512 case NODE_UNARY_EXPRESSION
:
513 return ctf_visitor_unary_expression(fd
, depth
, node
);
516 switch (node
->parent
->type
) {
525 case NODE_CTF_EXPRESSION
:
526 case NODE_UNARY_EXPRESSION
:
528 case NODE_TYPEALIAS_TARGET
:
529 case NODE_TYPEALIAS_ALIAS
:
531 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
532 case NODE_TYPE_SPECIFIER
:
533 case NODE_TYPE_SPECIFIER_LIST
:
535 case NODE_TYPE_DECLARATOR
:
536 case NODE_FLOATING_POINT
:
539 case NODE_ENUMERATOR
:
546 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
547 node
->u
._typedef
.type_specifier_list
);
550 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
551 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
557 case NODE_TYPEALIAS_TARGET
:
561 switch (node
->parent
->type
) {
569 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
570 node
->u
.typealias_target
.type_specifier_list
);
574 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
575 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
580 if (nr_declarators
> 1) {
581 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
588 case NODE_TYPEALIAS_ALIAS
:
592 switch (node
->parent
->type
) {
600 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
601 node
->u
.typealias_alias
.type_specifier_list
);
605 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
606 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
611 if (nr_declarators
> 1) {
612 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
620 switch (node
->parent
->type
) {
629 case NODE_CTF_EXPRESSION
:
630 case NODE_UNARY_EXPRESSION
:
632 case NODE_TYPEALIAS_TARGET
:
633 case NODE_TYPEALIAS_ALIAS
:
635 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
636 case NODE_TYPE_SPECIFIER
:
637 case NODE_TYPE_SPECIFIER_LIST
:
639 case NODE_TYPE_DECLARATOR
:
640 case NODE_FLOATING_POINT
:
643 case NODE_ENUMERATOR
:
649 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
652 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
657 case NODE_TYPE_SPECIFIER_LIST
:
658 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
662 case NODE_TYPE_SPECIFIER
:
663 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
668 switch (node
->parent
->type
) {
669 case NODE_TYPE_DECLARATOR
:
675 case NODE_TYPE_DECLARATOR
:
676 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
681 case NODE_FLOATING_POINT
:
682 switch (node
->parent
->type
) {
683 case NODE_TYPE_SPECIFIER
:
688 case NODE_UNARY_EXPRESSION
:
691 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
692 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
698 switch (node
->parent
->type
) {
699 case NODE_TYPE_SPECIFIER
:
706 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
707 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
713 switch (node
->parent
->type
) {
714 case NODE_TYPE_SPECIFIER
:
719 case NODE_UNARY_EXPRESSION
:
723 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
724 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
729 case NODE_ENUMERATOR
:
730 switch (node
->parent
->type
) {
737 * Enumerators are only allows to contain:
738 * numeric unary expression
739 * or num. unary exp. ... num. unary exp
744 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
747 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
748 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
749 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
750 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
751 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
755 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
756 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
757 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
758 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
759 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
769 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
770 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
776 switch (node
->parent
->type
) {
777 case NODE_TYPE_SPECIFIER
:
782 case NODE_UNARY_EXPRESSION
:
787 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
791 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
792 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
798 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
799 switch (node
->parent
->type
) {
806 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
807 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
810 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
811 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
817 switch (node
->parent
->type
) {
818 case NODE_TYPE_SPECIFIER
:
823 case NODE_UNARY_EXPRESSION
:
826 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
827 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
834 switch (node
->parent
->type
) {
835 case NODE_TYPE_SPECIFIER
:
840 case NODE_UNARY_EXPRESSION
:
843 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
844 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
852 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
859 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
860 node_type(node
->parent
), node_type(node
));
861 return -EINVAL
; /* Incoherent structure */
864 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
865 node_type(node
->parent
), node_type(node
));
866 return -EPERM
; /* Structure not allowed */
869 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
874 * First make sure we create the parent links for all children. Let's
875 * take the safe route and recreate them at each validation, just in
876 * case the structure has changed.
878 printf_verbose("CTF visitor: parent links creation... ");
879 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
882 printf_verbose("done.\n");
883 printf_verbose("CTF visitor: semantic check... ");
884 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
887 printf_verbose("done.\n");