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