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_list(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
:
202 case NODE_TYPE_SPECIFIER_LIST
:
204 case NODE_FLOATING_POINT
:
207 case NODE_ENUMERATOR
:
215 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
216 node_type(node
->parent
), node_type(node
));
217 return -EINVAL
; /* Incoherent structure */
221 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
223 switch (node
->parent
->type
) {
224 case NODE_TYPE_SPECIFIER_LIST
:
227 case NODE_CTF_EXPRESSION
:
228 case NODE_TYPE_DECLARATOR
:
230 case NODE_TYPEALIAS_TARGET
:
231 case NODE_TYPEALIAS_ALIAS
:
233 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
238 case NODE_UNARY_EXPRESSION
:
240 case NODE_TYPE_SPECIFIER
:
242 case NODE_FLOATING_POINT
:
245 case NODE_ENUMERATOR
:
253 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
254 node_type(node
->parent
), node_type(node
));
255 return -EINVAL
; /* Incoherent structure */
259 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
262 struct ctf_node
*iter
;
266 switch (node
->parent
->type
) {
267 case NODE_TYPE_DECLARATOR
:
269 * A nested type declarator is not allowed to contain pointers.
271 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
274 case NODE_TYPEALIAS_TARGET
:
276 case NODE_TYPEALIAS_ALIAS
:
278 * Only accept alias name containing:
280 * - identifier * (any number of pointers)
281 * NOT accepting alias names containing [] (would otherwise
282 * cause semantic clash for later declarations of
283 * arrays/sequences of elements, where elements could be
284 * arrays/sequences themselves (if allowed in typealias).
285 * NOT accepting alias with identifier. The declarator should
286 * be either empty or contain pointer(s).
288 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
290 switch (node
->u
.type_declarator
.type
) {
291 case TYPESPEC_FLOATING_POINT
:
292 case TYPESPEC_INTEGER
:
293 case TYPESPEC_STRING
:
294 case TYPESPEC_STRUCT
:
295 case TYPESPEC_VARIANT
:
297 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
303 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
304 node
->u
.type_declarator
.u
.id
!= NULL
)
308 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
315 case NODE_CTF_EXPRESSION
:
316 case NODE_UNARY_EXPRESSION
:
318 case NODE_TYPE_SPECIFIER
:
320 case NODE_FLOATING_POINT
:
323 case NODE_ENUMERATOR
:
331 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
332 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
334 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
340 switch (node
->u
.type_declarator
.type
) {
345 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
346 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
347 node
->u
.type_declarator
.u
.nested
.type_declarator
);
351 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
352 node
->u
.type_declarator
.u
.nested
.length
);
355 if (node
->u
.type_declarator
.bitfield_len
) {
356 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
357 node
->u
.type_declarator
.bitfield_len
);
363 case TYPEDEC_UNKNOWN
:
365 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
366 (int) node
->u
.type_declarator
.type
);
373 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
374 node_type(node
->parent
), node_type(node
));
375 return -EINVAL
; /* Incoherent structure */
378 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
379 node_type(node
->parent
), node_type(node
));
380 return -EPERM
; /* Structure not allowed */
384 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
387 struct ctf_node
*iter
;
389 switch (node
->type
) {
391 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
392 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
396 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
397 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
401 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
402 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
406 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
407 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
414 switch (node
->parent
->type
) {
421 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
422 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
428 switch (node
->parent
->type
) {
435 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
436 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
442 switch (node
->parent
->type
) {
449 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
450 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
456 case NODE_CTF_EXPRESSION
:
457 switch (node
->parent
->type
) {
462 case NODE_FLOATING_POINT
:
467 case NODE_CTF_EXPRESSION
:
468 case NODE_UNARY_EXPRESSION
:
470 case NODE_TYPEALIAS_TARGET
:
471 case NODE_TYPEALIAS_ALIAS
:
472 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
474 case NODE_TYPE_SPECIFIER
:
475 case NODE_TYPE_SPECIFIER_LIST
:
477 case NODE_TYPE_DECLARATOR
:
478 case NODE_ENUMERATOR
:
487 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
488 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
492 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
493 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
499 case NODE_UNARY_EXPRESSION
:
500 return ctf_visitor_unary_expression(fd
, depth
, node
);
503 switch (node
->parent
->type
) {
512 case NODE_CTF_EXPRESSION
:
513 case NODE_UNARY_EXPRESSION
:
515 case NODE_TYPEALIAS_TARGET
:
516 case NODE_TYPEALIAS_ALIAS
:
518 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
519 case NODE_TYPE_SPECIFIER
:
520 case NODE_TYPE_SPECIFIER_LIST
:
522 case NODE_TYPE_DECLARATOR
:
523 case NODE_FLOATING_POINT
:
526 case NODE_ENUMERATOR
:
533 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
534 node
->u
._typedef
.type_specifier_list
);
537 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
538 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
544 case NODE_TYPEALIAS_TARGET
:
548 switch (node
->parent
->type
) {
556 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
557 node
->u
.typealias_target
.type_specifier_list
);
561 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
562 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
567 if (nr_declarators
> 1) {
568 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
575 case NODE_TYPEALIAS_ALIAS
:
579 switch (node
->parent
->type
) {
587 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
588 node
->u
.typealias_alias
.type_specifier_list
);
592 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
593 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
598 if (nr_declarators
> 1) {
599 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
607 switch (node
->parent
->type
) {
616 case NODE_CTF_EXPRESSION
:
617 case NODE_UNARY_EXPRESSION
:
619 case NODE_TYPEALIAS_TARGET
:
620 case NODE_TYPEALIAS_ALIAS
:
622 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
623 case NODE_TYPE_SPECIFIER
:
624 case NODE_TYPE_SPECIFIER_LIST
:
626 case NODE_TYPE_DECLARATOR
:
627 case NODE_FLOATING_POINT
:
630 case NODE_ENUMERATOR
:
636 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
639 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
644 case NODE_TYPE_SPECIFIER_LIST
:
645 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
649 case NODE_TYPE_SPECIFIER
:
650 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
655 switch (node
->parent
->type
) {
656 case NODE_TYPE_DECLARATOR
:
662 case NODE_TYPE_DECLARATOR
:
663 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
668 case NODE_FLOATING_POINT
:
669 switch (node
->parent
->type
) {
670 case NODE_TYPE_SPECIFIER
:
675 case NODE_UNARY_EXPRESSION
:
678 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
679 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
685 switch (node
->parent
->type
) {
686 case NODE_TYPE_SPECIFIER
:
693 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
694 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
700 switch (node
->parent
->type
) {
701 case NODE_TYPE_SPECIFIER
:
706 case NODE_UNARY_EXPRESSION
:
710 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
711 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
716 case NODE_ENUMERATOR
:
717 switch (node
->parent
->type
) {
724 * Enumerators are only allows to contain:
725 * numeric unary expression
726 * or num. unary exp. ... num. unary exp
731 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
734 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
735 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
736 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
737 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
738 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
742 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
743 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
744 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
745 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
746 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
756 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
757 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
763 switch (node
->parent
->type
) {
764 case NODE_TYPE_SPECIFIER
:
769 case NODE_UNARY_EXPRESSION
:
774 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
778 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
779 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
785 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
786 switch (node
->parent
->type
) {
793 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
794 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
797 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
798 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
804 switch (node
->parent
->type
) {
805 case NODE_TYPE_SPECIFIER
:
810 case NODE_UNARY_EXPRESSION
:
813 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
814 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
821 switch (node
->parent
->type
) {
822 case NODE_TYPE_SPECIFIER
:
827 case NODE_UNARY_EXPRESSION
:
830 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
831 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
839 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
846 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
847 node_type(node
->parent
), node_type(node
));
848 return -EINVAL
; /* Incoherent structure */
851 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
852 node_type(node
->parent
), node_type(node
));
853 return -EPERM
; /* Structure not allowed */
856 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
861 * First make sure we create the parent links for all children. Let's
862 * take the safe route and recreate them at each validation, just in
863 * case the structure has changed.
865 fprintf(fd
, "CTF visitor: parent links creation... ");
866 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
869 fprintf(fd
, "done.\n");
870 fprintf(fd
, "CTF visitor: semantic check... ");
871 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
874 fprintf(fd
, "done.\n");