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-internal.h>
28 #include <babeltrace/list.h>
29 #include "ctf-scanner.h"
30 #include "ctf-parser.h"
33 #define _bt_list_first_entry(ptr, type, member) \
34 bt_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 bt_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
:
77 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");
84 * We are the size of a struct align attribute.
86 switch (node
->u
.unary_expression
.type
) {
87 case UNARY_UNSIGNED_CONSTANT
:
90 fprintf(fd
, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
96 /* The enumerator's parent has validated its validity already. */
99 case NODE_UNARY_EXPRESSION
:
101 * We disallow nested unary expressions and "sbrac" unary
104 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
115 case NODE_TYPEALIAS_TARGET
:
116 case NODE_TYPEALIAS_ALIAS
:
118 case NODE_TYPE_SPECIFIER
:
120 case NODE_FLOATING_POINT
:
124 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
130 switch (node
->u
.unary_expression
.link
) {
131 case UNARY_LINK_UNKNOWN
:
132 /* We don't allow empty link except on the first node of the list */
133 if (is_ctf_exp
&& _bt_list_first_entry(is_ctf_exp_left
?
134 &node
->parent
->u
.ctf_expression
.left
:
135 &node
->parent
->u
.ctf_expression
.right
,
138 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
143 case UNARY_ARROWLINK
:
144 /* We only allow -> and . links between children of ctf_expression. */
145 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
146 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
150 * Only strings can be separated linked by . or ->.
151 * This includes "", '' and non-quoted identifiers.
153 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
154 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
157 /* We don't allow link on the first node of the list */
158 if (is_ctf_exp
&& _bt_list_first_entry(is_ctf_exp_left
?
159 &node
->parent
->u
.ctf_expression
.left
:
160 &node
->parent
->u
.ctf_expression
.right
,
163 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
167 case UNARY_DOTDOTDOT
:
168 /* We only allow ... link between children of enumerator. */
169 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
170 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
173 /* We don't allow link on the first node of the list */
174 if (_bt_list_first_entry(&node
->parent
->u
.enumerator
.values
,
177 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
182 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
183 (int) node
->u
.unary_expression
.link
);
189 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
190 node_type(node
->parent
), node_type(node
));
191 return -EINVAL
; /* Incoherent structure */
194 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
195 node_type(node
->parent
), node_type(node
));
196 return -EPERM
; /* Structure not allowed */
200 int ctf_visitor_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
202 switch (node
->parent
->type
) {
203 case NODE_CTF_EXPRESSION
:
204 case NODE_TYPE_DECLARATOR
:
206 case NODE_TYPEALIAS_TARGET
:
207 case NODE_TYPEALIAS_ALIAS
:
209 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
219 case NODE_UNARY_EXPRESSION
:
221 case NODE_TYPE_SPECIFIER
:
222 case NODE_TYPE_SPECIFIER_LIST
:
224 case NODE_FLOATING_POINT
:
227 case NODE_ENUMERATOR
:
235 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
236 node_type(node
->parent
), node_type(node
));
237 return -EINVAL
; /* Incoherent structure */
241 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
243 switch (node
->parent
->type
) {
244 case NODE_TYPE_SPECIFIER_LIST
:
247 case NODE_CTF_EXPRESSION
:
248 case NODE_TYPE_DECLARATOR
:
250 case NODE_TYPEALIAS_TARGET
:
251 case NODE_TYPEALIAS_ALIAS
:
253 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
261 case NODE_UNARY_EXPRESSION
:
263 case NODE_TYPE_SPECIFIER
:
265 case NODE_FLOATING_POINT
:
268 case NODE_ENUMERATOR
:
276 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
277 node_type(node
->parent
), node_type(node
));
278 return -EINVAL
; /* Incoherent structure */
282 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
285 struct ctf_node
*iter
;
289 switch (node
->parent
->type
) {
290 case NODE_TYPE_DECLARATOR
:
292 * A nested type declarator is not allowed to contain pointers.
294 if (!bt_list_empty(&node
->u
.type_declarator
.pointers
))
297 case NODE_TYPEALIAS_TARGET
:
299 case NODE_TYPEALIAS_ALIAS
:
301 * Only accept alias name containing:
303 * - identifier * (any number of pointers)
304 * NOT accepting alias names containing [] (would otherwise
305 * cause semantic clash for later declarations of
306 * arrays/sequences of elements, where elements could be
307 * arrays/sequences themselves (if allowed in typealias).
308 * NOT accepting alias with identifier. The declarator should
309 * be either empty or contain pointer(s).
311 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
313 bt_list_for_each_entry(iter
, &node
->parent
->u
.typealias_alias
.type_specifier_list
->u
.type_specifier_list
.head
,
315 switch (iter
->u
.type_specifier
.type
) {
316 case TYPESPEC_FLOATING_POINT
:
317 case TYPESPEC_INTEGER
:
318 case TYPESPEC_STRING
:
319 case TYPESPEC_STRUCT
:
320 case TYPESPEC_VARIANT
:
322 if (bt_list_empty(&node
->u
.type_declarator
.pointers
))
329 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
330 node
->u
.type_declarator
.u
.id
!= NULL
)
334 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
344 case NODE_CTF_EXPRESSION
:
345 case NODE_UNARY_EXPRESSION
:
347 case NODE_TYPE_SPECIFIER
:
349 case NODE_FLOATING_POINT
:
352 case NODE_ENUMERATOR
:
360 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
362 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
367 switch (node
->u
.type_declarator
.type
) {
372 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
373 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
374 node
->u
.type_declarator
.u
.nested
.type_declarator
);
378 if (!node
->u
.type_declarator
.u
.nested
.abstract_array
) {
379 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
381 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
382 fprintf(fd
, "[error] %s: expecting unary expression as length\n", __func__
);
385 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
390 if (node
->parent
->type
== NODE_TYPEALIAS_TARGET
) {
391 fprintf(fd
, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__
);
395 if (node
->u
.type_declarator
.bitfield_len
) {
396 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
397 node
->u
.type_declarator
.bitfield_len
);
403 case TYPEDEC_UNKNOWN
:
405 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
406 (int) node
->u
.type_declarator
.type
);
413 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
414 node_type(node
->parent
), node_type(node
));
415 return -EINVAL
; /* Incoherent structure */
418 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
419 node_type(node
->parent
), node_type(node
));
420 return -EPERM
; /* Structure not allowed */
424 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
427 struct ctf_node
*iter
;
429 switch (node
->type
) {
431 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
432 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
436 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
437 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
441 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
442 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
446 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
447 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
454 switch (node
->parent
->type
) {
461 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
462 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
468 switch (node
->parent
->type
) {
475 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
476 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
482 switch (node
->parent
->type
) {
489 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
490 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
496 switch (node
->parent
->type
) {
503 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
504 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
510 switch (node
->parent
->type
) {
517 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
518 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
524 switch (node
->parent
->type
) {
531 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
532 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
538 case NODE_CTF_EXPRESSION
:
539 switch (node
->parent
->type
) {
547 case NODE_FLOATING_POINT
:
552 case NODE_CTF_EXPRESSION
:
553 case NODE_UNARY_EXPRESSION
:
555 case NODE_TYPEALIAS_TARGET
:
556 case NODE_TYPEALIAS_ALIAS
:
557 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
559 case NODE_TYPE_SPECIFIER
:
560 case NODE_TYPE_SPECIFIER_LIST
:
562 case NODE_TYPE_DECLARATOR
:
563 case NODE_ENUMERATOR
:
572 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
573 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
577 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
578 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
584 case NODE_UNARY_EXPRESSION
:
585 return ctf_visitor_unary_expression(fd
, depth
, node
);
588 switch (node
->parent
->type
) {
597 case NODE_CTF_EXPRESSION
:
598 case NODE_UNARY_EXPRESSION
:
600 case NODE_TYPEALIAS_TARGET
:
601 case NODE_TYPEALIAS_ALIAS
:
603 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
604 case NODE_TYPE_SPECIFIER
:
605 case NODE_TYPE_SPECIFIER_LIST
:
607 case NODE_TYPE_DECLARATOR
:
608 case NODE_FLOATING_POINT
:
611 case NODE_ENUMERATOR
:
621 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
622 node
->u
._typedef
.type_specifier_list
);
625 bt_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
626 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
632 case NODE_TYPEALIAS_TARGET
:
636 switch (node
->parent
->type
) {
644 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
645 node
->u
.typealias_target
.type_specifier_list
);
649 bt_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
650 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
655 if (nr_declarators
> 1) {
656 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
663 case NODE_TYPEALIAS_ALIAS
:
667 switch (node
->parent
->type
) {
675 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
676 node
->u
.typealias_alias
.type_specifier_list
);
680 bt_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
681 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
686 if (nr_declarators
> 1) {
687 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
695 switch (node
->parent
->type
) {
704 case NODE_CTF_EXPRESSION
:
705 case NODE_UNARY_EXPRESSION
:
707 case NODE_TYPEALIAS_TARGET
:
708 case NODE_TYPEALIAS_ALIAS
:
710 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
711 case NODE_TYPE_SPECIFIER
:
712 case NODE_TYPE_SPECIFIER_LIST
:
714 case NODE_TYPE_DECLARATOR
:
715 case NODE_FLOATING_POINT
:
718 case NODE_ENUMERATOR
:
727 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
730 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
735 case NODE_TYPE_SPECIFIER_LIST
:
736 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
740 case NODE_TYPE_SPECIFIER
:
741 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
746 switch (node
->parent
->type
) {
747 case NODE_TYPE_DECLARATOR
:
753 case NODE_TYPE_DECLARATOR
:
754 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
759 case NODE_FLOATING_POINT
:
760 switch (node
->parent
->type
) {
761 case NODE_TYPE_SPECIFIER
:
766 case NODE_UNARY_EXPRESSION
:
769 bt_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
770 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
776 switch (node
->parent
->type
) {
777 case NODE_TYPE_SPECIFIER
:
784 bt_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
785 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
791 switch (node
->parent
->type
) {
792 case NODE_TYPE_SPECIFIER
:
797 case NODE_UNARY_EXPRESSION
:
801 bt_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
802 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
807 case NODE_ENUMERATOR
:
808 switch (node
->parent
->type
) {
815 * Enumerators are only allows to contain:
816 * numeric unary expression
817 * or num. unary exp. ... num. unary exp
822 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
825 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
826 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
827 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
828 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
829 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
833 case 1: 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_DOTDOTDOT
) {
837 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
847 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
848 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
854 switch (node
->parent
->type
) {
855 case NODE_TYPE_SPECIFIER
:
860 case NODE_UNARY_EXPRESSION
:
865 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
869 bt_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
870 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
876 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
877 switch (node
->parent
->type
) {
884 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
885 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
888 bt_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
889 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
895 switch (node
->parent
->type
) {
896 case NODE_TYPE_SPECIFIER
:
901 case NODE_UNARY_EXPRESSION
:
904 bt_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
905 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
912 switch (node
->parent
->type
) {
913 case NODE_TYPE_SPECIFIER
:
918 case NODE_UNARY_EXPRESSION
:
921 bt_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 printf_verbose("CTF visitor: parent links creation... ");
957 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
960 printf_verbose("done.\n");
961 printf_verbose("CTF visitor: semantic check... ");
962 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
965 printf_verbose("done.\n");