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_SIGNED_CONSTANT
:
74 case UNARY_UNSIGNED_CONSTANT
:
77 fprintf(fd
, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
82 /* The enumerator's parent has validated its validity already. */
85 case NODE_UNARY_EXPRESSION
:
87 * We disallow nested unary expressions and "sbrac" unary
90 fprintf(fd
, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
98 case NODE_TYPEALIAS_TARGET
:
99 case NODE_TYPEALIAS_ALIAS
:
101 case NODE_TYPE_SPECIFIER
:
103 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_list(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
:
203 case NODE_TYPE_SPECIFIER_LIST
:
205 case NODE_FLOATING_POINT
:
208 case NODE_ENUMERATOR
:
216 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
217 node_type(node
->parent
), node_type(node
));
218 return -EINVAL
; /* Incoherent structure */
222 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
224 switch (node
->parent
->type
) {
225 case NODE_TYPE_SPECIFIER_LIST
:
228 case NODE_CTF_EXPRESSION
:
229 case NODE_TYPE_DECLARATOR
:
231 case NODE_TYPEALIAS_TARGET
:
232 case NODE_TYPEALIAS_ALIAS
:
234 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
239 case NODE_UNARY_EXPRESSION
:
241 case NODE_TYPE_SPECIFIER
:
243 case NODE_FLOATING_POINT
:
246 case NODE_ENUMERATOR
:
254 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
255 node_type(node
->parent
), node_type(node
));
256 return -EINVAL
; /* Incoherent structure */
260 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
263 struct ctf_node
*iter
;
267 switch (node
->parent
->type
) {
268 case NODE_TYPE_DECLARATOR
:
270 * A nested type declarator is not allowed to contain pointers.
272 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
275 case NODE_TYPEALIAS_TARGET
:
277 case NODE_TYPEALIAS_ALIAS
:
279 * Only accept alias name containing:
281 * - identifier * (any number of pointers)
282 * NOT accepting alias names containing [] (would otherwise
283 * cause semantic clash for later declarations of
284 * arrays/sequences of elements, where elements could be
285 * arrays/sequences themselves (if allowed in typealias).
286 * NOT accepting alias with identifier. The declarator should
287 * be either empty or contain pointer(s).
289 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
291 switch (node
->u
.type_declarator
.type
) {
292 case TYPESPEC_FLOATING_POINT
:
293 case TYPESPEC_INTEGER
:
294 case TYPESPEC_STRING
:
295 case TYPESPEC_STRUCT
:
296 case TYPESPEC_VARIANT
:
298 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
304 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
305 node
->u
.type_declarator
.u
.id
!= NULL
)
309 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
316 case NODE_CTF_EXPRESSION
:
317 case NODE_UNARY_EXPRESSION
:
319 case NODE_TYPE_SPECIFIER
:
321 case NODE_FLOATING_POINT
:
324 case NODE_ENUMERATOR
:
332 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
333 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
335 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
341 switch (node
->u
.type_declarator
.type
) {
346 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
347 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
348 node
->u
.type_declarator
.u
.nested
.type_declarator
);
352 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
353 node
->u
.type_declarator
.u
.nested
.length
);
356 if (node
->u
.type_declarator
.bitfield_len
) {
357 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
358 node
->u
.type_declarator
.bitfield_len
);
364 case TYPEDEC_UNKNOWN
:
366 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
367 (int) node
->u
.type_declarator
.type
);
374 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
375 node_type(node
->parent
), node_type(node
));
376 return -EINVAL
; /* Incoherent structure */
379 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
380 node_type(node
->parent
), node_type(node
));
381 return -EPERM
; /* Structure not allowed */
385 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
388 struct ctf_node
*iter
;
390 switch (node
->type
) {
392 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
393 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
397 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
398 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
402 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
403 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
407 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
408 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
415 switch (node
->parent
->type
) {
422 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
423 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
429 switch (node
->parent
->type
) {
436 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
437 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
443 switch (node
->parent
->type
) {
450 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
451 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
457 case NODE_CTF_EXPRESSION
:
458 switch (node
->parent
->type
) {
463 case NODE_FLOATING_POINT
:
468 case NODE_CTF_EXPRESSION
:
469 case NODE_UNARY_EXPRESSION
:
471 case NODE_TYPEALIAS_TARGET
:
472 case NODE_TYPEALIAS_ALIAS
:
473 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
475 case NODE_TYPE_SPECIFIER
:
476 case NODE_TYPE_SPECIFIER_LIST
:
478 case NODE_TYPE_DECLARATOR
:
479 case NODE_ENUMERATOR
:
488 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
489 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
493 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
494 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
500 case NODE_UNARY_EXPRESSION
:
501 return ctf_visitor_unary_expression(fd
, depth
, node
);
504 switch (node
->parent
->type
) {
513 case NODE_CTF_EXPRESSION
:
514 case NODE_UNARY_EXPRESSION
:
516 case NODE_TYPEALIAS_TARGET
:
517 case NODE_TYPEALIAS_ALIAS
:
519 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
520 case NODE_TYPE_SPECIFIER
:
521 case NODE_TYPE_SPECIFIER_LIST
:
523 case NODE_TYPE_DECLARATOR
:
524 case NODE_FLOATING_POINT
:
527 case NODE_ENUMERATOR
:
534 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
535 node
->u
._typedef
.type_specifier_list
);
538 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
539 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
545 case NODE_TYPEALIAS_TARGET
:
549 switch (node
->parent
->type
) {
557 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
558 node
->u
.typealias_target
.type_specifier_list
);
562 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
563 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
568 if (nr_declarators
> 1) {
569 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
576 case NODE_TYPEALIAS_ALIAS
:
580 switch (node
->parent
->type
) {
588 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
589 node
->u
.typealias_alias
.type_specifier_list
);
593 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
594 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
599 if (nr_declarators
> 1) {
600 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
608 switch (node
->parent
->type
) {
617 case NODE_CTF_EXPRESSION
:
618 case NODE_UNARY_EXPRESSION
:
620 case NODE_TYPEALIAS_TARGET
:
621 case NODE_TYPEALIAS_ALIAS
:
623 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
624 case NODE_TYPE_SPECIFIER
:
625 case NODE_TYPE_SPECIFIER_LIST
:
627 case NODE_TYPE_DECLARATOR
:
628 case NODE_FLOATING_POINT
:
631 case NODE_ENUMERATOR
:
637 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
640 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
645 case NODE_TYPE_SPECIFIER_LIST
:
646 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
650 case NODE_TYPE_SPECIFIER
:
651 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
656 switch (node
->parent
->type
) {
657 case NODE_TYPE_DECLARATOR
:
663 case NODE_TYPE_DECLARATOR
:
664 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
669 case NODE_FLOATING_POINT
:
670 switch (node
->parent
->type
) {
671 case NODE_TYPE_SPECIFIER
:
676 case NODE_UNARY_EXPRESSION
:
679 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
680 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
686 switch (node
->parent
->type
) {
687 case NODE_TYPE_SPECIFIER
:
694 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
695 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
701 switch (node
->parent
->type
) {
702 case NODE_TYPE_SPECIFIER
:
707 case NODE_UNARY_EXPRESSION
:
711 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
712 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
717 case NODE_ENUMERATOR
:
718 switch (node
->parent
->type
) {
725 * Enumerators are only allows to contain:
726 * numeric unary expression
727 * or num. unary exp. ... num. unary exp
732 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
735 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
736 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
737 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
738 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
739 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
743 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
744 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
745 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
746 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
747 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
757 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
758 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
764 switch (node
->parent
->type
) {
765 case NODE_TYPE_SPECIFIER
:
770 case NODE_UNARY_EXPRESSION
:
775 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
779 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
780 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
786 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
787 switch (node
->parent
->type
) {
794 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
795 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
798 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
799 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
805 switch (node
->parent
->type
) {
806 case NODE_TYPE_SPECIFIER
:
811 case NODE_UNARY_EXPRESSION
:
814 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
815 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
822 switch (node
->parent
->type
) {
823 case NODE_TYPE_SPECIFIER
:
828 case NODE_UNARY_EXPRESSION
:
831 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
832 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
840 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
847 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
848 node_type(node
->parent
), node_type(node
));
849 return -EINVAL
; /* Incoherent structure */
852 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
853 node_type(node
->parent
), node_type(node
));
854 return -EPERM
; /* Structure not allowed */
857 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
862 * First make sure we create the parent links for all children. Let's
863 * take the safe route and recreate them at each validation, just in
864 * case the structure has changed.
866 printf_verbose("CTF visitor: parent links creation... ");
867 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
870 printf_verbose("done.\n");
871 printf_verbose("CTF visitor: semantic check... ");
872 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
875 printf_verbose("done.\n");