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