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
:
69 * We are the length of a type declarator.
71 switch (node
->u
.unary_expression
.type
) {
72 case UNARY_SIGNED_CONSTANT
:
73 case UNARY_UNSIGNED_CONSTANT
:
76 fprintf(fd
, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
81 /* The enumerator's parent has validated its validity already. */
84 case NODE_UNARY_EXPRESSION
:
86 * We disallow nested unary expressions and "sbrac" unary
89 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
97 case NODE_TYPEALIAS_TARGET
:
98 case NODE_TYPEALIAS_ALIAS
:
100 case NODE_TYPE_SPECIFIER
:
102 case NODE_FLOATING_POINT
:
106 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
113 switch (node
->u
.unary_expression
.link
) {
114 case UNARY_LINK_UNKNOWN
:
115 /* We don't allow empty link except on the first node of the list */
116 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
117 &node
->parent
->u
.ctf_expression
.left
:
118 &node
->parent
->u
.ctf_expression
.right
,
121 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
126 case UNARY_ARROWLINK
:
127 /* We only allow -> and . links between children of ctf_expression. */
128 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
129 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
133 * Only strings can be separated linked by . or ->.
134 * This includes "", '' and non-quoted identifiers.
136 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
137 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
140 /* We don't allow link on the first node of the list */
141 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
142 &node
->parent
->u
.ctf_expression
.left
:
143 &node
->parent
->u
.ctf_expression
.right
,
146 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
150 case UNARY_DOTDOTDOT
:
151 /* We only allow ... link between children of enumerator. */
152 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
153 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
156 /* We don't allow link on the first node of the list */
157 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
160 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
165 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
166 (int) node
->u
.unary_expression
.link
);
172 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
173 node_type(node
->parent
), node_type(node
));
174 return -EINVAL
; /* Incoherent structure */
177 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
178 node_type(node
->parent
), node_type(node
));
179 return -EPERM
; /* Structure not allowed */
183 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
185 switch (node
->parent
->type
) {
186 case NODE_CTF_EXPRESSION
:
187 case NODE_TYPE_DECLARATOR
:
189 case NODE_TYPEALIAS_TARGET
:
190 case NODE_TYPEALIAS_ALIAS
:
192 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
199 case NODE_UNARY_EXPRESSION
:
201 case NODE_TYPE_SPECIFIER
:
203 case NODE_FLOATING_POINT
:
206 case NODE_ENUMERATOR
:
214 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
215 node_type(node
->parent
), node_type(node
));
216 return -EINVAL
; /* Incoherent structure */
220 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
223 struct ctf_node
*iter
;
227 switch (node
->parent
->type
) {
228 case NODE_TYPE_DECLARATOR
:
230 * A nested type declarator is not allowed to contain pointers.
232 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
235 case NODE_TYPEALIAS_TARGET
:
237 case NODE_TYPEALIAS_ALIAS
:
239 * Only accept alias name containing:
241 * - identifier * (any number of pointers)
242 * NOT accepting alias names containing [] (would otherwise
243 * cause semantic clash for later declarations of
244 * arrays/sequences of elements, where elements could be
245 * arrays/sequences themselves (if allowed in typealias).
246 * NOT accepting alias with identifier. The declarator should
247 * be either empty or contain pointer(s).
249 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
251 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
253 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
254 node
->u
.type_declarator
.u
.id
!= NULL
)
258 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
265 case NODE_CTF_EXPRESSION
:
266 case NODE_UNARY_EXPRESSION
:
268 case NODE_TYPE_SPECIFIER
:
270 case NODE_FLOATING_POINT
:
273 case NODE_ENUMERATOR
:
281 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
282 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
284 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
290 switch (node
->u
.type_declarator
.type
) {
297 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
298 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
299 node
->u
.type_declarator
.u
.nested
.type_declarator
);
303 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
305 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
310 if (iter
->type
== NODE_UNARY_EXPRESSION
&& nr_nest_len
> 1) {
314 if (node
->u
.type_declarator
.bitfield_len
) {
315 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
316 node
->u
.type_declarator
.bitfield_len
);
322 case TYPEDEC_UNKNOWN
:
324 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
325 (int) node
->u
.type_declarator
.type
);
332 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
333 node_type(node
->parent
), node_type(node
));
334 return -EINVAL
; /* Incoherent structure */
337 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
338 node_type(node
->parent
), node_type(node
));
339 return -EPERM
; /* Structure not allowed */
343 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
346 struct ctf_node
*iter
;
348 switch (node
->type
) {
350 cds_list_for_each_entry(iter
, &node
->u
.root
._typedef
,
352 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
356 cds_list_for_each_entry(iter
, &node
->u
.root
.typealias
,
358 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
362 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_specifier
, siblings
) {
363 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
367 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
368 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
372 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
373 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
377 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
378 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
385 switch (node
->parent
->type
) {
392 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
393 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
399 switch (node
->parent
->type
) {
406 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
407 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
413 switch (node
->parent
->type
) {
420 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
421 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
427 case NODE_CTF_EXPRESSION
:
428 switch (node
->parent
->type
) {
433 case NODE_FLOATING_POINT
:
438 case NODE_CTF_EXPRESSION
:
439 case NODE_UNARY_EXPRESSION
:
441 case NODE_TYPEALIAS_TARGET
:
442 case NODE_TYPEALIAS_ALIAS
:
443 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
445 case NODE_TYPE_SPECIFIER
:
447 case NODE_TYPE_DECLARATOR
:
448 case NODE_ENUMERATOR
:
457 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
458 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
462 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
463 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
469 case NODE_UNARY_EXPRESSION
:
470 return ctf_visitor_unary_expression(fd
, depth
, node
);
473 switch (node
->parent
->type
) {
482 case NODE_CTF_EXPRESSION
:
483 case NODE_UNARY_EXPRESSION
:
485 case NODE_TYPEALIAS_TARGET
:
486 case NODE_TYPEALIAS_ALIAS
:
488 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
489 case NODE_TYPE_SPECIFIER
:
491 case NODE_TYPE_DECLARATOR
:
492 case NODE_FLOATING_POINT
:
495 case NODE_ENUMERATOR
:
502 cds_list_for_each_entry(iter
, &node
->u
._typedef
.declaration_specifier
, siblings
) {
503 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
507 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
508 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
514 case NODE_TYPEALIAS_TARGET
:
518 switch (node
->parent
->type
) {
526 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.declaration_specifier
, siblings
) {
527 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
532 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
533 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
538 if (nr_declarators
> 1) {
539 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
546 case NODE_TYPEALIAS_ALIAS
:
550 switch (node
->parent
->type
) {
558 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.declaration_specifier
, siblings
) {
559 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
564 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
565 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
570 if (nr_declarators
> 1) {
571 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
579 switch (node
->parent
->type
) {
588 case NODE_CTF_EXPRESSION
:
589 case NODE_UNARY_EXPRESSION
:
591 case NODE_TYPEALIAS_TARGET
:
592 case NODE_TYPEALIAS_ALIAS
:
594 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
595 case NODE_TYPE_SPECIFIER
:
597 case NODE_TYPE_DECLARATOR
:
598 case NODE_FLOATING_POINT
:
601 case NODE_ENUMERATOR
:
607 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
610 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
615 case NODE_TYPE_SPECIFIER
:
616 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
621 switch (node
->parent
->type
) {
622 case NODE_TYPE_DECLARATOR
:
628 case NODE_TYPE_DECLARATOR
:
629 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
634 case NODE_FLOATING_POINT
:
635 switch (node
->parent
->type
) {
636 case NODE_CTF_EXPRESSION
:
638 case NODE_TYPEALIAS_TARGET
:
639 case NODE_TYPEALIAS_ALIAS
:
640 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
648 case NODE_TYPE_SPECIFIER
:
650 case NODE_TYPE_DECLARATOR
:
651 case NODE_FLOATING_POINT
:
654 case NODE_ENUMERATOR
:
661 case NODE_UNARY_EXPRESSION
:
664 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
665 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
671 switch (node
->parent
->type
) {
672 case NODE_CTF_EXPRESSION
:
673 case NODE_UNARY_EXPRESSION
:
675 case NODE_TYPEALIAS_TARGET
:
676 case NODE_TYPEALIAS_ALIAS
:
677 case NODE_TYPE_DECLARATOR
:
679 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
687 case NODE_TYPE_SPECIFIER
:
689 case NODE_FLOATING_POINT
:
692 case NODE_ENUMERATOR
:
700 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
701 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
707 switch (node
->parent
->type
) {
708 case NODE_CTF_EXPRESSION
:
710 case NODE_TYPEALIAS_TARGET
:
711 case NODE_TYPEALIAS_ALIAS
:
712 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
720 case NODE_TYPE_SPECIFIER
:
722 case NODE_TYPE_DECLARATOR
:
723 case NODE_FLOATING_POINT
:
726 case NODE_ENUMERATOR
:
733 case NODE_UNARY_EXPRESSION
:
737 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
738 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
743 case NODE_ENUMERATOR
:
744 switch (node
->parent
->type
) {
751 * Enumerators are only allows to contain:
752 * numeric unary expression
753 * or num. unary exp. ... num. unary exp
758 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
761 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
762 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
763 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
764 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
765 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
769 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
770 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
771 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
772 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
773 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
783 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
784 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
790 switch (node
->parent
->type
) {
795 case NODE_CTF_EXPRESSION
:
797 case NODE_TYPEALIAS_TARGET
:
798 case NODE_TYPEALIAS_ALIAS
:
799 case NODE_TYPE_DECLARATOR
:
800 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
804 case NODE_TYPE_SPECIFIER
:
806 case NODE_FLOATING_POINT
:
809 case NODE_ENUMERATOR
:
816 case NODE_UNARY_EXPRESSION
:
821 cds_list_for_each_entry(iter
, &node
->u
._enum
.container_type
,
823 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
828 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
829 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
835 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
836 switch (node
->parent
->type
) {
843 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.declaration_specifier
, siblings
) {
844 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
848 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
849 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
855 switch (node
->parent
->type
) {
860 case NODE_CTF_EXPRESSION
:
862 case NODE_TYPEALIAS_TARGET
:
863 case NODE_TYPEALIAS_ALIAS
:
864 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
868 case NODE_TYPE_SPECIFIER
:
870 case NODE_TYPE_DECLARATOR
:
871 case NODE_FLOATING_POINT
:
874 case NODE_ENUMERATOR
:
881 case NODE_UNARY_EXPRESSION
:
884 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
885 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
892 switch (node
->parent
->type
) {
897 case NODE_CTF_EXPRESSION
:
899 case NODE_TYPEALIAS_TARGET
:
900 case NODE_TYPEALIAS_ALIAS
:
901 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
905 case NODE_TYPE_SPECIFIER
:
907 case NODE_TYPE_DECLARATOR
:
908 case NODE_FLOATING_POINT
:
911 case NODE_ENUMERATOR
:
918 case NODE_UNARY_EXPRESSION
:
921 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
922 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
930 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
937 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
938 node_type(node
->parent
), node_type(node
));
939 return -EINVAL
; /* Incoherent structure */
942 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
943 node_type(node
->parent
), node_type(node
));
944 return -EPERM
; /* Structure not allowed */
947 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
952 * First make sure we create the parent links for all children. Let's
953 * take the safe route and recreate them at each validation, just in
954 * case the structure has changed.
956 fprintf(fd
, "CTF visitor: parent links creation... ");
957 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
960 fprintf(fd
, "done.\n");
961 fprintf(fd
, "CTF visitor: semantic check... ");
962 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
965 fprintf(fd
, "done.\n");