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/list.h>
28 #include "ctf-scanner.h"
29 #include "ctf-parser.h"
32 #define _cds_list_first_entry(ptr, type, member) \
33 cds_list_entry((ptr)->next, type, member)
35 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
38 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
);
41 int ctf_visitor_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
43 struct ctf_node
*iter
;
44 int is_ctf_exp
= 0, is_ctf_exp_left
= 0;
46 switch (node
->parent
->type
) {
47 case NODE_CTF_EXPRESSION
:
49 cds_list_for_each_entry(iter
, &node
->parent
->u
.ctf_expression
.left
,
54 * We are a left child of a ctf expression.
55 * We are only allowed to be a string.
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");
65 /* Right child of a ctf expression can be any type of unary exp. */
67 case NODE_TYPE_DECLARATOR
:
70 * We are the length of a type declarator or the size of an enum
71 * container. We can only be a numeric constant.
73 switch (node
->u
.unary_expression
.type
) {
74 case UNARY_SIGNED_CONSTANT
:
75 case UNARY_UNSIGNED_CONSTANT
:
78 fprintf(fd
, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
83 /* The enumerator's parent has validated its validity already. */
86 case NODE_UNARY_EXPRESSION
:
88 * We disallow nested unary expressions and "sbrac" unary
91 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
99 case NODE_TYPEALIAS_TARGET
:
100 case NODE_TYPEALIAS_ALIAS
:
102 case NODE_TYPE_SPECIFIER
:
104 case NODE_FLOATING_POINT
:
107 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
114 switch (node
->u
.unary_expression
.link
) {
115 case UNARY_LINK_UNKNOWN
:
116 /* We don't allow empty link except on the first node of the list */
117 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
118 &node
->parent
->u
.ctf_expression
.left
:
119 &node
->parent
->u
.ctf_expression
.right
,
122 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
127 case UNARY_ARROWLINK
:
128 /* We only allow -> and . links between children of ctf_expression. */
129 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
130 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
134 * Only strings can be separated linked by . or ->.
135 * This includes "", '' and non-quoted identifiers.
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");
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
,
147 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
151 case UNARY_DOTDOTDOT
:
152 /* We only allow ... link between children of enumerator. */
153 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
154 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
157 /* We don't allow link on the first node of the list */
158 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
161 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
166 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
167 (int) node
->u
.unary_expression
.link
);
173 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
174 node_type(node
->parent
), node_type(node
));
175 return -EINVAL
; /* Incoherent structure */
178 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
179 node_type(node
->parent
), node_type(node
));
180 return -EPERM
; /* Structure not allowed */
184 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
186 switch (node
->parent
->type
) {
187 case NODE_CTF_EXPRESSION
:
188 case NODE_TYPE_DECLARATOR
:
190 case NODE_TYPEALIAS_TARGET
:
191 case NODE_TYPEALIAS_ALIAS
:
193 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
200 case NODE_UNARY_EXPRESSION
:
202 case NODE_TYPE_SPECIFIER
:
204 case NODE_FLOATING_POINT
:
207 case NODE_ENUMERATOR
:
215 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
216 node_type(node
->parent
), node_type(node
));
217 return -EINVAL
; /* Incoherent structure */
221 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
224 struct ctf_node
*iter
;
228 switch (node
->parent
->type
) {
229 case NODE_TYPE_DECLARATOR
:
231 * A nested type declarator is not allowed to contain pointers.
233 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
236 case NODE_TYPEALIAS_TARGET
:
238 case NODE_TYPEALIAS_ALIAS
:
240 * Only accept alias name containing:
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).
250 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
252 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
254 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
255 node
->u
.type_declarator
.u
.id
!= NULL
)
259 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
266 case NODE_CTF_EXPRESSION
:
267 case NODE_UNARY_EXPRESSION
:
269 case NODE_TYPE_SPECIFIER
:
271 case NODE_FLOATING_POINT
:
274 case NODE_ENUMERATOR
:
282 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
283 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
285 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
291 switch (node
->u
.type_declarator
.type
) {
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
);
304 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
306 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
311 if (iter
->type
== NODE_UNARY_EXPRESSION
&& nr_nest_len
> 1) {
315 if (node
->u
.type_declarator
.bitfield_len
) {
316 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
317 node
->u
.type_declarator
.bitfield_len
);
323 case TYPEDEC_UNKNOWN
:
325 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
326 (int) node
->u
.type_declarator
.type
);
333 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
334 node_type(node
->parent
), node_type(node
));
335 return -EINVAL
; /* Incoherent structure */
338 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
339 node_type(node
->parent
), node_type(node
));
340 return -EPERM
; /* Structure not allowed */
344 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
347 struct ctf_node
*iter
;
349 switch (node
->type
) {
351 cds_list_for_each_entry(iter
, &node
->u
.root
._typedef
,
353 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
357 cds_list_for_each_entry(iter
, &node
->u
.root
.typealias
,
359 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
363 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_specifier
, siblings
) {
364 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
368 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
369 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
373 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
374 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
378 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
379 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
386 switch (node
->parent
->type
) {
393 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
394 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
400 switch (node
->parent
->type
) {
407 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
408 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
414 switch (node
->parent
->type
) {
421 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
422 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
428 case NODE_CTF_EXPRESSION
:
429 switch (node
->parent
->type
) {
434 case NODE_FLOATING_POINT
:
439 case NODE_CTF_EXPRESSION
:
440 case NODE_UNARY_EXPRESSION
:
442 case NODE_TYPEALIAS_TARGET
:
443 case NODE_TYPEALIAS_ALIAS
:
444 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
446 case NODE_TYPE_SPECIFIER
:
448 case NODE_TYPE_DECLARATOR
:
449 case NODE_ENUMERATOR
:
458 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
459 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
463 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
464 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
470 case NODE_UNARY_EXPRESSION
:
471 return ctf_visitor_unary_expression(fd
, depth
, node
);
474 switch (node
->parent
->type
) {
483 case NODE_CTF_EXPRESSION
:
484 case NODE_UNARY_EXPRESSION
:
486 case NODE_TYPEALIAS_TARGET
:
487 case NODE_TYPEALIAS_ALIAS
:
489 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
490 case NODE_TYPE_SPECIFIER
:
492 case NODE_TYPE_DECLARATOR
:
493 case NODE_FLOATING_POINT
:
496 case NODE_ENUMERATOR
:
503 cds_list_for_each_entry(iter
, &node
->u
._typedef
.declaration_specifier
, siblings
) {
504 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
508 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
509 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
515 case NODE_TYPEALIAS_TARGET
:
519 switch (node
->parent
->type
) {
527 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.declaration_specifier
, siblings
) {
528 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
533 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
534 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
539 if (nr_declarators
> 1) {
540 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
547 case NODE_TYPEALIAS_ALIAS
:
551 switch (node
->parent
->type
) {
559 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.declaration_specifier
, siblings
) {
560 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
565 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
566 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
571 if (nr_declarators
> 1) {
572 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
580 switch (node
->parent
->type
) {
589 case NODE_CTF_EXPRESSION
:
590 case NODE_UNARY_EXPRESSION
:
592 case NODE_TYPEALIAS_TARGET
:
593 case NODE_TYPEALIAS_ALIAS
:
595 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
596 case NODE_TYPE_SPECIFIER
:
598 case NODE_TYPE_DECLARATOR
:
599 case NODE_FLOATING_POINT
:
602 case NODE_ENUMERATOR
:
608 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
611 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
616 case NODE_TYPE_SPECIFIER
:
617 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
622 switch (node
->parent
->type
) {
623 case NODE_TYPE_DECLARATOR
:
629 case NODE_TYPE_DECLARATOR
:
630 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
635 case NODE_FLOATING_POINT
:
636 switch (node
->parent
->type
) {
637 case NODE_CTF_EXPRESSION
:
639 case NODE_TYPEALIAS_TARGET
:
640 case NODE_TYPEALIAS_ALIAS
:
641 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
649 case NODE_TYPE_SPECIFIER
:
651 case NODE_TYPE_DECLARATOR
:
652 case NODE_FLOATING_POINT
:
655 case NODE_ENUMERATOR
:
662 case NODE_UNARY_EXPRESSION
:
665 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
666 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
672 switch (node
->parent
->type
) {
673 case NODE_CTF_EXPRESSION
:
674 case NODE_UNARY_EXPRESSION
:
676 case NODE_TYPEALIAS_TARGET
:
677 case NODE_TYPEALIAS_ALIAS
:
678 case NODE_TYPE_DECLARATOR
:
680 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
688 case NODE_TYPE_SPECIFIER
:
690 case NODE_FLOATING_POINT
:
693 case NODE_ENUMERATOR
:
701 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
702 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
708 switch (node
->parent
->type
) {
709 case NODE_CTF_EXPRESSION
:
711 case NODE_TYPEALIAS_TARGET
:
712 case NODE_TYPEALIAS_ALIAS
:
713 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
721 case NODE_TYPE_SPECIFIER
:
723 case NODE_TYPE_DECLARATOR
:
724 case NODE_FLOATING_POINT
:
727 case NODE_ENUMERATOR
:
734 case NODE_UNARY_EXPRESSION
:
738 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
739 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
744 case NODE_ENUMERATOR
:
745 switch (node
->parent
->type
) {
752 * Enumerators are only allows to contain:
753 * numeric unary expression
754 * or num. unary exp. ... num. unary exp
759 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
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
)
765 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
766 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
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
)
773 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
774 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
784 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
785 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
791 switch (node
->parent
->type
) {
796 case NODE_CTF_EXPRESSION
:
798 case NODE_TYPEALIAS_TARGET
:
799 case NODE_TYPEALIAS_ALIAS
:
800 case NODE_TYPE_DECLARATOR
:
801 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
805 case NODE_TYPE_SPECIFIER
:
807 case NODE_FLOATING_POINT
:
810 case NODE_ENUMERATOR
:
817 case NODE_UNARY_EXPRESSION
:
822 cds_list_for_each_entry(iter
, &node
->u
._enum
.container_type
,
824 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
829 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
830 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
836 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
837 switch (node
->parent
->type
) {
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
);
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
);
856 switch (node
->parent
->type
) {
861 case NODE_CTF_EXPRESSION
:
863 case NODE_TYPEALIAS_TARGET
:
864 case NODE_TYPEALIAS_ALIAS
:
865 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
869 case NODE_TYPE_SPECIFIER
:
871 case NODE_TYPE_DECLARATOR
:
872 case NODE_FLOATING_POINT
:
875 case NODE_ENUMERATOR
:
882 case NODE_UNARY_EXPRESSION
:
885 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
886 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
893 switch (node
->parent
->type
) {
898 case NODE_CTF_EXPRESSION
:
900 case NODE_TYPEALIAS_TARGET
:
901 case NODE_TYPEALIAS_ALIAS
:
902 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
906 case NODE_TYPE_SPECIFIER
:
908 case NODE_TYPE_DECLARATOR
:
909 case NODE_FLOATING_POINT
:
912 case NODE_ENUMERATOR
:
919 case NODE_UNARY_EXPRESSION
:
922 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
923 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
931 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
938 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
939 node_type(node
->parent
), node_type(node
));
940 return -EINVAL
; /* Incoherent structure */
943 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
944 node_type(node
->parent
), node_type(node
));
945 return -EPERM
; /* Structure not allowed */
948 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
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.
957 fprintf(fd
, "CTF visitor: parent links creation... ");
958 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
961 fprintf(fd
, "done.\n");
962 fprintf(fd
, "CTF visitor: semantic check... ");
963 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
966 fprintf(fd
, "done.\n");