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
:
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");
112 case NODE_TYPEALIAS_TARGET
:
113 case NODE_TYPEALIAS_ALIAS
:
115 case NODE_TYPE_SPECIFIER
:
117 case NODE_FLOATING_POINT
:
121 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
127 switch (node
->u
.unary_expression
.link
) {
128 case UNARY_LINK_UNKNOWN
:
129 /* We don't allow empty link except on the first node of the list */
130 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
131 &node
->parent
->u
.ctf_expression
.left
:
132 &node
->parent
->u
.ctf_expression
.right
,
135 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
140 case UNARY_ARROWLINK
:
141 /* We only allow -> and . links between children of ctf_expression. */
142 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
143 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
147 * Only strings can be separated linked by . or ->.
148 * This includes "", '' and non-quoted identifiers.
150 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
151 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
154 /* We don't allow link on the first node of the list */
155 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
156 &node
->parent
->u
.ctf_expression
.left
:
157 &node
->parent
->u
.ctf_expression
.right
,
160 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
164 case UNARY_DOTDOTDOT
:
165 /* We only allow ... link between children of enumerator. */
166 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
167 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
170 /* We don't allow link on the first node of the list */
171 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
174 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
179 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
180 (int) node
->u
.unary_expression
.link
);
186 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
187 node_type(node
->parent
), node_type(node
));
188 return -EINVAL
; /* Incoherent structure */
191 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
192 node_type(node
->parent
), node_type(node
));
193 return -EPERM
; /* Structure not allowed */
197 int ctf_visitor_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
199 switch (node
->parent
->type
) {
200 case NODE_CTF_EXPRESSION
:
201 case NODE_TYPE_DECLARATOR
:
203 case NODE_TYPEALIAS_TARGET
:
204 case NODE_TYPEALIAS_ALIAS
:
206 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
213 case NODE_UNARY_EXPRESSION
:
215 case NODE_TYPE_SPECIFIER
:
216 case NODE_TYPE_SPECIFIER_LIST
:
218 case NODE_FLOATING_POINT
:
221 case NODE_ENUMERATOR
:
229 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
230 node_type(node
->parent
), node_type(node
));
231 return -EINVAL
; /* Incoherent structure */
235 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
237 switch (node
->parent
->type
) {
238 case NODE_TYPE_SPECIFIER_LIST
:
241 case NODE_CTF_EXPRESSION
:
242 case NODE_TYPE_DECLARATOR
:
244 case NODE_TYPEALIAS_TARGET
:
245 case NODE_TYPEALIAS_ALIAS
:
247 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
252 case NODE_UNARY_EXPRESSION
:
254 case NODE_TYPE_SPECIFIER
:
256 case NODE_FLOATING_POINT
:
259 case NODE_ENUMERATOR
:
267 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
268 node_type(node
->parent
), node_type(node
));
269 return -EINVAL
; /* Incoherent structure */
273 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
276 struct ctf_node
*iter
;
280 switch (node
->parent
->type
) {
281 case NODE_TYPE_DECLARATOR
:
283 * A nested type declarator is not allowed to contain pointers.
285 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
288 case NODE_TYPEALIAS_TARGET
:
290 case NODE_TYPEALIAS_ALIAS
:
292 * Only accept alias name containing:
294 * - identifier * (any number of pointers)
295 * NOT accepting alias names containing [] (would otherwise
296 * cause semantic clash for later declarations of
297 * arrays/sequences of elements, where elements could be
298 * arrays/sequences themselves (if allowed in typealias).
299 * NOT accepting alias with identifier. The declarator should
300 * be either empty or contain pointer(s).
302 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
304 cds_list_for_each_entry(iter
, &node
->parent
->u
.typealias_alias
.type_specifier_list
->u
.type_specifier_list
.head
,
306 switch (iter
->u
.type_specifier
.type
) {
307 case TYPESPEC_FLOATING_POINT
:
308 case TYPESPEC_INTEGER
:
309 case TYPESPEC_STRING
:
310 case TYPESPEC_STRUCT
:
311 case TYPESPEC_VARIANT
:
313 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
320 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
321 node
->u
.type_declarator
.u
.id
!= NULL
)
325 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
332 case NODE_CTF_EXPRESSION
:
333 case NODE_UNARY_EXPRESSION
:
335 case NODE_TYPE_SPECIFIER
:
337 case NODE_FLOATING_POINT
:
340 case NODE_ENUMERATOR
:
348 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
350 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
355 switch (node
->u
.type_declarator
.type
) {
360 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
361 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
362 node
->u
.type_declarator
.u
.nested
.type_declarator
);
366 if (!node
->u
.type_declarator
.u
.nested
.abstract_array
) {
367 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
369 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
370 fprintf(fd
, "[error] %s: expecting unary expression as length\n", __func__
);
373 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
378 if (node
->parent
->type
== NODE_TYPEALIAS_TARGET
) {
379 fprintf(fd
, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__
);
383 if (node
->u
.type_declarator
.bitfield_len
) {
384 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
385 node
->u
.type_declarator
.bitfield_len
);
391 case TYPEDEC_UNKNOWN
:
393 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
394 (int) node
->u
.type_declarator
.type
);
401 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
402 node_type(node
->parent
), node_type(node
));
403 return -EINVAL
; /* Incoherent structure */
406 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
407 node_type(node
->parent
), node_type(node
));
408 return -EPERM
; /* Structure not allowed */
412 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
415 struct ctf_node
*iter
;
417 switch (node
->type
) {
419 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
420 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
424 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
425 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
429 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
430 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
434 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
435 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
442 switch (node
->parent
->type
) {
449 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
450 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
456 switch (node
->parent
->type
) {
463 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
464 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
470 switch (node
->parent
->type
) {
477 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
478 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
484 case NODE_CTF_EXPRESSION
:
485 switch (node
->parent
->type
) {
490 case NODE_FLOATING_POINT
:
495 case NODE_CTF_EXPRESSION
:
496 case NODE_UNARY_EXPRESSION
:
498 case NODE_TYPEALIAS_TARGET
:
499 case NODE_TYPEALIAS_ALIAS
:
500 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
502 case NODE_TYPE_SPECIFIER
:
503 case NODE_TYPE_SPECIFIER_LIST
:
505 case NODE_TYPE_DECLARATOR
:
506 case NODE_ENUMERATOR
:
515 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
516 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
520 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
521 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
527 case NODE_UNARY_EXPRESSION
:
528 return ctf_visitor_unary_expression(fd
, depth
, node
);
531 switch (node
->parent
->type
) {
540 case NODE_CTF_EXPRESSION
:
541 case NODE_UNARY_EXPRESSION
:
543 case NODE_TYPEALIAS_TARGET
:
544 case NODE_TYPEALIAS_ALIAS
:
546 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
547 case NODE_TYPE_SPECIFIER
:
548 case NODE_TYPE_SPECIFIER_LIST
:
550 case NODE_TYPE_DECLARATOR
:
551 case NODE_FLOATING_POINT
:
554 case NODE_ENUMERATOR
:
561 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
562 node
->u
._typedef
.type_specifier_list
);
565 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
566 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
572 case NODE_TYPEALIAS_TARGET
:
576 switch (node
->parent
->type
) {
584 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
585 node
->u
.typealias_target
.type_specifier_list
);
589 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
590 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
595 if (nr_declarators
> 1) {
596 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
603 case NODE_TYPEALIAS_ALIAS
:
607 switch (node
->parent
->type
) {
615 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
616 node
->u
.typealias_alias
.type_specifier_list
);
620 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
621 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
626 if (nr_declarators
> 1) {
627 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
635 switch (node
->parent
->type
) {
644 case NODE_CTF_EXPRESSION
:
645 case NODE_UNARY_EXPRESSION
:
647 case NODE_TYPEALIAS_TARGET
:
648 case NODE_TYPEALIAS_ALIAS
:
650 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
651 case NODE_TYPE_SPECIFIER
:
652 case NODE_TYPE_SPECIFIER_LIST
:
654 case NODE_TYPE_DECLARATOR
:
655 case NODE_FLOATING_POINT
:
658 case NODE_ENUMERATOR
:
664 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
667 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
672 case NODE_TYPE_SPECIFIER_LIST
:
673 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
677 case NODE_TYPE_SPECIFIER
:
678 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
683 switch (node
->parent
->type
) {
684 case NODE_TYPE_DECLARATOR
:
690 case NODE_TYPE_DECLARATOR
:
691 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
696 case NODE_FLOATING_POINT
:
697 switch (node
->parent
->type
) {
698 case NODE_TYPE_SPECIFIER
:
703 case NODE_UNARY_EXPRESSION
:
706 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
707 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
713 switch (node
->parent
->type
) {
714 case NODE_TYPE_SPECIFIER
:
721 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
722 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
728 switch (node
->parent
->type
) {
729 case NODE_TYPE_SPECIFIER
:
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
) {
792 case NODE_TYPE_SPECIFIER
:
797 case NODE_UNARY_EXPRESSION
:
802 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
806 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
807 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
813 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
814 switch (node
->parent
->type
) {
821 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
822 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
825 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
826 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
832 switch (node
->parent
->type
) {
833 case NODE_TYPE_SPECIFIER
:
838 case NODE_UNARY_EXPRESSION
:
841 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
842 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
849 switch (node
->parent
->type
) {
850 case NODE_TYPE_SPECIFIER
:
855 case NODE_UNARY_EXPRESSION
:
858 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
859 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
867 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
874 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
875 node_type(node
->parent
), node_type(node
));
876 return -EINVAL
; /* Incoherent structure */
879 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
880 node_type(node
->parent
), node_type(node
));
881 return -EPERM
; /* Structure not allowed */
884 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
889 * First make sure we create the parent links for all children. Let's
890 * take the safe route and recreate them at each validation, just in
891 * case the structure has changed.
893 printf_verbose("CTF visitor: parent links creation... ");
894 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
897 printf_verbose("done.\n");
898 printf_verbose("CTF visitor: semantic check... ");
899 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
902 printf_verbose("done.\n");