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