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.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/list.h>
37 #include "ctf-scanner.h"
38 #include "ctf-parser.h"
41 #define _bt_list_first_entry(ptr, type, member) \
42 bt_list_entry((ptr)->next, type, member)
44 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
47 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
);
50 int ctf_visitor_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
52 struct ctf_node
*iter
;
53 int is_ctf_exp
= 0, is_ctf_exp_left
= 0;
55 switch (node
->parent
->type
) {
56 case NODE_CTF_EXPRESSION
:
58 bt_list_for_each_entry(iter
, &node
->parent
->u
.ctf_expression
.left
,
63 * We are a left child of a ctf expression.
64 * We are only allowed to be a string.
66 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
67 fprintf(fd
, "[error]: semantic error (left child of a ctf expression is only allowed to be a string)\n");
74 /* Right child of a ctf expression can be any type of unary exp. */
76 case NODE_TYPE_DECLARATOR
:
78 * We are the length of a type declarator.
80 switch (node
->u
.unary_expression
.type
) {
81 case UNARY_UNSIGNED_CONSTANT
:
85 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");
92 * We are the size of a struct align attribute.
94 switch (node
->u
.unary_expression
.type
) {
95 case UNARY_UNSIGNED_CONSTANT
:
98 fprintf(fd
, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
103 case NODE_ENUMERATOR
:
104 /* The enumerator's parent has validated its validity already. */
107 case NODE_UNARY_EXPRESSION
:
109 * We disallow nested unary expressions and "sbrac" unary
112 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
123 case NODE_TYPEALIAS_TARGET
:
124 case NODE_TYPEALIAS_ALIAS
:
126 case NODE_TYPE_SPECIFIER
:
128 case NODE_FLOATING_POINT
:
132 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
138 switch (node
->u
.unary_expression
.link
) {
139 case UNARY_LINK_UNKNOWN
:
140 /* We don't allow empty link except on the first node of the list */
141 if (is_ctf_exp
&& _bt_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 (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
151 case UNARY_ARROWLINK
:
152 /* We only allow -> and . links between children of ctf_expression. */
153 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
154 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
158 * Only strings can be separated linked by . or ->.
159 * This includes "", '' and non-quoted identifiers.
161 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
162 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
165 /* We don't allow link on the first node of the list */
166 if (is_ctf_exp
&& _bt_list_first_entry(is_ctf_exp_left
?
167 &node
->parent
->u
.ctf_expression
.left
:
168 &node
->parent
->u
.ctf_expression
.right
,
171 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
175 case UNARY_DOTDOTDOT
:
176 /* We only allow ... link between children of enumerator. */
177 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
178 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
181 /* We don't allow link on the first node of the list */
182 if (_bt_list_first_entry(&node
->parent
->u
.enumerator
.values
,
185 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
190 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
191 (int) node
->u
.unary_expression
.link
);
197 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
198 node_type(node
->parent
), node_type(node
));
199 return -EINVAL
; /* Incoherent structure */
202 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
203 node_type(node
->parent
), node_type(node
));
204 return -EPERM
; /* Structure not allowed */
208 int ctf_visitor_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
210 switch (node
->parent
->type
) {
211 case NODE_CTF_EXPRESSION
:
212 case NODE_TYPE_DECLARATOR
:
214 case NODE_TYPEALIAS_TARGET
:
215 case NODE_TYPEALIAS_ALIAS
:
217 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
227 case NODE_UNARY_EXPRESSION
:
229 case NODE_TYPE_SPECIFIER
:
230 case NODE_TYPE_SPECIFIER_LIST
:
232 case NODE_FLOATING_POINT
:
235 case NODE_ENUMERATOR
:
243 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
244 node_type(node
->parent
), node_type(node
));
245 return -EINVAL
; /* Incoherent structure */
249 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
251 switch (node
->parent
->type
) {
252 case NODE_TYPE_SPECIFIER_LIST
:
255 case NODE_CTF_EXPRESSION
:
256 case NODE_TYPE_DECLARATOR
:
258 case NODE_TYPEALIAS_TARGET
:
259 case NODE_TYPEALIAS_ALIAS
:
261 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
269 case NODE_UNARY_EXPRESSION
:
271 case NODE_TYPE_SPECIFIER
:
273 case NODE_FLOATING_POINT
:
276 case NODE_ENUMERATOR
:
284 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
285 node_type(node
->parent
), node_type(node
));
286 return -EINVAL
; /* Incoherent structure */
290 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
293 struct ctf_node
*iter
;
297 switch (node
->parent
->type
) {
298 case NODE_TYPE_DECLARATOR
:
300 * A nested type declarator is not allowed to contain pointers.
302 if (!bt_list_empty(&node
->u
.type_declarator
.pointers
))
305 case NODE_TYPEALIAS_TARGET
:
307 case NODE_TYPEALIAS_ALIAS
:
309 * Only accept alias name containing:
311 * - identifier * (any number of pointers)
312 * NOT accepting alias names containing [] (would otherwise
313 * cause semantic clash for later declarations of
314 * arrays/sequences of elements, where elements could be
315 * arrays/sequences themselves (if allowed in typealias).
316 * NOT accepting alias with identifier. The declarator should
317 * be either empty or contain pointer(s).
319 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
321 bt_list_for_each_entry(iter
, &node
->parent
->u
.typealias_alias
.type_specifier_list
->u
.type_specifier_list
.head
,
323 switch (iter
->u
.type_specifier
.type
) {
324 case TYPESPEC_FLOATING_POINT
:
325 case TYPESPEC_INTEGER
:
326 case TYPESPEC_STRING
:
327 case TYPESPEC_STRUCT
:
328 case TYPESPEC_VARIANT
:
330 if (bt_list_empty(&node
->u
.type_declarator
.pointers
))
337 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
338 node
->u
.type_declarator
.u
.id
!= NULL
)
342 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
352 case NODE_CTF_EXPRESSION
:
353 case NODE_UNARY_EXPRESSION
:
355 case NODE_TYPE_SPECIFIER
:
357 case NODE_FLOATING_POINT
:
360 case NODE_ENUMERATOR
:
368 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
370 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
375 switch (node
->u
.type_declarator
.type
) {
380 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
381 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
382 node
->u
.type_declarator
.u
.nested
.type_declarator
);
386 if (!node
->u
.type_declarator
.u
.nested
.abstract_array
) {
387 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
389 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
390 fprintf(fd
, "[error] %s: expecting unary expression as length\n", __func__
);
393 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
398 if (node
->parent
->type
== NODE_TYPEALIAS_TARGET
) {
399 fprintf(fd
, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__
);
403 if (node
->u
.type_declarator
.bitfield_len
) {
404 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
405 node
->u
.type_declarator
.bitfield_len
);
411 case TYPEDEC_UNKNOWN
:
413 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
414 (int) node
->u
.type_declarator
.type
);
421 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
422 node_type(node
->parent
), node_type(node
));
423 return -EINVAL
; /* Incoherent structure */
426 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
427 node_type(node
->parent
), node_type(node
));
428 return -EPERM
; /* Structure not allowed */
432 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
435 struct ctf_node
*iter
;
437 switch (node
->type
) {
439 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
440 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
444 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
445 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
449 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
450 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
454 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
455 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
462 switch (node
->parent
->type
) {
469 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
470 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
476 switch (node
->parent
->type
) {
483 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
484 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
490 switch (node
->parent
->type
) {
497 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
498 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
504 switch (node
->parent
->type
) {
511 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
512 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
518 switch (node
->parent
->type
) {
525 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
526 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
532 switch (node
->parent
->type
) {
539 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
540 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
546 case NODE_CTF_EXPRESSION
:
547 switch (node
->parent
->type
) {
555 case NODE_FLOATING_POINT
:
560 case NODE_CTF_EXPRESSION
:
561 case NODE_UNARY_EXPRESSION
:
563 case NODE_TYPEALIAS_TARGET
:
564 case NODE_TYPEALIAS_ALIAS
:
565 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
567 case NODE_TYPE_SPECIFIER
:
568 case NODE_TYPE_SPECIFIER_LIST
:
570 case NODE_TYPE_DECLARATOR
:
571 case NODE_ENUMERATOR
:
580 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
581 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
585 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
586 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
592 case NODE_UNARY_EXPRESSION
:
593 return ctf_visitor_unary_expression(fd
, depth
, node
);
596 switch (node
->parent
->type
) {
605 case NODE_CTF_EXPRESSION
:
606 case NODE_UNARY_EXPRESSION
:
608 case NODE_TYPEALIAS_TARGET
:
609 case NODE_TYPEALIAS_ALIAS
:
611 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
612 case NODE_TYPE_SPECIFIER
:
613 case NODE_TYPE_SPECIFIER_LIST
:
615 case NODE_TYPE_DECLARATOR
:
616 case NODE_FLOATING_POINT
:
619 case NODE_ENUMERATOR
:
629 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
630 node
->u
._typedef
.type_specifier_list
);
633 bt_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
634 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
640 case NODE_TYPEALIAS_TARGET
:
644 switch (node
->parent
->type
) {
652 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
653 node
->u
.typealias_target
.type_specifier_list
);
657 bt_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
658 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
663 if (nr_declarators
> 1) {
664 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
671 case NODE_TYPEALIAS_ALIAS
:
675 switch (node
->parent
->type
) {
683 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
684 node
->u
.typealias_alias
.type_specifier_list
);
688 bt_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
689 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
694 if (nr_declarators
> 1) {
695 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
703 switch (node
->parent
->type
) {
712 case NODE_CTF_EXPRESSION
:
713 case NODE_UNARY_EXPRESSION
:
715 case NODE_TYPEALIAS_TARGET
:
716 case NODE_TYPEALIAS_ALIAS
:
718 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
719 case NODE_TYPE_SPECIFIER
:
720 case NODE_TYPE_SPECIFIER_LIST
:
722 case NODE_TYPE_DECLARATOR
:
723 case NODE_FLOATING_POINT
:
726 case NODE_ENUMERATOR
:
735 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
738 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
743 case NODE_TYPE_SPECIFIER_LIST
:
744 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
748 case NODE_TYPE_SPECIFIER
:
749 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
754 switch (node
->parent
->type
) {
755 case NODE_TYPE_DECLARATOR
:
761 case NODE_TYPE_DECLARATOR
:
762 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
767 case NODE_FLOATING_POINT
:
768 switch (node
->parent
->type
) {
769 case NODE_TYPE_SPECIFIER
:
774 case NODE_UNARY_EXPRESSION
:
777 bt_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
778 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
784 switch (node
->parent
->type
) {
785 case NODE_TYPE_SPECIFIER
:
792 bt_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
793 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
799 switch (node
->parent
->type
) {
800 case NODE_TYPE_SPECIFIER
:
805 case NODE_UNARY_EXPRESSION
:
809 bt_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
810 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
815 case NODE_ENUMERATOR
:
816 switch (node
->parent
->type
) {
823 * Enumerators are only allows to contain:
824 * numeric unary expression
825 * or num. unary exp. ... num. unary exp
830 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
833 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
834 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
835 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
836 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
837 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
841 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
842 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
843 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
844 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
845 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
855 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
856 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
862 switch (node
->parent
->type
) {
863 case NODE_TYPE_SPECIFIER
:
868 case NODE_UNARY_EXPRESSION
:
873 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
877 bt_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
878 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
884 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
885 switch (node
->parent
->type
) {
892 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
893 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
896 bt_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
897 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
903 switch (node
->parent
->type
) {
904 case NODE_TYPE_SPECIFIER
:
909 case NODE_UNARY_EXPRESSION
:
912 bt_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
913 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
920 switch (node
->parent
->type
) {
921 case NODE_TYPE_SPECIFIER
:
926 case NODE_UNARY_EXPRESSION
:
929 bt_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
930 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
938 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
945 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
946 node_type(node
->parent
), node_type(node
));
947 return -EINVAL
; /* Incoherent structure */
950 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
951 node_type(node
->parent
), node_type(node
));
952 return -EPERM
; /* Structure not allowed */
955 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
960 * First make sure we create the parent links for all children. Let's
961 * take the safe route and recreate them at each validation, just in
962 * case the structure has changed.
964 printf_verbose("CTF visitor: parent links creation... ");
965 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
968 printf_verbose("done.\n");
969 printf_verbose("CTF visitor: semantic check... ");
970 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
973 printf_verbose("done.\n");