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 _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");
113 case NODE_TYPEALIAS_TARGET
:
114 case NODE_TYPEALIAS_ALIAS
:
116 case NODE_TYPE_SPECIFIER
:
118 case NODE_FLOATING_POINT
:
122 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
128 switch (node
->u
.unary_expression
.link
) {
129 case UNARY_LINK_UNKNOWN
:
130 /* We don't allow empty link except on the first node of the list */
131 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
132 &node
->parent
->u
.ctf_expression
.left
:
133 &node
->parent
->u
.ctf_expression
.right
,
136 fprintf(fd
, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
141 case UNARY_ARROWLINK
:
142 /* We only allow -> and . links between children of ctf_expression. */
143 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
) {
144 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
148 * Only strings can be separated linked by . or ->.
149 * This includes "", '' and non-quoted identifiers.
151 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
152 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
155 /* We don't allow link on the first node of the list */
156 if (is_ctf_exp
&& _cds_list_first_entry(is_ctf_exp_left
?
157 &node
->parent
->u
.ctf_expression
.left
:
158 &node
->parent
->u
.ctf_expression
.right
,
161 fprintf(fd
, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
165 case UNARY_DOTDOTDOT
:
166 /* We only allow ... link between children of enumerator. */
167 if (node
->parent
->type
!= NODE_ENUMERATOR
) {
168 fprintf(fd
, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
171 /* We don't allow link on the first node of the list */
172 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
175 fprintf(fd
, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
180 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
181 (int) node
->u
.unary_expression
.link
);
187 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
188 node_type(node
->parent
), node_type(node
));
189 return -EINVAL
; /* Incoherent structure */
192 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
193 node_type(node
->parent
), node_type(node
));
194 return -EPERM
; /* Structure not allowed */
198 int ctf_visitor_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
200 switch (node
->parent
->type
) {
201 case NODE_CTF_EXPRESSION
:
202 case NODE_TYPE_DECLARATOR
:
204 case NODE_TYPEALIAS_TARGET
:
205 case NODE_TYPEALIAS_ALIAS
:
207 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
215 case NODE_UNARY_EXPRESSION
:
217 case NODE_TYPE_SPECIFIER
:
218 case NODE_TYPE_SPECIFIER_LIST
:
220 case NODE_FLOATING_POINT
:
223 case NODE_ENUMERATOR
:
231 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
232 node_type(node
->parent
), node_type(node
));
233 return -EINVAL
; /* Incoherent structure */
237 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
239 switch (node
->parent
->type
) {
240 case NODE_TYPE_SPECIFIER_LIST
:
243 case NODE_CTF_EXPRESSION
:
244 case NODE_TYPE_DECLARATOR
:
246 case NODE_TYPEALIAS_TARGET
:
247 case NODE_TYPEALIAS_ALIAS
:
249 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
255 case NODE_UNARY_EXPRESSION
:
257 case NODE_TYPE_SPECIFIER
:
259 case NODE_FLOATING_POINT
:
262 case NODE_ENUMERATOR
:
270 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
271 node_type(node
->parent
), node_type(node
));
272 return -EINVAL
; /* Incoherent structure */
276 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
279 struct ctf_node
*iter
;
283 switch (node
->parent
->type
) {
284 case NODE_TYPE_DECLARATOR
:
286 * A nested type declarator is not allowed to contain pointers.
288 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
291 case NODE_TYPEALIAS_TARGET
:
293 case NODE_TYPEALIAS_ALIAS
:
295 * Only accept alias name containing:
297 * - identifier * (any number of pointers)
298 * NOT accepting alias names containing [] (would otherwise
299 * cause semantic clash for later declarations of
300 * arrays/sequences of elements, where elements could be
301 * arrays/sequences themselves (if allowed in typealias).
302 * NOT accepting alias with identifier. The declarator should
303 * be either empty or contain pointer(s).
305 if (node
->u
.type_declarator
.type
== TYPEDEC_NESTED
)
307 cds_list_for_each_entry(iter
, &node
->parent
->u
.typealias_alias
.type_specifier_list
->u
.type_specifier_list
.head
,
309 switch (iter
->u
.type_specifier
.type
) {
310 case TYPESPEC_FLOATING_POINT
:
311 case TYPESPEC_INTEGER
:
312 case TYPESPEC_STRING
:
313 case TYPESPEC_STRUCT
:
314 case TYPESPEC_VARIANT
:
316 if (cds_list_empty(&node
->u
.type_declarator
.pointers
))
323 if (node
->u
.type_declarator
.type
== TYPEDEC_ID
&&
324 node
->u
.type_declarator
.u
.id
!= NULL
)
328 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
336 case NODE_CTF_EXPRESSION
:
337 case NODE_UNARY_EXPRESSION
:
339 case NODE_TYPE_SPECIFIER
:
341 case NODE_FLOATING_POINT
:
344 case NODE_ENUMERATOR
:
352 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
354 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
359 switch (node
->u
.type_declarator
.type
) {
364 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
365 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
366 node
->u
.type_declarator
.u
.nested
.type_declarator
);
370 if (!node
->u
.type_declarator
.u
.nested
.abstract_array
) {
371 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
373 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
374 fprintf(fd
, "[error] %s: expecting unary expression as length\n", __func__
);
377 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
382 if (node
->parent
->type
== NODE_TYPEALIAS_TARGET
) {
383 fprintf(fd
, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__
);
387 if (node
->u
.type_declarator
.bitfield_len
) {
388 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
389 node
->u
.type_declarator
.bitfield_len
);
395 case TYPEDEC_UNKNOWN
:
397 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
398 (int) node
->u
.type_declarator
.type
);
405 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
406 node_type(node
->parent
), node_type(node
));
407 return -EINVAL
; /* Incoherent structure */
410 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
411 node_type(node
->parent
), node_type(node
));
412 return -EPERM
; /* Structure not allowed */
416 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
419 struct ctf_node
*iter
;
421 switch (node
->type
) {
423 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
, siblings
) {
424 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
428 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
429 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
433 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
434 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
438 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
439 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
446 switch (node
->parent
->type
) {
453 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
454 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
460 switch (node
->parent
->type
) {
467 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
468 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
474 switch (node
->parent
->type
) {
481 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
482 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
488 switch (node
->parent
->type
) {
495 cds_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
496 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
503 case NODE_CTF_EXPRESSION
:
504 switch (node
->parent
->type
) {
510 case NODE_FLOATING_POINT
:
515 case NODE_CTF_EXPRESSION
:
516 case NODE_UNARY_EXPRESSION
:
518 case NODE_TYPEALIAS_TARGET
:
519 case NODE_TYPEALIAS_ALIAS
:
520 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
522 case NODE_TYPE_SPECIFIER
:
523 case NODE_TYPE_SPECIFIER_LIST
:
525 case NODE_TYPE_DECLARATOR
:
526 case NODE_ENUMERATOR
:
535 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
536 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
540 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
541 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
547 case NODE_UNARY_EXPRESSION
:
548 return ctf_visitor_unary_expression(fd
, depth
, node
);
551 switch (node
->parent
->type
) {
560 case NODE_CTF_EXPRESSION
:
561 case NODE_UNARY_EXPRESSION
:
563 case NODE_TYPEALIAS_TARGET
:
564 case NODE_TYPEALIAS_ALIAS
:
566 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_FLOATING_POINT
:
574 case NODE_ENUMERATOR
:
582 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
583 node
->u
._typedef
.type_specifier_list
);
586 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
587 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
593 case NODE_TYPEALIAS_TARGET
:
597 switch (node
->parent
->type
) {
605 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
606 node
->u
.typealias_target
.type_specifier_list
);
610 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
611 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
616 if (nr_declarators
> 1) {
617 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
624 case NODE_TYPEALIAS_ALIAS
:
628 switch (node
->parent
->type
) {
636 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
637 node
->u
.typealias_alias
.type_specifier_list
);
641 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
642 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
647 if (nr_declarators
> 1) {
648 fprintf(fd
, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__
, nr_declarators
);
656 switch (node
->parent
->type
) {
665 case NODE_CTF_EXPRESSION
:
666 case NODE_UNARY_EXPRESSION
:
668 case NODE_TYPEALIAS_TARGET
:
669 case NODE_TYPEALIAS_ALIAS
:
671 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
672 case NODE_TYPE_SPECIFIER
:
673 case NODE_TYPE_SPECIFIER_LIST
:
675 case NODE_TYPE_DECLARATOR
:
676 case NODE_FLOATING_POINT
:
679 case NODE_ENUMERATOR
:
686 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
689 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
694 case NODE_TYPE_SPECIFIER_LIST
:
695 ret
= ctf_visitor_type_specifier_list(fd
, depth
, node
);
699 case NODE_TYPE_SPECIFIER
:
700 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
705 switch (node
->parent
->type
) {
706 case NODE_TYPE_DECLARATOR
:
712 case NODE_TYPE_DECLARATOR
:
713 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
718 case NODE_FLOATING_POINT
:
719 switch (node
->parent
->type
) {
720 case NODE_TYPE_SPECIFIER
:
725 case NODE_UNARY_EXPRESSION
:
728 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
729 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
735 switch (node
->parent
->type
) {
736 case NODE_TYPE_SPECIFIER
:
743 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
744 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
750 switch (node
->parent
->type
) {
751 case NODE_TYPE_SPECIFIER
:
756 case NODE_UNARY_EXPRESSION
:
760 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
761 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
766 case NODE_ENUMERATOR
:
767 switch (node
->parent
->type
) {
774 * Enumerators are only allows to contain:
775 * numeric unary expression
776 * or num. unary exp. ... num. unary exp
781 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
,
784 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
785 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
786 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
787 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
) {
788 fprintf(fd
, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
792 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
793 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
794 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
795 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
) {
796 fprintf(fd
, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
806 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
807 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
813 switch (node
->parent
->type
) {
814 case NODE_TYPE_SPECIFIER
:
819 case NODE_UNARY_EXPRESSION
:
824 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
828 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
829 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
835 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
836 switch (node
->parent
->type
) {
843 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
844 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
847 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, 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
:
863 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
864 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
871 switch (node
->parent
->type
) {
872 case NODE_TYPE_SPECIFIER
:
877 case NODE_UNARY_EXPRESSION
:
880 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
881 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
889 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
896 fprintf(fd
, "[error] %s: incoherent parent type %s for node type %s\n", __func__
,
897 node_type(node
->parent
), node_type(node
));
898 return -EINVAL
; /* Incoherent structure */
901 fprintf(fd
, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__
,
902 node_type(node
->parent
), node_type(node
));
903 return -EPERM
; /* Structure not allowed */
906 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
911 * First make sure we create the parent links for all children. Let's
912 * take the safe route and recreate them at each validation, just in
913 * case the structure has changed.
915 printf_verbose("CTF visitor: parent links creation... ");
916 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
919 printf_verbose("done.\n");
920 printf_verbose("CTF visitor: semantic check... ");
921 ret
= _ctf_visitor_semantic_check(fd
, depth
, node
);
924 printf_verbose("done.\n");