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