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