Move `src/plugins/comp-logging.h` -> `src/logging/comp-logging.h`
[babeltrace.git] / src / plugins / ctf / common / metadata / visitor-semantic-validator.c
1 /*
2 * ctf-visitor-semantic-validator.c
3 *
4 * Common Trace Format Metadata Semantic Validator.
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp)
28 #define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level)
29 #define BT_LOG_TAG "PLUGIN/CTF/META/SEMANTIC-VALIDATOR-VISITOR"
30 #include "logging/comp-logging.h"
31
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include "common/assert.h"
37 #include <glib.h>
38 #include <inttypes.h>
39 #include <errno.h>
40 #include "common/list.h"
41 #include "scanner.h"
42 #include "parser.h"
43 #include "ast.h"
44 #include "logging.h"
45
46 #define _bt_list_first_entry(ptr, type, member) \
47 bt_list_entry((ptr)->next, type, member)
48
49 static
50 int _ctf_visitor_semantic_check(int depth, struct ctf_node *node,
51 struct meta_log_config *log_cfg);
52
53 static
54 int ctf_visitor_unary_expression(int depth, struct ctf_node *node,
55 struct meta_log_config *log_cfg)
56 {
57 struct ctf_node *iter;
58 int is_ctf_exp = 0, is_ctf_exp_left = 0;
59
60 switch (node->parent->type) {
61 case NODE_CTF_EXPRESSION:
62 is_ctf_exp = 1;
63 bt_list_for_each_entry(iter, &node->parent->u.ctf_expression.left,
64 siblings) {
65 if (iter == node) {
66 is_ctf_exp_left = 1;
67 /*
68 * We are a left child of a ctf expression.
69 * We are only allowed to be a string.
70 */
71 if (node->u.unary_expression.type != UNARY_STRING) {
72 _BT_COMP_LOGE_LINENO(node->lineno,
73 "Left child of a CTF expression is only allowed to be a string.");
74 goto errperm;
75 }
76 break;
77 }
78 }
79 /* Right child of a ctf expression can be any type of unary exp. */
80 break; /* OK */
81 case NODE_TYPE_DECLARATOR:
82 /*
83 * We are the length of a type declarator.
84 */
85 switch (node->u.unary_expression.type) {
86 case UNARY_UNSIGNED_CONSTANT:
87 case UNARY_STRING:
88 break;
89 default:
90 _BT_COMP_LOGE_LINENO(node->lineno,
91 "Children of field class declarator and `enum` can only be unsigned numeric constants or references to fields (e.g., `a.b.c`).");
92 goto errperm;
93 }
94 break; /* OK */
95
96 case NODE_STRUCT:
97 /*
98 * We are the size of a struct align attribute.
99 */
100 switch (node->u.unary_expression.type) {
101 case UNARY_UNSIGNED_CONSTANT:
102 break;
103 default:
104 _BT_COMP_LOGE_LINENO(node->lineno,
105 "Structure alignment attribute can only be an unsigned numeric constant.");
106 goto errperm;
107 }
108 break;
109
110 case NODE_ENUMERATOR:
111 /* The enumerator's parent has validated its validity already. */
112 break; /* OK */
113
114 case NODE_UNARY_EXPRESSION:
115 /*
116 * We disallow nested unary expressions and "sbrac" unary
117 * expressions.
118 */
119 _BT_COMP_LOGE_LINENO(node->lineno,
120 "Nested unary expressions not allowed (`()` and `[]`).");
121 goto errperm;
122
123 case NODE_ROOT:
124 case NODE_EVENT:
125 case NODE_STREAM:
126 case NODE_ENV:
127 case NODE_TRACE:
128 case NODE_CLOCK:
129 case NODE_CALLSITE:
130 case NODE_TYPEDEF:
131 case NODE_TYPEALIAS_TARGET:
132 case NODE_TYPEALIAS_ALIAS:
133 case NODE_TYPEALIAS:
134 case NODE_TYPE_SPECIFIER:
135 case NODE_POINTER:
136 case NODE_FLOATING_POINT:
137 case NODE_INTEGER:
138 case NODE_STRING:
139 case NODE_ENUM:
140 case NODE_STRUCT_OR_VARIANT_DECLARATION:
141 case NODE_VARIANT:
142 default:
143 goto errinval;
144 }
145
146 switch (node->u.unary_expression.link) {
147 case UNARY_LINK_UNKNOWN:
148 /* We don't allow empty link except on the first node of the list */
149 if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ?
150 &node->parent->u.ctf_expression.left :
151 &node->parent->u.ctf_expression.right,
152 struct ctf_node,
153 siblings) != node) {
154 _BT_COMP_LOGE_LINENO(node->lineno,
155 "Empty link is not allowed except on first node of unary expression (need to separate nodes with `.` or `->`).");
156 goto errperm;
157 }
158 break; /* OK */
159 case UNARY_DOTLINK:
160 case UNARY_ARROWLINK:
161 /* We only allow -> and . links between children of ctf_expression. */
162 if (node->parent->type != NODE_CTF_EXPRESSION) {
163 _BT_COMP_LOGE_LINENO(node->lineno,
164 "Links `.` and `->` are only allowed as children of CTF expression.");
165 goto errperm;
166 }
167 /*
168 * Only strings can be separated linked by . or ->.
169 * This includes "", '' and non-quoted identifiers.
170 */
171 if (node->u.unary_expression.type != UNARY_STRING) {
172 _BT_COMP_LOGE_LINENO(node->lineno,
173 "Links `.` and `->` are only allowed to separate strings and identifiers.");
174 goto errperm;
175 }
176 /* We don't allow link on the first node of the list */
177 if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ?
178 &node->parent->u.ctf_expression.left :
179 &node->parent->u.ctf_expression.right,
180 struct ctf_node,
181 siblings) == node) {
182 _BT_COMP_LOGE_LINENO(node->lineno,
183 "Links `.` and `->` are not allowed before first node of the unary expression list.");
184 goto errperm;
185 }
186 break;
187 case UNARY_DOTDOTDOT:
188 /* We only allow ... link between children of enumerator. */
189 if (node->parent->type != NODE_ENUMERATOR) {
190 _BT_COMP_LOGE_LINENO(node->lineno,
191 "Link `...` is only allowed within enumerator.");
192 goto errperm;
193 }
194 /* We don't allow link on the first node of the list */
195 if (_bt_list_first_entry(&node->parent->u.enumerator.values,
196 struct ctf_node,
197 siblings) == node) {
198 _BT_COMP_LOGE_LINENO(node->lineno,
199 "Link `...` is not allowed on the first node of the unary expression list.");
200 goto errperm;
201 }
202 break;
203 default:
204 _BT_COMP_LOGE_LINENO(node->lineno,
205 "Unknown expression link type: type=%d",
206 node->u.unary_expression.link);
207 return -EINVAL;
208 }
209 return 0;
210
211 errinval:
212 _BT_COMP_LOGE_LINENO(node->lineno,
213 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
214 node_type(node), node_type(node->parent));
215 return -EINVAL; /* Incoherent structure */
216
217 errperm:
218 _BT_COMP_LOGE_LINENO(node->lineno,
219 "Semantic error: node-type=%s, parent-node-type=%s",
220 node_type(node), node_type(node->parent));
221 return -EPERM; /* Structure not allowed */
222 }
223
224 static
225 int ctf_visitor_field_class_specifier_list(int depth, struct ctf_node *node,
226 struct meta_log_config *log_cfg)
227 {
228 switch (node->parent->type) {
229 case NODE_CTF_EXPRESSION:
230 case NODE_TYPE_DECLARATOR:
231 case NODE_TYPEDEF:
232 case NODE_TYPEALIAS_TARGET:
233 case NODE_TYPEALIAS_ALIAS:
234 case NODE_ENUM:
235 case NODE_STRUCT_OR_VARIANT_DECLARATION:
236 case NODE_ROOT:
237 break; /* OK */
238
239 case NODE_EVENT:
240 case NODE_STREAM:
241 case NODE_ENV:
242 case NODE_TRACE:
243 case NODE_CLOCK:
244 case NODE_CALLSITE:
245 case NODE_UNARY_EXPRESSION:
246 case NODE_TYPEALIAS:
247 case NODE_TYPE_SPECIFIER:
248 case NODE_TYPE_SPECIFIER_LIST:
249 case NODE_POINTER:
250 case NODE_FLOATING_POINT:
251 case NODE_INTEGER:
252 case NODE_STRING:
253 case NODE_ENUMERATOR:
254 case NODE_VARIANT:
255 case NODE_STRUCT:
256 default:
257 goto errinval;
258 }
259 return 0;
260 errinval:
261 _BT_COMP_LOGE_LINENO(node->lineno,
262 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
263 node_type(node), node_type(node->parent));
264 return -EINVAL; /* Incoherent structure */
265 }
266
267 static
268 int ctf_visitor_field_class_specifier(int depth, struct ctf_node *node,
269 struct meta_log_config *log_cfg)
270 {
271 switch (node->parent->type) {
272 case NODE_TYPE_SPECIFIER_LIST:
273 break; /* OK */
274
275 case NODE_CTF_EXPRESSION:
276 case NODE_TYPE_DECLARATOR:
277 case NODE_TYPEDEF:
278 case NODE_TYPEALIAS_TARGET:
279 case NODE_TYPEALIAS_ALIAS:
280 case NODE_ENUM:
281 case NODE_STRUCT_OR_VARIANT_DECLARATION:
282 case NODE_ROOT:
283 case NODE_EVENT:
284 case NODE_STREAM:
285 case NODE_ENV:
286 case NODE_TRACE:
287 case NODE_CLOCK:
288 case NODE_CALLSITE:
289 case NODE_UNARY_EXPRESSION:
290 case NODE_TYPEALIAS:
291 case NODE_TYPE_SPECIFIER:
292 case NODE_POINTER:
293 case NODE_FLOATING_POINT:
294 case NODE_INTEGER:
295 case NODE_STRING:
296 case NODE_ENUMERATOR:
297 case NODE_VARIANT:
298 case NODE_STRUCT:
299 default:
300 goto errinval;
301 }
302 return 0;
303 errinval:
304 _BT_COMP_LOGE_LINENO(node->lineno,
305 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
306 node_type(node), node_type(node->parent));
307 return -EINVAL; /* Incoherent structure */
308 }
309
310 static
311 int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node,
312 struct meta_log_config *log_cfg)
313 {
314 int ret = 0;
315 struct ctf_node *iter;
316
317 depth++;
318
319 switch (node->parent->type) {
320 case NODE_TYPE_DECLARATOR:
321 /*
322 * A nested field class declarator is not allowed to
323 * contain pointers.
324 */
325 if (!bt_list_empty(&node->u.field_class_declarator.pointers))
326 goto errperm;
327 break; /* OK */
328 case NODE_TYPEALIAS_TARGET:
329 break; /* OK */
330 case NODE_TYPEALIAS_ALIAS:
331 /*
332 * Only accept alias name containing:
333 * - identifier
334 * - identifier * (any number of pointers)
335 * NOT accepting alias names containing [] (would otherwise
336 * cause semantic clash for later declarations of
337 * arrays/sequences of elements, where elements could be
338 * arrays/sequences themselves (if allowed in field class alias).
339 * NOT accepting alias with identifier. The declarator should
340 * be either empty or contain pointer(s).
341 */
342 if (node->u.field_class_declarator.type == TYPEDEC_NESTED)
343 goto errperm;
344 bt_list_for_each_entry(iter, &node->parent->u.field_class_alias_name.field_class_specifier_list->u.field_class_specifier_list.head,
345 siblings) {
346 switch (iter->u.field_class_specifier.type) {
347 case TYPESPEC_FLOATING_POINT:
348 case TYPESPEC_INTEGER:
349 case TYPESPEC_STRING:
350 case TYPESPEC_STRUCT:
351 case TYPESPEC_VARIANT:
352 case TYPESPEC_ENUM:
353 if (bt_list_empty(&node->u.field_class_declarator.pointers))
354 goto errperm;
355 break;
356 default:
357 break;
358 }
359 }
360 if (node->u.field_class_declarator.type == TYPEDEC_ID &&
361 node->u.field_class_declarator.u.id)
362 goto errperm;
363 break; /* OK */
364 case NODE_TYPEDEF:
365 case NODE_STRUCT_OR_VARIANT_DECLARATION:
366 break; /* OK */
367
368 case NODE_ROOT:
369 case NODE_EVENT:
370 case NODE_STREAM:
371 case NODE_ENV:
372 case NODE_TRACE:
373 case NODE_CLOCK:
374 case NODE_CALLSITE:
375 case NODE_CTF_EXPRESSION:
376 case NODE_UNARY_EXPRESSION:
377 case NODE_TYPEALIAS:
378 case NODE_TYPE_SPECIFIER:
379 case NODE_POINTER:
380 case NODE_FLOATING_POINT:
381 case NODE_INTEGER:
382 case NODE_STRING:
383 case NODE_ENUMERATOR:
384 case NODE_ENUM:
385 case NODE_VARIANT:
386 case NODE_STRUCT:
387 default:
388 goto errinval;
389 }
390
391 bt_list_for_each_entry(iter, &node->u.field_class_declarator.pointers,
392 siblings) {
393 ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg);
394 if (ret)
395 return ret;
396 }
397
398 switch (node->u.field_class_declarator.type) {
399 case TYPEDEC_ID:
400 break;
401 case TYPEDEC_NESTED:
402 {
403 if (node->u.field_class_declarator.u.nested.field_class_declarator) {
404 ret = _ctf_visitor_semantic_check(depth + 1,
405 node->u.field_class_declarator.u.nested.field_class_declarator,
406 log_cfg);
407 if (ret)
408 return ret;
409 }
410 if (!node->u.field_class_declarator.u.nested.abstract_array) {
411 bt_list_for_each_entry(iter, &node->u.field_class_declarator.u.nested.length,
412 siblings) {
413 if (iter->type != NODE_UNARY_EXPRESSION) {
414 _BT_COMP_LOGE_LINENO(node->lineno,
415 "Expecting unary expression as length: node-type=%s",
416 node_type(iter));
417 return -EINVAL;
418 }
419 ret = _ctf_visitor_semantic_check(depth + 1,
420 iter, log_cfg);
421 if (ret)
422 return ret;
423 }
424 } else {
425 if (node->parent->type == NODE_TYPEALIAS_TARGET) {
426 _BT_COMP_LOGE_LINENO(node->lineno,
427 "Abstract array declarator not permitted as target of field class alias.");
428 return -EINVAL;
429 }
430 }
431 if (node->u.field_class_declarator.bitfield_len) {
432 ret = _ctf_visitor_semantic_check(depth + 1,
433 node->u.field_class_declarator.bitfield_len,
434 log_cfg);
435 if (ret)
436 return ret;
437 }
438 break;
439 }
440 case TYPEDEC_UNKNOWN:
441 default:
442 _BT_COMP_LOGE_LINENO(node->lineno,
443 "Unknown field class declarator: type=%d",
444 node->u.field_class_declarator.type);
445 return -EINVAL;
446 }
447 depth--;
448 return 0;
449
450 errinval:
451 _BT_COMP_LOGE_LINENO(node->lineno,
452 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
453 node_type(node), node_type(node->parent));
454 return -EINVAL; /* Incoherent structure */
455
456 errperm:
457 _BT_COMP_LOGE_LINENO(node->lineno,
458 "Semantic error: node-type=%s, parent-node-type=%s",
459 node_type(node), node_type(node->parent));
460 return -EPERM; /* Structure not allowed */
461 }
462
463 static
464 int _ctf_visitor_semantic_check(int depth, struct ctf_node *node,
465 struct meta_log_config *log_cfg)
466 {
467 int ret = 0;
468 struct ctf_node *iter;
469
470 if (node->visited)
471 return 0;
472
473 switch (node->type) {
474 case NODE_ROOT:
475 bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) {
476 ret = _ctf_visitor_semantic_check(depth + 1, iter,
477 log_cfg);
478 if (ret)
479 return ret;
480 }
481 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
482 ret = _ctf_visitor_semantic_check(depth + 1, iter,
483 log_cfg);
484 if (ret)
485 return ret;
486 }
487 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
488 ret = _ctf_visitor_semantic_check(depth + 1, iter,
489 log_cfg);
490 if (ret)
491 return ret;
492 }
493 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
494 ret = _ctf_visitor_semantic_check(depth + 1, iter,
495 log_cfg);
496 if (ret)
497 return ret;
498 }
499 break;
500
501 case NODE_EVENT:
502 switch (node->parent->type) {
503 case NODE_ROOT:
504 break; /* OK */
505 default:
506 goto errinval;
507 }
508
509 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
510 ret = _ctf_visitor_semantic_check(depth + 1, iter,
511 log_cfg);
512 if (ret)
513 return ret;
514 }
515 break;
516 case NODE_STREAM:
517 switch (node->parent->type) {
518 case NODE_ROOT:
519 break; /* OK */
520 default:
521 goto errinval;
522 }
523
524 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
525 ret = _ctf_visitor_semantic_check(depth + 1, iter,
526 log_cfg);
527 if (ret)
528 return ret;
529 }
530 break;
531 case NODE_ENV:
532 switch (node->parent->type) {
533 case NODE_ROOT:
534 break; /* OK */
535 default:
536 goto errinval;
537 }
538
539 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
540 ret = _ctf_visitor_semantic_check(depth + 1, iter,
541 log_cfg);
542 if (ret)
543 return ret;
544 }
545 break;
546 case NODE_TRACE:
547 switch (node->parent->type) {
548 case NODE_ROOT:
549 break; /* OK */
550 default:
551 goto errinval;
552 }
553
554 bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
555 ret = _ctf_visitor_semantic_check(depth + 1, iter,
556 log_cfg);
557 if (ret)
558 return ret;
559 }
560 break;
561 case NODE_CLOCK:
562 switch (node->parent->type) {
563 case NODE_ROOT:
564 break; /* OK */
565 default:
566 goto errinval;
567 }
568
569 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
570 ret = _ctf_visitor_semantic_check(depth + 1, iter,
571 log_cfg);
572 if (ret)
573 return ret;
574 }
575 break;
576 case NODE_CALLSITE:
577 switch (node->parent->type) {
578 case NODE_ROOT:
579 break; /* OK */
580 default:
581 goto errinval;
582 }
583
584 bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
585 ret = _ctf_visitor_semantic_check(depth + 1, iter,
586 log_cfg);
587 if (ret)
588 return ret;
589 }
590 break;
591
592 case NODE_CTF_EXPRESSION:
593 switch (node->parent->type) {
594 case NODE_ROOT:
595 case NODE_EVENT:
596 case NODE_STREAM:
597 case NODE_ENV:
598 case NODE_TRACE:
599 case NODE_CLOCK:
600 case NODE_CALLSITE:
601 case NODE_FLOATING_POINT:
602 case NODE_INTEGER:
603 case NODE_STRING:
604 break; /* OK */
605
606 case NODE_CTF_EXPRESSION:
607 case NODE_UNARY_EXPRESSION:
608 case NODE_TYPEDEF:
609 case NODE_TYPEALIAS_TARGET:
610 case NODE_TYPEALIAS_ALIAS:
611 case NODE_STRUCT_OR_VARIANT_DECLARATION:
612 case NODE_TYPEALIAS:
613 case NODE_TYPE_SPECIFIER:
614 case NODE_TYPE_SPECIFIER_LIST:
615 case NODE_POINTER:
616 case NODE_TYPE_DECLARATOR:
617 case NODE_ENUMERATOR:
618 case NODE_ENUM:
619 case NODE_VARIANT:
620 case NODE_STRUCT:
621 default:
622 goto errinval;
623 }
624
625 depth++;
626 bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
627 ret = _ctf_visitor_semantic_check(depth + 1, iter,
628 log_cfg);
629 if (ret)
630 return ret;
631 }
632 bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
633 ret = _ctf_visitor_semantic_check(depth + 1, iter,
634 log_cfg);
635 if (ret)
636 return ret;
637 }
638 depth--;
639 break;
640 case NODE_UNARY_EXPRESSION:
641 return ctf_visitor_unary_expression(depth, node, log_cfg);
642
643 case NODE_TYPEDEF:
644 switch (node->parent->type) {
645 case NODE_ROOT:
646 case NODE_EVENT:
647 case NODE_STREAM:
648 case NODE_TRACE:
649 case NODE_VARIANT:
650 case NODE_STRUCT:
651 break; /* OK */
652
653 case NODE_CTF_EXPRESSION:
654 case NODE_UNARY_EXPRESSION:
655 case NODE_TYPEDEF:
656 case NODE_TYPEALIAS_TARGET:
657 case NODE_TYPEALIAS_ALIAS:
658 case NODE_TYPEALIAS:
659 case NODE_STRUCT_OR_VARIANT_DECLARATION:
660 case NODE_TYPE_SPECIFIER:
661 case NODE_TYPE_SPECIFIER_LIST:
662 case NODE_POINTER:
663 case NODE_TYPE_DECLARATOR:
664 case NODE_FLOATING_POINT:
665 case NODE_INTEGER:
666 case NODE_STRING:
667 case NODE_ENUMERATOR:
668 case NODE_ENUM:
669 case NODE_CLOCK:
670 case NODE_CALLSITE:
671 case NODE_ENV:
672 default:
673 goto errinval;
674 }
675
676 depth++;
677 ret = _ctf_visitor_semantic_check(depth + 1,
678 node->u.field_class_def.field_class_specifier_list,
679 log_cfg);
680 if (ret)
681 return ret;
682 bt_list_for_each_entry(iter, &node->u.field_class_def.field_class_declarators, siblings) {
683 ret = _ctf_visitor_semantic_check(depth + 1, iter,
684 log_cfg);
685 if (ret)
686 return ret;
687 }
688 depth--;
689 break;
690 case NODE_TYPEALIAS_TARGET:
691 {
692 int nr_declarators;
693
694 switch (node->parent->type) {
695 case NODE_TYPEALIAS:
696 break; /* OK */
697 default:
698 goto errinval;
699 }
700
701 depth++;
702 ret = _ctf_visitor_semantic_check(depth + 1,
703 node->u.field_class_alias_target.field_class_specifier_list,
704 log_cfg);
705 if (ret)
706 return ret;
707 nr_declarators = 0;
708 bt_list_for_each_entry(iter, &node->u.field_class_alias_target.field_class_declarators, siblings) {
709 ret = _ctf_visitor_semantic_check(depth + 1, iter,
710 log_cfg);
711 if (ret)
712 return ret;
713 nr_declarators++;
714 }
715 if (nr_declarators > 1) {
716 _BT_COMP_LOGE_LINENO(node->lineno,
717 "Too many declarators in field class alias's name (maximum is 1): count=%d",
718 nr_declarators);
719 return -EINVAL;
720 }
721 depth--;
722 break;
723 }
724 case NODE_TYPEALIAS_ALIAS:
725 {
726 int nr_declarators;
727
728 switch (node->parent->type) {
729 case NODE_TYPEALIAS:
730 break; /* OK */
731 default:
732 goto errinval;
733 }
734
735 depth++;
736 ret = _ctf_visitor_semantic_check(depth + 1,
737 node->u.field_class_alias_name.field_class_specifier_list,
738 log_cfg);
739 if (ret)
740 return ret;
741 nr_declarators = 0;
742 bt_list_for_each_entry(iter, &node->u.field_class_alias_name.field_class_declarators, siblings) {
743 ret = _ctf_visitor_semantic_check(depth + 1, iter,
744 log_cfg);
745 if (ret)
746 return ret;
747 nr_declarators++;
748 }
749 if (nr_declarators > 1) {
750 _BT_COMP_LOGE_LINENO(node->lineno,
751 "Too many declarators in field class alias's name (maximum is 1): count=%d",
752 nr_declarators);
753 return -EINVAL;
754 }
755 depth--;
756 break;
757 }
758 case NODE_TYPEALIAS:
759 switch (node->parent->type) {
760 case NODE_ROOT:
761 case NODE_EVENT:
762 case NODE_STREAM:
763 case NODE_TRACE:
764 case NODE_VARIANT:
765 case NODE_STRUCT:
766 break; /* OK */
767
768 case NODE_CTF_EXPRESSION:
769 case NODE_UNARY_EXPRESSION:
770 case NODE_TYPEDEF:
771 case NODE_TYPEALIAS_TARGET:
772 case NODE_TYPEALIAS_ALIAS:
773 case NODE_TYPEALIAS:
774 case NODE_STRUCT_OR_VARIANT_DECLARATION:
775 case NODE_TYPE_SPECIFIER:
776 case NODE_TYPE_SPECIFIER_LIST:
777 case NODE_POINTER:
778 case NODE_TYPE_DECLARATOR:
779 case NODE_FLOATING_POINT:
780 case NODE_INTEGER:
781 case NODE_STRING:
782 case NODE_ENUMERATOR:
783 case NODE_ENUM:
784 case NODE_CLOCK:
785 case NODE_CALLSITE:
786 case NODE_ENV:
787 default:
788 goto errinval;
789 }
790
791 ret = _ctf_visitor_semantic_check(depth + 1,
792 node->u.field_class_alias.target, log_cfg);
793 if (ret)
794 return ret;
795 ret = _ctf_visitor_semantic_check(depth + 1,
796 node->u.field_class_alias.alias, log_cfg);
797 if (ret)
798 return ret;
799 break;
800
801 case NODE_TYPE_SPECIFIER_LIST:
802 ret = ctf_visitor_field_class_specifier_list(depth, node,
803 log_cfg);
804 if (ret)
805 return ret;
806 break;
807 case NODE_TYPE_SPECIFIER:
808 ret = ctf_visitor_field_class_specifier(depth, node,
809 log_cfg);
810 if (ret)
811 return ret;
812 break;
813 case NODE_POINTER:
814 switch (node->parent->type) {
815 case NODE_TYPE_DECLARATOR:
816 break; /* OK */
817 default:
818 goto errinval;
819 }
820 break;
821 case NODE_TYPE_DECLARATOR:
822 ret = ctf_visitor_field_class_declarator(depth, node,
823 log_cfg);
824 if (ret)
825 return ret;
826 break;
827
828 case NODE_FLOATING_POINT:
829 switch (node->parent->type) {
830 case NODE_TYPE_SPECIFIER:
831 break; /* OK */
832 default:
833 goto errinval;
834
835 case NODE_UNARY_EXPRESSION:
836 goto errperm;
837 }
838 bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
839 ret = _ctf_visitor_semantic_check(depth + 1, iter,
840 log_cfg);
841 if (ret)
842 return ret;
843 }
844 break;
845 case NODE_INTEGER:
846 switch (node->parent->type) {
847 case NODE_TYPE_SPECIFIER:
848 break; /* OK */
849 default:
850 goto errinval;
851
852 }
853
854 bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
855 ret = _ctf_visitor_semantic_check(depth + 1, iter,
856 log_cfg);
857 if (ret)
858 return ret;
859 }
860 break;
861 case NODE_STRING:
862 switch (node->parent->type) {
863 case NODE_TYPE_SPECIFIER:
864 break; /* OK */
865 default:
866 goto errinval;
867
868 case NODE_UNARY_EXPRESSION:
869 goto errperm;
870 }
871
872 bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
873 ret = _ctf_visitor_semantic_check(depth + 1, iter,
874 log_cfg);
875 if (ret)
876 return ret;
877 }
878 break;
879 case NODE_ENUMERATOR:
880 switch (node->parent->type) {
881 case NODE_ENUM:
882 break;
883 default:
884 goto errinval;
885 }
886 /*
887 * Enumerators are only allows to contain:
888 * numeric unary expression
889 * or num. unary exp. ... num. unary exp
890 */
891 {
892 int count = 0;
893
894 bt_list_for_each_entry(iter, &node->u.enumerator.values,
895 siblings) {
896 switch (count++) {
897 case 0: if (iter->type != NODE_UNARY_EXPRESSION
898 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
899 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
900 || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) {
901 _BT_COMP_LOGE_LINENO(iter->lineno,
902 "First unary expression of enumerator is unexpected.");
903 goto errperm;
904 }
905 break;
906 case 1: if (iter->type != NODE_UNARY_EXPRESSION
907 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
908 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
909 || iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
910 _BT_COMP_LOGE_LINENO(iter->lineno,
911 "Second unary expression of enumerator is unexpected.");
912 goto errperm;
913 }
914 break;
915 default:
916 goto errperm;
917 }
918 }
919 }
920
921 bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
922 ret = _ctf_visitor_semantic_check(depth + 1, iter,
923 log_cfg);
924 if (ret)
925 return ret;
926 }
927 break;
928 case NODE_ENUM:
929 switch (node->parent->type) {
930 case NODE_TYPE_SPECIFIER:
931 break; /* OK */
932 default:
933 goto errinval;
934
935 case NODE_UNARY_EXPRESSION:
936 goto errperm;
937 }
938
939 depth++;
940 ret = _ctf_visitor_semantic_check(depth + 1,
941 node->u._enum.container_field_class, log_cfg);
942 if (ret)
943 return ret;
944
945 bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
946 ret = _ctf_visitor_semantic_check(depth + 1, iter,
947 log_cfg);
948 if (ret)
949 return ret;
950 }
951 depth--;
952 break;
953 case NODE_STRUCT_OR_VARIANT_DECLARATION:
954 switch (node->parent->type) {
955 case NODE_STRUCT:
956 case NODE_VARIANT:
957 break;
958 default:
959 goto errinval;
960 }
961 ret = _ctf_visitor_semantic_check(depth + 1,
962 node->u.struct_or_variant_declaration.field_class_specifier_list,
963 log_cfg);
964 if (ret)
965 return ret;
966 bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) {
967 ret = _ctf_visitor_semantic_check(depth + 1, iter,
968 log_cfg);
969 if (ret)
970 return ret;
971 }
972 break;
973 case NODE_VARIANT:
974 switch (node->parent->type) {
975 case NODE_TYPE_SPECIFIER:
976 break; /* OK */
977 default:
978 goto errinval;
979
980 case NODE_UNARY_EXPRESSION:
981 goto errperm;
982 }
983 bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
984 ret = _ctf_visitor_semantic_check(depth + 1, iter,
985 log_cfg);
986 if (ret)
987 return ret;
988 }
989 break;
990
991 case NODE_STRUCT:
992 switch (node->parent->type) {
993 case NODE_TYPE_SPECIFIER:
994 break; /* OK */
995 default:
996 goto errinval;
997
998 case NODE_UNARY_EXPRESSION:
999 goto errperm;
1000 }
1001 bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
1002 ret = _ctf_visitor_semantic_check(depth + 1, iter,
1003 log_cfg);
1004 if (ret)
1005 return ret;
1006 }
1007 break;
1008
1009 case NODE_UNKNOWN:
1010 default:
1011 _BT_COMP_LOGE_LINENO(node->lineno,
1012 "Unknown node type: type=%d", node->type);
1013 return -EINVAL;
1014 }
1015 return ret;
1016
1017 errinval:
1018 _BT_COMP_LOGE_LINENO(node->lineno,
1019 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
1020 node_type(node), node_type(node->parent));
1021 return -EINVAL; /* Incoherent structure */
1022
1023 errperm:
1024 _BT_COMP_LOGE_LINENO(node->lineno,
1025 "Semantic error: node-type=%s, parent-node-type=%s",
1026 node_type(node), node_type(node->parent));
1027 return -EPERM; /* Structure not allowed */
1028 }
1029
1030 int ctf_visitor_semantic_check(int depth, struct ctf_node *node,
1031 struct meta_log_config *log_cfg)
1032 {
1033 int ret = 0;
1034
1035 /*
1036 * First make sure we create the parent links for all children. Let's
1037 * take the safe route and recreate them at each validation, just in
1038 * case the structure has changed.
1039 */
1040 ret = ctf_visitor_parent_links(depth, node, log_cfg);
1041 if (ret) {
1042 _BT_COMP_LOGE_LINENO(node->lineno,
1043 "Cannot create parent links in metadata's AST: "
1044 "ret=%d", ret);
1045 goto end;
1046 }
1047
1048 ret = _ctf_visitor_semantic_check(depth, node, log_cfg);
1049 if (ret) {
1050 _BT_COMP_LOGE_LINENO(node->lineno,
1051 "Cannot check metadata's AST semantics: "
1052 "ret=%d", ret);
1053 goto end;
1054 }
1055
1056 end:
1057 return ret;
1058 }
This page took 0.052986 seconds and 4 git commands to generate.