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 printf_dbg(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_left
= 0;
46 switch (node
->parent
->type
) {
47 case NODE_CTF_EXPRESSION
:
48 cds_list_for_each_entry(iter
, &node
->parent
->u
.ctf_expression
.left
,
53 * We are a left child of a ctf expression.
54 * We are only allowed to be a string.
56 if (node
->u
.unary_expression
.type
!= UNARY_STRING
)
61 /* Right child of a ctf expression can be any type of unary exp. */
63 case NODE_TYPE_DECLARATOR
:
65 * We are the length of a type declarator. We can only be
68 switch (node
->u
.unary_expression
.type
) {
69 case UNARY_SIGNED_CONSTANT
:
70 case UNARY_UNSIGNED_CONSTANT
:
77 /* The enumerator parent has validated our validity already. */
80 case NODE_UNARY_EXPRESSION
:
82 * We disallow nested unary expressions and "sbrac" unary
92 case NODE_TYPEALIAS_TARGET
:
93 case NODE_TYPEALIAS_ALIAS
:
95 case NODE_TYPE_SPECIFIER
:
97 case NODE_FLOATING_POINT
:
101 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
108 switch (node
->u
.unary_expression
.link
) {
109 case UNARY_LINK_UNKNOWN
:
112 case UNARY_ARROWLINK
:
113 /* We only allow -> and . links between children of ctf_expression. */
114 if (node
->parent
->type
!= NODE_CTF_EXPRESSION
)
116 /* We don't allow link on the first node of the list */
117 if (_cds_list_first_entry(is_ctf_exp_left
?
118 &node
->parent
->u
.ctf_expression
.left
:
119 &node
->parent
->u
.ctf_expression
.right
,
124 case UNARY_DOTDOTDOT
:
125 /* We only allow ... link between children of enumerator. */
126 if (node
->parent
->type
!= NODE_ENUMERATOR
)
128 /* We don't allow link on the first node of the list */
129 if (_cds_list_first_entry(&node
->parent
->u
.enumerator
.values
,
135 fprintf(fd
, "[error] %s: unknown expression link type %d\n", __func__
,
136 (int) node
->u
.unary_expression
.link
);
142 fprintf(fd
, "[error] %s: incoherent parent type %d for node type %d\n", __func__
,
143 (int) node
->parent
->type
, (int) node
->type
);
144 return -EINVAL
; /* Incoherent structure */
147 return -EPERM
; /* Structure not allowed */
151 int ctf_visitor_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
153 switch (node
->parent
->type
) {
154 case NODE_CTF_EXPRESSION
:
155 case NODE_TYPE_DECLARATOR
:
157 case NODE_TYPEALIAS_TARGET
:
158 case NODE_TYPEALIAS_ALIAS
:
166 case NODE_UNARY_EXPRESSION
:
168 case NODE_TYPE_SPECIFIER
:
170 case NODE_FLOATING_POINT
:
173 case NODE_ENUMERATOR
:
174 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
182 fprintf(fd
, "[error] %s: incoherent parent type %d for node type %d\n", __func__
,
183 (int) node
->parent
->type
, (int) node
->type
);
184 return -EINVAL
; /* Incoherent structure */
188 int ctf_visitor_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
191 struct ctf_node
*iter
;
195 switch (node
->parent
->type
) {
196 case NODE_TYPE_DECLARATOR
:
198 * A nested type declarator is not allowed to contain pointers.
200 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
))
204 case NODE_TYPEALIAS_TARGET
:
205 case NODE_TYPEALIAS_ALIAS
:
206 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
213 case NODE_CTF_EXPRESSION
:
214 case NODE_UNARY_EXPRESSION
:
216 case NODE_TYPE_SPECIFIER
:
218 case NODE_FLOATING_POINT
:
221 case NODE_ENUMERATOR
:
229 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
230 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
232 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
238 switch (node
->u
.type_declarator
.type
) {
242 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
243 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
244 node
->u
.type_declarator
.u
.nested
.type_declarator
);
248 if (node
->u
.type_declarator
.u
.nested
.length
) {
249 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
250 node
->u
.type_declarator
.u
.nested
.length
);
254 if (node
->u
.type_declarator
.bitfield_len
) {
255 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1,
256 node
->u
.type_declarator
.bitfield_len
);
261 case TYPEDEC_UNKNOWN
:
263 fprintf(fd
, "[error] %s: unknown type declarator %d\n", __func__
,
264 (int) node
->u
.type_declarator
.type
);
271 fprintf(fd
, "[error] %s: incoherent parent type %d for node type %d\n", __func__
,
272 (int) node
->parent
->type
, (int) node
->type
);
273 return -EINVAL
; /* Incoherent structure */
276 return -EPERM
; /* Structure not allowed */
280 int _ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
283 struct ctf_node
*iter
;
285 switch (node
->type
) {
287 cds_list_for_each_entry(iter
, &node
->u
.root
._typedef
,
289 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
293 cds_list_for_each_entry(iter
, &node
->u
.root
.typealias
,
295 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
299 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_specifier
, siblings
) {
300 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
304 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
305 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
309 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
310 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
314 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
315 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
322 switch (node
->parent
->type
) {
329 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
330 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
336 switch (node
->parent
->type
) {
343 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
344 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
350 switch (node
->parent
->type
) {
357 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
358 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
364 case NODE_CTF_EXPRESSION
:
365 switch (node
->parent
->type
) {
370 case NODE_FLOATING_POINT
:
375 case NODE_CTF_EXPRESSION
:
376 case NODE_UNARY_EXPRESSION
:
378 case NODE_TYPEALIAS_TARGET
:
379 case NODE_TYPEALIAS_ALIAS
:
380 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
382 case NODE_TYPE_SPECIFIER
:
384 case NODE_TYPE_DECLARATOR
:
385 case NODE_ENUMERATOR
:
394 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
395 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
399 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
400 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
406 case NODE_UNARY_EXPRESSION
:
407 return ctf_visitor_unary_expression(fd
, depth
, node
);
410 switch (node
->parent
->type
) {
419 case NODE_CTF_EXPRESSION
:
420 case NODE_UNARY_EXPRESSION
:
422 case NODE_TYPEALIAS_TARGET
:
423 case NODE_TYPEALIAS_ALIAS
:
425 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
426 case NODE_TYPE_SPECIFIER
:
428 case NODE_TYPE_DECLARATOR
:
429 case NODE_FLOATING_POINT
:
432 case NODE_ENUMERATOR
:
439 cds_list_for_each_entry(iter
, &node
->u
._typedef
.declaration_specifier
, siblings
) {
440 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
444 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
445 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
451 case NODE_TYPEALIAS_TARGET
:
452 switch (node
->parent
->type
) {
460 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.declaration_specifier
, siblings
) {
461 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
465 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
466 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
472 case NODE_TYPEALIAS_ALIAS
:
473 switch (node
->parent
->type
) {
481 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.declaration_specifier
, siblings
) {
482 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
486 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
487 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
494 switch (node
->parent
->type
) {
503 case NODE_CTF_EXPRESSION
:
504 case NODE_UNARY_EXPRESSION
:
506 case NODE_TYPEALIAS_TARGET
:
507 case NODE_TYPEALIAS_ALIAS
:
509 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
510 case NODE_TYPE_SPECIFIER
:
512 case NODE_TYPE_DECLARATOR
:
513 case NODE_FLOATING_POINT
:
516 case NODE_ENUMERATOR
:
522 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.target
);
525 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
.typealias
.alias
);
530 case NODE_TYPE_SPECIFIER
:
531 ret
= ctf_visitor_type_specifier(fd
, depth
, node
);
536 switch (node
->parent
->type
) {
537 case NODE_TYPE_DECLARATOR
:
543 case NODE_TYPE_DECLARATOR
:
544 ret
= ctf_visitor_type_declarator(fd
, depth
, node
);
549 case NODE_FLOATING_POINT
:
550 switch (node
->parent
->type
) {
551 case NODE_CTF_EXPRESSION
:
553 case NODE_TYPEALIAS_TARGET
:
554 case NODE_TYPEALIAS_ALIAS
:
555 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
563 case NODE_TYPE_SPECIFIER
:
565 case NODE_TYPE_DECLARATOR
:
566 case NODE_FLOATING_POINT
:
569 case NODE_ENUMERATOR
:
576 case NODE_UNARY_EXPRESSION
:
579 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
580 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
586 switch (node
->parent
->type
) {
587 case NODE_CTF_EXPRESSION
:
588 case NODE_UNARY_EXPRESSION
:
590 case NODE_TYPEALIAS_TARGET
:
591 case NODE_TYPEALIAS_ALIAS
:
592 case NODE_TYPE_DECLARATOR
:
594 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
602 case NODE_TYPE_SPECIFIER
:
604 case NODE_FLOATING_POINT
:
607 case NODE_ENUMERATOR
:
615 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
616 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
622 switch (node
->parent
->type
) {
623 case NODE_CTF_EXPRESSION
:
625 case NODE_TYPEALIAS_TARGET
:
626 case NODE_TYPEALIAS_ALIAS
:
627 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
635 case NODE_TYPE_SPECIFIER
:
637 case NODE_TYPE_DECLARATOR
:
638 case NODE_FLOATING_POINT
:
641 case NODE_ENUMERATOR
:
648 case NODE_UNARY_EXPRESSION
:
652 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
653 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
658 case NODE_ENUMERATOR
:
659 switch (node
->parent
->type
) {
666 * Enumerators are only allows to contain:
667 * numeric unary expression
668 * or num. unary exp. ... num. unary exp
673 cds_list_for_each_entry(iter
, &node
->parent
->u
.enumerator
.values
,
676 case 0: if (iter
->type
!= NODE_UNARY_EXPRESSION
677 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
678 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
679 || iter
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
)
682 case 1: if (iter
->type
!= NODE_UNARY_EXPRESSION
683 || (iter
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
684 && iter
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
685 || iter
->u
.unary_expression
.link
!= UNARY_DOTDOTDOT
)
694 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
695 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
701 switch (node
->parent
->type
) {
706 case NODE_CTF_EXPRESSION
:
708 case NODE_TYPEALIAS_TARGET
:
709 case NODE_TYPEALIAS_ALIAS
:
710 case NODE_TYPE_DECLARATOR
:
711 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
715 case NODE_TYPE_SPECIFIER
:
717 case NODE_FLOATING_POINT
:
720 case NODE_ENUMERATOR
:
727 case NODE_UNARY_EXPRESSION
:
732 if (node
->u
._enum
.container_type
) {
733 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, node
->u
._enum
.container_type
);
738 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
739 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
745 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
746 switch (node
->parent
->type
) {
753 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.declaration_specifier
, siblings
) {
754 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
758 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
759 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
765 switch (node
->parent
->type
) {
770 case NODE_CTF_EXPRESSION
:
772 case NODE_TYPEALIAS_TARGET
:
773 case NODE_TYPEALIAS_ALIAS
:
774 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
778 case NODE_TYPE_SPECIFIER
:
780 case NODE_TYPE_DECLARATOR
:
781 case NODE_FLOATING_POINT
:
784 case NODE_ENUMERATOR
:
791 case NODE_UNARY_EXPRESSION
:
794 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
795 ret
= _ctf_visitor_semantic_check(fd
, depth
+ 1, iter
);
802 switch (node
->parent
->type
) {
807 case NODE_CTF_EXPRESSION
:
809 case NODE_TYPEALIAS_TARGET
:
810 case NODE_TYPEALIAS_ALIAS
:
811 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
815 case NODE_TYPE_SPECIFIER
:
817 case NODE_TYPE_DECLARATOR
:
818 case NODE_FLOATING_POINT
:
821 case NODE_ENUMERATOR
:
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 %d for node type %d\n", __func__
,
848 (int) node
->parent
->type
, (int) node
->type
);
849 return -EINVAL
; /* Incoherent structure */
852 return -EPERM
; /* Structure not allowed */
855 int ctf_visitor_semantic_check(FILE *fd
, int depth
, struct ctf_node
*node
)
860 * First make sure we create the parent links for all children. Let's
861 * take the safe route and recreate them at each validation, just in
862 * case the structure has changed.
864 ret
= ctf_visitor_parent_links(fd
, depth
, node
);
867 return _ctf_visitor_semantic_check(fd
, depth
, node
);