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