5592d6d577511aa74060d50aa577157c1c5f91de
[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_LOG_TAG "PLUGIN-CTF-METADATA-SEMANTIC-VALIDATOR-VISITOR"
28 #include "logging.h"
29
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include "common/assert.h"
35 #include <glib.h>
36 #include <inttypes.h>
37 #include <errno.h>
38 #include "common/list.h"
39 #include "scanner.h"
40 #include "parser.h"
41 #include "ast.h"
42
43 #define _bt_list_first_entry(ptr, type, member) \
44 bt_list_entry((ptr)->next, type, member)
45
46 static
47 int _ctf_visitor_semantic_check(int depth, struct ctf_node *node);
48
49 static
50 int ctf_visitor_unary_expression(int depth, struct ctf_node *node)
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) {
67 _BT_LOGE_LINENO(node->lineno,
68 "Left child of a CTF expression is only allowed to be a string.");
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:
85 _BT_LOGE_LINENO(node->lineno,
86 "Children of field class declarator and `enum` can only be unsigned numeric constants or references to fields (e.g., `a.b.c`).");
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:
99 _BT_LOGE_LINENO(node->lineno,
100 "Structure alignment attribute can only be an unsigned numeric constant.");
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 */
114 _BT_LOGE_LINENO(node->lineno,
115 "Nested unary expressions not allowed (`()` and `[]`).");
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) {
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 `->`).");
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) {
158 _BT_LOGE_LINENO(node->lineno,
159 "Links `.` and `->` are only allowed as children of CTF expression.");
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) {
167 _BT_LOGE_LINENO(node->lineno,
168 "Links `.` and `->` are only allowed to separate strings and identifiers.");
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) {
177 _BT_LOGE_LINENO(node->lineno,
178 "Links `.` and `->` are not allowed before first node of the unary expression list.");
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) {
185 _BT_LOGE_LINENO(node->lineno,
186 "Link `...` is only allowed within enumerator.");
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) {
193 _BT_LOGE_LINENO(node->lineno,
194 "Link `...` is not allowed on the first node of the unary expression list.");
195 goto errperm;
196 }
197 break;
198 default:
199 _BT_LOGE_LINENO(node->lineno,
200 "Unknown expression link type: type=%d",
201 node->u.unary_expression.link);
202 return -EINVAL;
203 }
204 return 0;
205
206 errinval:
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));
210 return -EINVAL; /* Incoherent structure */
211
212 errperm:
213 _BT_LOGE_LINENO(node->lineno,
214 "Semantic error: node-type=%s, parent-node-type=%s",
215 node_type(node), node_type(node->parent));
216 return -EPERM; /* Structure not allowed */
217 }
218
219 static
220 int ctf_visitor_field_class_specifier_list(int depth, struct ctf_node *node)
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;
254 errinval:
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));
258 return -EINVAL; /* Incoherent structure */
259 }
260
261 static
262 int ctf_visitor_field_class_specifier(int depth, struct ctf_node *node)
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;
296 errinval:
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));
300 return -EINVAL; /* Incoherent structure */
301 }
302
303 static
304 int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node)
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 field class declarator is not allowed to
315 * contain pointers.
316 */
317 if (!bt_list_empty(&node->u.field_class_declarator.pointers))
318 goto errperm;
319 break; /* OK */
320 case NODE_TYPEALIAS_TARGET:
321 break; /* OK */
322 case NODE_TYPEALIAS_ALIAS:
323 /*
324 * Only accept alias name containing:
325 * - identifier
326 * - identifier * (any number of pointers)
327 * NOT accepting alias names containing [] (would otherwise
328 * cause semantic clash for later declarations of
329 * arrays/sequences of elements, where elements could be
330 * arrays/sequences themselves (if allowed in field class alias).
331 * NOT accepting alias with identifier. The declarator should
332 * be either empty or contain pointer(s).
333 */
334 if (node->u.field_class_declarator.type == TYPEDEC_NESTED)
335 goto errperm;
336 bt_list_for_each_entry(iter, &node->parent->u.field_class_alias_name.field_class_specifier_list->u.field_class_specifier_list.head,
337 siblings) {
338 switch (iter->u.field_class_specifier.type) {
339 case TYPESPEC_FLOATING_POINT:
340 case TYPESPEC_INTEGER:
341 case TYPESPEC_STRING:
342 case TYPESPEC_STRUCT:
343 case TYPESPEC_VARIANT:
344 case TYPESPEC_ENUM:
345 if (bt_list_empty(&node->u.field_class_declarator.pointers))
346 goto errperm;
347 break;
348 default:
349 break;
350 }
351 }
352 if (node->u.field_class_declarator.type == TYPEDEC_ID &&
353 node->u.field_class_declarator.u.id != NULL)
354 goto errperm;
355 break; /* OK */
356 case NODE_TYPEDEF:
357 case NODE_STRUCT_OR_VARIANT_DECLARATION:
358 break; /* OK */
359
360 case NODE_ROOT:
361 case NODE_EVENT:
362 case NODE_STREAM:
363 case NODE_ENV:
364 case NODE_TRACE:
365 case NODE_CLOCK:
366 case NODE_CALLSITE:
367 case NODE_CTF_EXPRESSION:
368 case NODE_UNARY_EXPRESSION:
369 case NODE_TYPEALIAS:
370 case NODE_TYPE_SPECIFIER:
371 case NODE_POINTER:
372 case NODE_FLOATING_POINT:
373 case NODE_INTEGER:
374 case NODE_STRING:
375 case NODE_ENUMERATOR:
376 case NODE_ENUM:
377 case NODE_VARIANT:
378 case NODE_STRUCT:
379 default:
380 goto errinval;
381 }
382
383 bt_list_for_each_entry(iter, &node->u.field_class_declarator.pointers,
384 siblings) {
385 ret = _ctf_visitor_semantic_check(depth + 1, iter);
386 if (ret)
387 return ret;
388 }
389
390 switch (node->u.field_class_declarator.type) {
391 case TYPEDEC_ID:
392 break;
393 case TYPEDEC_NESTED:
394 {
395 if (node->u.field_class_declarator.u.nested.field_class_declarator) {
396 ret = _ctf_visitor_semantic_check(depth + 1,
397 node->u.field_class_declarator.u.nested.field_class_declarator);
398 if (ret)
399 return ret;
400 }
401 if (!node->u.field_class_declarator.u.nested.abstract_array) {
402 bt_list_for_each_entry(iter, &node->u.field_class_declarator.u.nested.length,
403 siblings) {
404 if (iter->type != NODE_UNARY_EXPRESSION) {
405 _BT_LOGE_LINENO(node->lineno,
406 "Expecting unary expression as length: node-type=%s",
407 node_type(iter));
408 return -EINVAL;
409 }
410 ret = _ctf_visitor_semantic_check(depth + 1, iter);
411 if (ret)
412 return ret;
413 }
414 } else {
415 if (node->parent->type == NODE_TYPEALIAS_TARGET) {
416 _BT_LOGE_LINENO(node->lineno,
417 "Abstract array declarator not permitted as target of field class alias.");
418 return -EINVAL;
419 }
420 }
421 if (node->u.field_class_declarator.bitfield_len) {
422 ret = _ctf_visitor_semantic_check(depth + 1,
423 node->u.field_class_declarator.bitfield_len);
424 if (ret)
425 return ret;
426 }
427 break;
428 }
429 case TYPEDEC_UNKNOWN:
430 default:
431 _BT_LOGE_LINENO(node->lineno,
432 "Unknown field class declarator: type=%d",
433 node->u.field_class_declarator.type);
434 return -EINVAL;
435 }
436 depth--;
437 return 0;
438
439 errinval:
440 _BT_LOGE_LINENO(node->lineno,
441 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
442 node_type(node), node_type(node->parent));
443 return -EINVAL; /* Incoherent structure */
444
445 errperm:
446 _BT_LOGE_LINENO(node->lineno,
447 "Semantic error: node-type=%s, parent-node-type=%s",
448 node_type(node), node_type(node->parent));
449 return -EPERM; /* Structure not allowed */
450 }
451
452 static
453 int _ctf_visitor_semantic_check(int depth, struct ctf_node *node)
454 {
455 int ret = 0;
456 struct ctf_node *iter;
457
458 if (node->visited)
459 return 0;
460
461 switch (node->type) {
462 case NODE_ROOT:
463 bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) {
464 ret = _ctf_visitor_semantic_check(depth + 1, iter);
465 if (ret)
466 return ret;
467 }
468 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
469 ret = _ctf_visitor_semantic_check(depth + 1, iter);
470 if (ret)
471 return ret;
472 }
473 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
474 ret = _ctf_visitor_semantic_check(depth + 1, iter);
475 if (ret)
476 return ret;
477 }
478 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
479 ret = _ctf_visitor_semantic_check(depth + 1, iter);
480 if (ret)
481 return ret;
482 }
483 break;
484
485 case NODE_EVENT:
486 switch (node->parent->type) {
487 case NODE_ROOT:
488 break; /* OK */
489 default:
490 goto errinval;
491 }
492
493 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
494 ret = _ctf_visitor_semantic_check(depth + 1, iter);
495 if (ret)
496 return ret;
497 }
498 break;
499 case NODE_STREAM:
500 switch (node->parent->type) {
501 case NODE_ROOT:
502 break; /* OK */
503 default:
504 goto errinval;
505 }
506
507 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
508 ret = _ctf_visitor_semantic_check(depth + 1, iter);
509 if (ret)
510 return ret;
511 }
512 break;
513 case NODE_ENV:
514 switch (node->parent->type) {
515 case NODE_ROOT:
516 break; /* OK */
517 default:
518 goto errinval;
519 }
520
521 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
522 ret = _ctf_visitor_semantic_check(depth + 1, iter);
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) {
536 ret = _ctf_visitor_semantic_check(depth + 1, iter);
537 if (ret)
538 return ret;
539 }
540 break;
541 case NODE_CLOCK:
542 switch (node->parent->type) {
543 case NODE_ROOT:
544 break; /* OK */
545 default:
546 goto errinval;
547 }
548
549 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
550 ret = _ctf_visitor_semantic_check(depth + 1, iter);
551 if (ret)
552 return ret;
553 }
554 break;
555 case NODE_CALLSITE:
556 switch (node->parent->type) {
557 case NODE_ROOT:
558 break; /* OK */
559 default:
560 goto errinval;
561 }
562
563 bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
564 ret = _ctf_visitor_semantic_check(depth + 1, iter);
565 if (ret)
566 return ret;
567 }
568 break;
569
570 case NODE_CTF_EXPRESSION:
571 switch (node->parent->type) {
572 case NODE_ROOT:
573 case NODE_EVENT:
574 case NODE_STREAM:
575 case NODE_ENV:
576 case NODE_TRACE:
577 case NODE_CLOCK:
578 case NODE_CALLSITE:
579 case NODE_FLOATING_POINT:
580 case NODE_INTEGER:
581 case NODE_STRING:
582 break; /* OK */
583
584 case NODE_CTF_EXPRESSION:
585 case NODE_UNARY_EXPRESSION:
586 case NODE_TYPEDEF:
587 case NODE_TYPEALIAS_TARGET:
588 case NODE_TYPEALIAS_ALIAS:
589 case NODE_STRUCT_OR_VARIANT_DECLARATION:
590 case NODE_TYPEALIAS:
591 case NODE_TYPE_SPECIFIER:
592 case NODE_TYPE_SPECIFIER_LIST:
593 case NODE_POINTER:
594 case NODE_TYPE_DECLARATOR:
595 case NODE_ENUMERATOR:
596 case NODE_ENUM:
597 case NODE_VARIANT:
598 case NODE_STRUCT:
599 default:
600 goto errinval;
601 }
602
603 depth++;
604 bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
605 ret = _ctf_visitor_semantic_check(depth + 1, iter);
606 if (ret)
607 return ret;
608 }
609 bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
610 ret = _ctf_visitor_semantic_check(depth + 1, iter);
611 if (ret)
612 return ret;
613 }
614 depth--;
615 break;
616 case NODE_UNARY_EXPRESSION:
617 return ctf_visitor_unary_expression(depth, node);
618
619 case NODE_TYPEDEF:
620 switch (node->parent->type) {
621 case NODE_ROOT:
622 case NODE_EVENT:
623 case NODE_STREAM:
624 case NODE_TRACE:
625 case NODE_VARIANT:
626 case NODE_STRUCT:
627 break; /* OK */
628
629 case NODE_CTF_EXPRESSION:
630 case NODE_UNARY_EXPRESSION:
631 case NODE_TYPEDEF:
632 case NODE_TYPEALIAS_TARGET:
633 case NODE_TYPEALIAS_ALIAS:
634 case NODE_TYPEALIAS:
635 case NODE_STRUCT_OR_VARIANT_DECLARATION:
636 case NODE_TYPE_SPECIFIER:
637 case NODE_TYPE_SPECIFIER_LIST:
638 case NODE_POINTER:
639 case NODE_TYPE_DECLARATOR:
640 case NODE_FLOATING_POINT:
641 case NODE_INTEGER:
642 case NODE_STRING:
643 case NODE_ENUMERATOR:
644 case NODE_ENUM:
645 case NODE_CLOCK:
646 case NODE_CALLSITE:
647 case NODE_ENV:
648 default:
649 goto errinval;
650 }
651
652 depth++;
653 ret = _ctf_visitor_semantic_check(depth + 1,
654 node->u.field_class_def.field_class_specifier_list);
655 if (ret)
656 return ret;
657 bt_list_for_each_entry(iter, &node->u.field_class_def.field_class_declarators, siblings) {
658 ret = _ctf_visitor_semantic_check(depth + 1, iter);
659 if (ret)
660 return ret;
661 }
662 depth--;
663 break;
664 case NODE_TYPEALIAS_TARGET:
665 {
666 int nr_declarators;
667
668 switch (node->parent->type) {
669 case NODE_TYPEALIAS:
670 break; /* OK */
671 default:
672 goto errinval;
673 }
674
675 depth++;
676 ret = _ctf_visitor_semantic_check(depth + 1,
677 node->u.field_class_alias_target.field_class_specifier_list);
678 if (ret)
679 return ret;
680 nr_declarators = 0;
681 bt_list_for_each_entry(iter, &node->u.field_class_alias_target.field_class_declarators, siblings) {
682 ret = _ctf_visitor_semantic_check(depth + 1, iter);
683 if (ret)
684 return ret;
685 nr_declarators++;
686 }
687 if (nr_declarators > 1) {
688 _BT_LOGE_LINENO(node->lineno,
689 "Too many declarators in field class alias's name (maximum is 1): count=%d",
690 nr_declarators);
691 return -EINVAL;
692 }
693 depth--;
694 break;
695 }
696 case NODE_TYPEALIAS_ALIAS:
697 {
698 int nr_declarators;
699
700 switch (node->parent->type) {
701 case NODE_TYPEALIAS:
702 break; /* OK */
703 default:
704 goto errinval;
705 }
706
707 depth++;
708 ret = _ctf_visitor_semantic_check(depth + 1,
709 node->u.field_class_alias_name.field_class_specifier_list);
710 if (ret)
711 return ret;
712 nr_declarators = 0;
713 bt_list_for_each_entry(iter, &node->u.field_class_alias_name.field_class_declarators, siblings) {
714 ret = _ctf_visitor_semantic_check(depth + 1, iter);
715 if (ret)
716 return ret;
717 nr_declarators++;
718 }
719 if (nr_declarators > 1) {
720 _BT_LOGE_LINENO(node->lineno,
721 "Too many declarators in field class alias's name (maximum is 1): count=%d",
722 nr_declarators);
723 return -EINVAL;
724 }
725 depth--;
726 break;
727 }
728 case NODE_TYPEALIAS:
729 switch (node->parent->type) {
730 case NODE_ROOT:
731 case NODE_EVENT:
732 case NODE_STREAM:
733 case NODE_TRACE:
734 case NODE_VARIANT:
735 case NODE_STRUCT:
736 break; /* OK */
737
738 case NODE_CTF_EXPRESSION:
739 case NODE_UNARY_EXPRESSION:
740 case NODE_TYPEDEF:
741 case NODE_TYPEALIAS_TARGET:
742 case NODE_TYPEALIAS_ALIAS:
743 case NODE_TYPEALIAS:
744 case NODE_STRUCT_OR_VARIANT_DECLARATION:
745 case NODE_TYPE_SPECIFIER:
746 case NODE_TYPE_SPECIFIER_LIST:
747 case NODE_POINTER:
748 case NODE_TYPE_DECLARATOR:
749 case NODE_FLOATING_POINT:
750 case NODE_INTEGER:
751 case NODE_STRING:
752 case NODE_ENUMERATOR:
753 case NODE_ENUM:
754 case NODE_CLOCK:
755 case NODE_CALLSITE:
756 case NODE_ENV:
757 default:
758 goto errinval;
759 }
760
761 ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.target);
762 if (ret)
763 return ret;
764 ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.alias);
765 if (ret)
766 return ret;
767 break;
768
769 case NODE_TYPE_SPECIFIER_LIST:
770 ret = ctf_visitor_field_class_specifier_list(depth, node);
771 if (ret)
772 return ret;
773 break;
774 case NODE_TYPE_SPECIFIER:
775 ret = ctf_visitor_field_class_specifier(depth, node);
776 if (ret)
777 return ret;
778 break;
779 case NODE_POINTER:
780 switch (node->parent->type) {
781 case NODE_TYPE_DECLARATOR:
782 break; /* OK */
783 default:
784 goto errinval;
785 }
786 break;
787 case NODE_TYPE_DECLARATOR:
788 ret = ctf_visitor_field_class_declarator(depth, node);
789 if (ret)
790 return ret;
791 break;
792
793 case NODE_FLOATING_POINT:
794 switch (node->parent->type) {
795 case NODE_TYPE_SPECIFIER:
796 break; /* OK */
797 default:
798 goto errinval;
799
800 case NODE_UNARY_EXPRESSION:
801 goto errperm;
802 }
803 bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
804 ret = _ctf_visitor_semantic_check(depth + 1, iter);
805 if (ret)
806 return ret;
807 }
808 break;
809 case NODE_INTEGER:
810 switch (node->parent->type) {
811 case NODE_TYPE_SPECIFIER:
812 break; /* OK */
813 default:
814 goto errinval;
815
816 }
817
818 bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
819 ret = _ctf_visitor_semantic_check(depth + 1, iter);
820 if (ret)
821 return ret;
822 }
823 break;
824 case NODE_STRING:
825 switch (node->parent->type) {
826 case NODE_TYPE_SPECIFIER:
827 break; /* OK */
828 default:
829 goto errinval;
830
831 case NODE_UNARY_EXPRESSION:
832 goto errperm;
833 }
834
835 bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
836 ret = _ctf_visitor_semantic_check(depth + 1, iter);
837 if (ret)
838 return ret;
839 }
840 break;
841 case NODE_ENUMERATOR:
842 switch (node->parent->type) {
843 case NODE_ENUM:
844 break;
845 default:
846 goto errinval;
847 }
848 /*
849 * Enumerators are only allows to contain:
850 * numeric unary expression
851 * or num. unary exp. ... num. unary exp
852 */
853 {
854 int count = 0;
855
856 bt_list_for_each_entry(iter, &node->u.enumerator.values,
857 siblings) {
858 switch (count++) {
859 case 0: 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_LINK_UNKNOWN) {
863 _BT_LOGE_LINENO(iter->lineno,
864 "First unary expression of enumerator is unexpected.");
865 goto errperm;
866 }
867 break;
868 case 1: if (iter->type != NODE_UNARY_EXPRESSION
869 || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
870 && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
871 || iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
872 _BT_LOGE_LINENO(iter->lineno,
873 "Second unary expression of enumerator is unexpected.");
874 goto errperm;
875 }
876 break;
877 default:
878 goto errperm;
879 }
880 }
881 }
882
883 bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
884 ret = _ctf_visitor_semantic_check(depth + 1, iter);
885 if (ret)
886 return ret;
887 }
888 break;
889 case NODE_ENUM:
890 switch (node->parent->type) {
891 case NODE_TYPE_SPECIFIER:
892 break; /* OK */
893 default:
894 goto errinval;
895
896 case NODE_UNARY_EXPRESSION:
897 goto errperm;
898 }
899
900 depth++;
901 ret = _ctf_visitor_semantic_check(depth + 1, node->u._enum.container_field_class);
902 if (ret)
903 return ret;
904
905 bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
906 ret = _ctf_visitor_semantic_check(depth + 1, iter);
907 if (ret)
908 return ret;
909 }
910 depth--;
911 break;
912 case NODE_STRUCT_OR_VARIANT_DECLARATION:
913 switch (node->parent->type) {
914 case NODE_STRUCT:
915 case NODE_VARIANT:
916 break;
917 default:
918 goto errinval;
919 }
920 ret = _ctf_visitor_semantic_check(depth + 1,
921 node->u.struct_or_variant_declaration.field_class_specifier_list);
922 if (ret)
923 return ret;
924 bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) {
925 ret = _ctf_visitor_semantic_check(depth + 1, iter);
926 if (ret)
927 return ret;
928 }
929 break;
930 case NODE_VARIANT:
931 switch (node->parent->type) {
932 case NODE_TYPE_SPECIFIER:
933 break; /* OK */
934 default:
935 goto errinval;
936
937 case NODE_UNARY_EXPRESSION:
938 goto errperm;
939 }
940 bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
941 ret = _ctf_visitor_semantic_check(depth + 1, iter);
942 if (ret)
943 return ret;
944 }
945 break;
946
947 case NODE_STRUCT:
948 switch (node->parent->type) {
949 case NODE_TYPE_SPECIFIER:
950 break; /* OK */
951 default:
952 goto errinval;
953
954 case NODE_UNARY_EXPRESSION:
955 goto errperm;
956 }
957 bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
958 ret = _ctf_visitor_semantic_check(depth + 1, iter);
959 if (ret)
960 return ret;
961 }
962 break;
963
964 case NODE_UNKNOWN:
965 default:
966 _BT_LOGE_LINENO(node->lineno,
967 "Unknown node type: type=%d", node->type);
968 return -EINVAL;
969 }
970 return ret;
971
972 errinval:
973 _BT_LOGE_LINENO(node->lineno,
974 "Incoherent parent node's type: node-type=%s, parent-node-type=%s",
975 node_type(node), node_type(node->parent));
976 return -EINVAL; /* Incoherent structure */
977
978 errperm:
979 _BT_LOGE_LINENO(node->lineno,
980 "Semantic error: node-type=%s, parent-node-type=%s",
981 node_type(node), node_type(node->parent));
982 return -EPERM; /* Structure not allowed */
983 }
984
985 int ctf_visitor_semantic_check(int depth, struct ctf_node *node)
986 {
987 int ret = 0;
988
989 /*
990 * First make sure we create the parent links for all children. Let's
991 * take the safe route and recreate them at each validation, just in
992 * case the structure has changed.
993 */
994 ret = ctf_visitor_parent_links(depth, node);
995 if (ret) {
996 _BT_LOGE_LINENO(node->lineno,
997 "Cannot create parent links in metadata's AST: "
998 "ret=%d", ret);
999 goto end;
1000 }
1001
1002 ret = _ctf_visitor_semantic_check(depth, node);
1003 if (ret) {
1004 _BT_LOGE_LINENO(node->lineno,
1005 "Cannot check metadata's AST semantics: "
1006 "ret=%d", ret);
1007 goto end;
1008 }
1009
1010 end:
1011 return ret;
1012 }
This page took 0.048974 seconds and 3 git commands to generate.