BT_CTF_BYTE_ORDER_NONE -> BT_CTF_BYTE_ORDER_UNSPECIFIED to match base
[babeltrace.git] / plugins / ctf / common / metadata / visitor-generate-ir.c
CommitLineData
e98a2d6e
PP
1/*
2 * ctf-visitor-generate-ir.c
3 *
4 * Common Trace Format metadata visitor (generates CTF IR objects).
5 *
6 * Based on older ctf-visitor-generate-io-struct.c.
7 *
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2016 - Philippe Proulx <philippe.proulx@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
08da4f77
PP
30#define BT_LOG_TAG "PLUGIN-CTF-METADATA-IR-VISITOR"
31#include "logging.h"
32
e98a2d6e
PP
33#include <stdio.h>
34#include <unistd.h>
35#include <string.h>
c55a9f58 36#include <stdbool.h>
e98a2d6e
PP
37#include <stdlib.h>
38#include <ctype.h>
39#include <assert.h>
40#include <glib.h>
41#include <inttypes.h>
42#include <errno.h>
3d9990ac
PP
43#include <babeltrace/compat/uuid-internal.h>
44#include <babeltrace/endian-internal.h>
e98a2d6e 45#include <babeltrace/ref.h>
e98a2d6e
PP
46#include <babeltrace/ctf-ir/trace.h>
47#include <babeltrace/ctf-ir/stream-class.h>
48#include <babeltrace/ctf-ir/event.h>
49#include <babeltrace/ctf-ir/event-class.h>
50#include <babeltrace/ctf-ir/field-types.h>
51#include <babeltrace/ctf-ir/field-types-internal.h>
ac0c6bdd 52#include <babeltrace/ctf-ir/clock-class.h>
e98a2d6e 53
06a626b8
JG
54#include "scanner.h"
55#include "parser.h"
56#include "ast.h"
a2a54545 57#include "decoder.h"
e98a2d6e
PP
58
59/* Bit value (left shift) */
60#define _BV(_val) (1 << (_val))
61
62/* Bit is set in a set of bits */
63#define _IS_SET(_set, _mask) (*(_set) & (_mask))
64
65/* Set bit in a set of bits */
66#define _SET(_set, _mask) (*(_set) |= (_mask))
67
68/* Bits for verifying existing attributes in various declarations */
69enum {
70 _CLOCK_NAME_SET = _BV(0),
71 _CLOCK_UUID_SET = _BV(1),
72 _CLOCK_FREQ_SET = _BV(2),
73 _CLOCK_PRECISION_SET = _BV(3),
74 _CLOCK_OFFSET_S_SET = _BV(4),
75 _CLOCK_OFFSET_SET = _BV(5),
76 _CLOCK_ABSOLUTE_SET = _BV(6),
77 _CLOCK_DESCRIPTION_SET = _BV(7),
78};
79
80enum {
81 _INTEGER_ALIGN_SET = _BV(0),
82 _INTEGER_SIZE_SET = _BV(1),
83 _INTEGER_BASE_SET = _BV(2),
84 _INTEGER_ENCODING_SET = _BV(3),
85 _INTEGER_BYTE_ORDER_SET = _BV(4),
86 _INTEGER_SIGNED_SET = _BV(5),
87 _INTEGER_MAP_SET = _BV(6),
88};
89
90enum {
91 _FLOAT_ALIGN_SET = _BV(0),
92 _FLOAT_MANT_DIG_SET = _BV(1),
93 _FLOAT_EXP_DIG_SET = _BV(2),
94 _FLOAT_BYTE_ORDER_SET = _BV(3),
95};
96
97enum {
98 _STRING_ENCODING_SET = _BV(0),
99};
100
101enum {
102 _TRACE_MINOR_SET = _BV(0),
103 _TRACE_MAJOR_SET = _BV(1),
104 _TRACE_BYTE_ORDER_SET = _BV(2),
105 _TRACE_UUID_SET = _BV(3),
106 _TRACE_PACKET_HEADER_SET = _BV(4),
107};
108
109enum {
110 _STREAM_ID_SET = _BV(0),
111 _STREAM_PACKET_CONTEXT_SET = _BV(1),
112 _STREAM_EVENT_HEADER_SET = _BV(2),
113 _STREAM_EVENT_CONTEXT_SET = _BV(3),
114};
115
116enum {
117 _EVENT_NAME_SET = _BV(0),
118 _EVENT_ID_SET = _BV(1),
119 _EVENT_MODEL_EMF_URI_SET = _BV(2),
120 _EVENT_STREAM_ID_SET = _BV(3),
121 _EVENT_LOGLEVEL_SET = _BV(4),
122 _EVENT_CONTEXT_SET = _BV(5),
123 _EVENT_FIELDS_SET = _BV(6),
124};
125
c3c30b08
MD
126enum loglevel {
127 LOGLEVEL_EMERG = 0,
128 LOGLEVEL_ALERT = 1,
129 LOGLEVEL_CRIT = 2,
130 LOGLEVEL_ERR = 3,
131 LOGLEVEL_WARNING = 4,
132 LOGLEVEL_NOTICE = 5,
133 LOGLEVEL_INFO = 6,
134 LOGLEVEL_DEBUG_SYSTEM = 7,
135 LOGLEVEL_DEBUG_PROGRAM = 8,
136 LOGLEVEL_DEBUG_PROCESS = 9,
137 LOGLEVEL_DEBUG_MODULE = 10,
138 LOGLEVEL_DEBUG_UNIT = 11,
139 LOGLEVEL_DEBUG_FUNCTION = 12,
140 LOGLEVEL_DEBUG_LINE = 13,
141 LOGLEVEL_DEBUG = 14,
142 _NR_LOGLEVELS = 15,
143};
144
e98a2d6e
PP
145/* Prefixes of type aliases */
146#define _PREFIX_ALIAS 'a'
147#define _PREFIX_ENUM 'e'
148#define _PREFIX_STRUCT 's'
149#define _PREFIX_VARIANT 'v'
150
151/* First entry in a BT list */
152#define _BT_LIST_FIRST_ENTRY(_ptr, _type, _member) \
153 bt_list_entry((_ptr)->next, _type, _member)
154
155#define _BT_CTF_FIELD_TYPE_INIT(_name) struct bt_ctf_field_type *_name = NULL;
156
28973adf
PP
157#define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
158 _BT_LOGE_LINENO((_node)->lineno, \
159 "Duplicate attribute in %s: attr-name=\"%s\"", \
160 _entity, _attr)
161
162#define _BT_LOGE_NODE(_node, _msg, args...) \
163 _BT_LOGE_LINENO((_node)->lineno, _msg, ## args)
164
165#define _BT_LOGW_NODE(_node, _msg, args...) \
166 _BT_LOGW_LINENO((_node)->lineno, _msg, ## args)
167
168#define _BT_LOGV_NODE(_node, _msg, args...) \
169 _BT_LOGV_LINENO((_node)->lineno, _msg, ## args)
e98a2d6e
PP
170
171/*
172 * Declaration scope of a visitor context. This represents a TSDL
173 * lexical scope, so that aliases and named structures, variants,
174 * and enumerations may be registered and looked up hierarchically.
175 */
176struct ctx_decl_scope {
177 /*
178 * Alias name to field type.
179 *
180 * GQuark -> struct bt_ctf_field_type *
181 */
182 GHashTable *decl_map;
183
184 /* Parent scope; NULL if this is the root declaration scope */
185 struct ctx_decl_scope *parent_scope;
186};
187
188/*
1e649dff 189 * Visitor context (private).
e98a2d6e
PP
190 */
191struct ctx {
1e649dff 192 /* Trace being filled (owned by this) */
e98a2d6e
PP
193 struct bt_ctf_trace *trace;
194
e98a2d6e
PP
195 /* Current declaration scope (top of the stack) */
196 struct ctx_decl_scope *current_scope;
197
198 /* 1 if trace declaration is visited */
199 int is_trace_visited;
200
f4421ff3
PP
201 /* 1 if this is an LTTng trace */
202 bool is_lttng;
203
91fd6f6a
PP
204 /* Eventual name suffix of the trace to set */
205 char *trace_name_suffix;
206
e98a2d6e 207 /* Trace attributes */
1e649dff 208 enum bt_ctf_byte_order trace_bo;
e98a2d6e
PP
209 uint64_t trace_major;
210 uint64_t trace_minor;
211 unsigned char trace_uuid[BABELTRACE_UUID_LEN];
212
213 /*
214 * Stream IDs to stream classes.
215 *
216 * int64_t -> struct bt_ctf_stream_class *
217 */
218 GHashTable *stream_classes;
a2a54545
PP
219
220 /* Config passed by the user */
221 struct ctf_metadata_decoder_config decoder_config;
e98a2d6e
PP
222};
223
1e649dff
PP
224/*
225 * Visitor (public).
226 */
227struct ctf_visitor_generate_ir { };
228
c3c30b08
MD
229static
230const char *loglevel_str [] = {
231 [ LOGLEVEL_EMERG ] = "TRACE_EMERG",
232 [ LOGLEVEL_ALERT ] = "TRACE_ALERT",
233 [ LOGLEVEL_CRIT ] = "TRACE_CRIT",
234 [ LOGLEVEL_ERR ] = "TRACE_ERR",
235 [ LOGLEVEL_WARNING ] = "TRACE_WARNING",
236 [ LOGLEVEL_NOTICE ] = "TRACE_NOTICE",
237 [ LOGLEVEL_INFO ] = "TRACE_INFO",
238 [ LOGLEVEL_DEBUG_SYSTEM ] = "TRACE_DEBUG_SYSTEM",
239 [ LOGLEVEL_DEBUG_PROGRAM ] = "TRACE_DEBUG_PROGRAM",
240 [ LOGLEVEL_DEBUG_PROCESS ] = "TRACE_DEBUG_PROCESS",
241 [ LOGLEVEL_DEBUG_MODULE ] = "TRACE_DEBUG_MODULE",
242 [ LOGLEVEL_DEBUG_UNIT ] = "TRACE_DEBUG_UNIT",
243 [ LOGLEVEL_DEBUG_FUNCTION ] = "TRACE_DEBUG_FUNCTION",
244 [ LOGLEVEL_DEBUG_LINE ] = "TRACE_DEBUG_LINE",
245 [ LOGLEVEL_DEBUG ] = "TRACE_DEBUG",
246};
247
248static
249const char *print_loglevel(int64_t value)
250{
251 if (value < 0) {
252 return NULL;
253 }
254 if (value >= _NR_LOGLEVELS) {
255 return "<<UNKNOWN>>";
256 }
257 return loglevel_str[value];
258}
259
e98a2d6e
PP
260/**
261 * Creates a new declaration scope.
262 *
263 * @param par_scope Parent scope (NULL if creating a root scope)
264 * @returns New declaration scope, or NULL on error
265 */
266static
267struct ctx_decl_scope *ctx_decl_scope_create(struct ctx_decl_scope *par_scope)
268{
269 struct ctx_decl_scope *scope;
270
271 scope = g_new(struct ctx_decl_scope, 1);
272 if (!scope) {
28973adf 273 BT_LOGE_STR("Failed to allocate one declaration scope.");
e98a2d6e
PP
274 goto end;
275 }
276
277 scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
278 NULL, (GDestroyNotify) bt_ctf_field_type_put);
279 scope->parent_scope = par_scope;
280
281end:
282 return scope;
283}
284
285/**
286 * Destroys a declaration scope.
287 *
288 * This function does not destroy the parent scope.
289 *
290 * @param scope Scope to destroy
291 */
292static
293void ctx_decl_scope_destroy(struct ctx_decl_scope *scope)
294{
295 if (!scope) {
296 goto end;
297 }
298
299 g_hash_table_destroy(scope->decl_map);
300 g_free(scope);
301
302end:
303 return;
304}
305
306/**
307 * Returns the GQuark of a prefixed alias.
308 *
309 * @param prefix Prefix character
310 * @param name Name
311 * @returns Associated GQuark, or 0 on error
312 */
313static
314GQuark get_prefixed_named_quark(char prefix, const char *name)
315{
316 GQuark qname = 0;
317
318 assert(name);
319
320 /* Prefix character + original string + '\0' */
321 char *prname = g_new(char, strlen(name) + 2);
322 if (!prname) {
28973adf 323 BT_LOGE_STR("Failed to allocate a string.");
e98a2d6e
PP
324 goto end;
325 }
326
327 sprintf(prname, "%c%s", prefix, name);
328 qname = g_quark_from_string(prname);
329 g_free(prname);
330
331end:
332 return qname;
333}
334
335/**
336 * Looks up a prefixed type alias within a declaration scope.
337 *
338 * @param scope Declaration scope
339 * @param prefix Prefix character
340 * @param name Alias name
341 * @param level Number of levels to dig (-1 means infinite)
342 * @returns Declaration, or NULL if not found
343 */
344static
345struct bt_ctf_field_type *ctx_decl_scope_lookup_prefix_alias(
346 struct ctx_decl_scope *scope, char prefix,
347 const char *name, int levels)
348{
349 GQuark qname = 0;
350 int cur_levels = 0;
351 _BT_CTF_FIELD_TYPE_INIT(decl);
352 struct ctx_decl_scope *cur_scope = scope;
353
354 assert(scope);
355 assert(name);
356 qname = get_prefixed_named_quark(prefix, name);
357 if (!qname) {
358 goto error;
359 }
360
361 if (levels < 0) {
362 levels = INT_MAX;
363 }
364
365 while (cur_scope && cur_levels < levels) {
366 decl = g_hash_table_lookup(cur_scope->decl_map,
71c7c95f 367 (gconstpointer) GUINT_TO_POINTER(qname));
e98a2d6e
PP
368 if (decl) {
369 /* Caller's reference */
370 bt_get(decl);
371 break;
372 }
373
374 cur_scope = cur_scope->parent_scope;
375 cur_levels++;
376 }
377
378 return decl;
379
380error:
381 return NULL;
382}
383
384/**
385 * Looks up a type alias within a declaration scope.
386 *
387 * @param scope Declaration scope
388 * @param name Alias name
389 * @param level Number of levels to dig (-1 means infinite)
390 * @returns Declaration, or NULL if not found
391 */
392static
393struct bt_ctf_field_type *ctx_decl_scope_lookup_alias(
394 struct ctx_decl_scope *scope, const char *name, int levels)
395{
396 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ALIAS,
397 name, levels);
398}
399
400/**
401 * Looks up an enumeration within a declaration scope.
402 *
403 * @param scope Declaration scope
404 * @param name Enumeration name
405 * @param level Number of levels to dig (-1 means infinite)
406 * @returns Declaration, or NULL if not found
407 */
408static
409struct bt_ctf_field_type *ctx_decl_scope_lookup_enum(
410 struct ctx_decl_scope *scope, const char *name, int levels)
411{
412 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ENUM,
413 name, levels);
414}
415
416/**
417 * Looks up a structure within a declaration scope.
418 *
419 * @param scope Declaration scope
420 * @param name Structure name
421 * @param level Number of levels to dig (-1 means infinite)
422 * @returns Declaration, or NULL if not found
423 */
424static
425struct bt_ctf_field_type *ctx_decl_scope_lookup_struct(
426 struct ctx_decl_scope *scope, const char *name, int levels)
427{
428 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_STRUCT,
429 name, levels);
430}
431
432/**
433 * Looks up a variant within a declaration scope.
434 *
435 * @param scope Declaration scope
436 * @param name Variant name
437 * @param level Number of levels to dig (-1 means infinite)
438 * @returns Declaration, or NULL if not found
439 */
440static
441struct bt_ctf_field_type *ctx_decl_scope_lookup_variant(
442 struct ctx_decl_scope *scope, const char *name, int levels)
443{
444 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_VARIANT,
445 name, levels);
446}
447
448/**
449 * Registers a prefixed type alias within a declaration scope.
450 *
451 * @param scope Declaration scope
452 * @param prefix Prefix character
453 * @param name Alias name (non-NULL)
454 * @param decl Declaration to register
455 * @returns 0 if registration went okay, negative value otherwise
456 */
457static
458int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope *scope,
459 char prefix, const char *name, struct bt_ctf_field_type *decl)
460{
461 int ret = 0;
462 GQuark qname = 0;
463 _BT_CTF_FIELD_TYPE_INIT(edecl);
464
465 assert(scope);
466 assert(name);
467 assert(decl);
468 qname = get_prefixed_named_quark(prefix, name);
469 if (!qname) {
470 ret = -ENOMEM;
471 goto error;
472 }
473
474 /* Make sure alias does not exist in local scope */
475 edecl = ctx_decl_scope_lookup_prefix_alias(scope, prefix, name, 1);
476 if (edecl) {
477 BT_PUT(edecl);
478 ret = -EEXIST;
479 goto error;
480 }
481
482 g_hash_table_insert(scope->decl_map,
71c7c95f 483 GUINT_TO_POINTER(qname), decl);
e98a2d6e
PP
484
485 /* Hash table's reference */
486 bt_get(decl);
487
488 return 0;
489
490error:
491 return ret;
492}
493
494/**
495 * Registers a type alias within a declaration scope.
496 *
497 * @param scope Declaration scope
498 * @param name Alias name (non-NULL)
499 * @param decl Declaration to register
500 * @returns 0 if registration went okay, negative value otherwise
501 */
502static
503int ctx_decl_scope_register_alias(struct ctx_decl_scope *scope,
504 const char *name, struct bt_ctf_field_type *decl)
505{
506 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ALIAS,
507 name, decl);
508}
509
510/**
511 * Registers an enumeration declaration within a declaration scope.
512 *
513 * @param scope Declaration scope
514 * @param name Enumeration name (non-NULL)
515 * @param decl Enumeration declaration to register
516 * @returns 0 if registration went okay, negative value otherwise
517 */
518static
519int ctx_decl_scope_register_enum(struct ctx_decl_scope *scope,
520 const char *name, struct bt_ctf_field_type *decl)
521{
522 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ENUM,
523 name, decl);
524}
525
526/**
527 * Registers a structure declaration within a declaration scope.
528 *
529 * @param scope Declaration scope
530 * @param name Structure name (non-NULL)
531 * @param decl Structure declaration to register
532 * @returns 0 if registration went okay, negative value otherwise
533 */
534static
535int ctx_decl_scope_register_struct(struct ctx_decl_scope *scope,
536 const char *name, struct bt_ctf_field_type *decl)
537{
538 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_STRUCT,
539 name, decl);
540}
541
542/**
543 * Registers a variant declaration within a declaration scope.
544 *
545 * @param scope Declaration scope
546 * @param name Variant name (non-NULL)
547 * @param decl Variant declaration to register
548 * @returns 0 if registration went okay, negative value otherwise
549 */
550static
551int ctx_decl_scope_register_variant(struct ctx_decl_scope *scope,
552 const char *name, struct bt_ctf_field_type *decl)
553{
554 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_VARIANT,
555 name, decl);
556}
557
91fd6f6a
PP
558/**
559 * Destroys a visitor context.
560 *
561 * @param ctx Visitor context to destroy
562 */
563static
564void ctx_destroy(struct ctx *ctx)
565{
566 struct ctx_decl_scope *scope;
567 /*
568 * Destroy all scopes, from current one to the root scope.
569 */
570
571 if (!ctx) {
572 goto end;
573 }
574
575 scope = ctx->current_scope;
576
577 while (scope) {
578 struct ctx_decl_scope *parent_scope = scope->parent_scope;
579
580 ctx_decl_scope_destroy(scope);
581 scope = parent_scope;
582 }
583
584 bt_put(ctx->trace);
585
586 if (ctx->stream_classes) {
587 g_hash_table_destroy(ctx->stream_classes);
588 }
589
590 free(ctx->trace_name_suffix);
591 g_free(ctx);
592
593end:
594 return;
595}
596
e98a2d6e
PP
597/**
598 * Creates a new visitor context.
599 *
600 * @param trace Associated trace
e98a2d6e
PP
601 * @returns New visitor context, or NULL on error
602 */
603static
55314f2a 604struct ctx *ctx_create(struct bt_ctf_trace *trace,
a2a54545
PP
605 const struct ctf_metadata_decoder_config *decoder_config,
606 const char *trace_name_suffix)
e98a2d6e
PP
607{
608 struct ctx *ctx = NULL;
609 struct ctx_decl_scope *scope = NULL;
610
a2a54545
PP
611 assert(decoder_config);
612
1e649dff 613 ctx = g_new0(struct ctx, 1);
e98a2d6e 614 if (!ctx) {
28973adf 615 BT_LOGE_STR("Failed to allocate one visitor context.");
e98a2d6e
PP
616 goto error;
617 }
618
619 /* Root declaration scope */
620 scope = ctx_decl_scope_create(NULL);
621 if (!scope) {
28973adf 622 BT_LOGE_STR("Cannot create declaration scope.");
e98a2d6e
PP
623 goto error;
624 }
625
626 ctx->stream_classes = g_hash_table_new_full(g_direct_hash,
627 g_direct_equal, NULL, (GDestroyNotify) bt_put);
628 if (!ctx->stream_classes) {
28973adf 629 BT_LOGE_STR("Failed to allocate a GHashTable.");
e98a2d6e
PP
630 goto error;
631 }
632
91fd6f6a
PP
633 if (trace_name_suffix) {
634 ctx->trace_name_suffix = strdup(trace_name_suffix);
635 if (!ctx->trace_name_suffix) {
28973adf 636 BT_LOGE_STR("Failed to copy string.");
91fd6f6a
PP
637 goto error;
638 }
639 }
640
e98a2d6e 641 ctx->trace = trace;
e98a2d6e 642 ctx->current_scope = scope;
91fd6f6a 643 scope = NULL;
1e649dff 644 ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
a2a54545 645 ctx->decoder_config = *decoder_config;
e98a2d6e
PP
646 return ctx;
647
648error:
91fd6f6a 649 ctx_destroy(ctx);
e98a2d6e 650 ctx_decl_scope_destroy(scope);
e98a2d6e
PP
651 return NULL;
652}
653
e98a2d6e
PP
654/**
655 * Pushes a new declaration scope on top of a visitor context's
656 * declaration scope stack.
657 *
658 * @param ctx Visitor context
659 * @returns 0 on success, or a negative value on error
660 */
661static
662int ctx_push_scope(struct ctx *ctx)
663{
664 int ret = 0;
665 struct ctx_decl_scope *new_scope;
666
667 assert(ctx);
668 new_scope = ctx_decl_scope_create(ctx->current_scope);
669 if (!new_scope) {
28973adf 670 BT_LOGE_STR("Cannot create declaration scope.");
e98a2d6e
PP
671 ret = -ENOMEM;
672 goto end;
673 }
674
675 ctx->current_scope = new_scope;
676
677end:
678 return ret;
679}
680
681static
682void ctx_pop_scope(struct ctx *ctx)
683{
684 struct ctx_decl_scope *parent_scope = NULL;
685
686 assert(ctx);
687
688 if (!ctx->current_scope) {
689 goto end;
690 }
691
692 parent_scope = ctx->current_scope->parent_scope;
693 ctx_decl_scope_destroy(ctx->current_scope);
694 ctx->current_scope = parent_scope;
695
696end:
697 return;
698}
699
700static
701int visit_type_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
702 struct bt_ctf_field_type **decl);
703
704static
705int is_unary_string(struct bt_list_head *head)
706{
707 int ret = TRUE;
708 struct ctf_node *node;
709
710 bt_list_for_each_entry(node, head, siblings) {
711 if (node->type != NODE_UNARY_EXPRESSION) {
712 ret = FALSE;
713 }
714
715 if (node->u.unary_expression.type != UNARY_STRING) {
716 ret = FALSE;
717 }
718 }
719
720 return ret;
721}
722
723static
724char *concatenate_unary_strings(struct bt_list_head *head)
725{
726 int i = 0;
727 GString *str;
728 struct ctf_node *node;
729
730 str = g_string_new(NULL);
08da4f77 731 assert(str);
e98a2d6e
PP
732
733 bt_list_for_each_entry(node, head, siblings) {
734 char *src_string;
735
736 if (
737 node->type != NODE_UNARY_EXPRESSION ||
738 node->u.unary_expression.type != UNARY_STRING ||
739 !(
740 (
741 node->u.unary_expression.link !=
742 UNARY_LINK_UNKNOWN
743 ) ^ (i == 0)
744 )
745 ) {
746 goto error;
747 }
748
749 switch (node->u.unary_expression.link) {
750 case UNARY_DOTLINK:
751 g_string_append(str, ".");
752 break;
753 case UNARY_ARROWLINK:
754 g_string_append(str, "->");
755 break;
756 case UNARY_DOTDOTDOT:
757 g_string_append(str, "...");
758 break;
759 default:
760 break;
761 }
762
763 src_string = node->u.unary_expression.u.string;
764 g_string_append(str, src_string);
765 i++;
766 }
767
768 /* Destroys the container, returns the underlying string */
769 return g_string_free(str, FALSE);
770
771error:
772 /* This always returns NULL */
773 return g_string_free(str, TRUE);
774}
775
776static
777const char *get_map_clock_name_value(struct bt_list_head *head)
778{
779 int i = 0;
780 struct ctf_node *node;
781 const char *name = NULL;
782
783 bt_list_for_each_entry(node, head, siblings) {
784 char *src_string;
785 int uexpr_type = node->u.unary_expression.type;
786 int uexpr_link = node->u.unary_expression.link;
787 int cond = node->type != NODE_UNARY_EXPRESSION ||
788 uexpr_type != UNARY_STRING ||
789 !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0));
790 if (cond) {
791 goto error;
792 }
793
794 /* Needs to be chained with . */
795 switch (node->u.unary_expression.link) {
796 case UNARY_DOTLINK:
797 break;
798 case UNARY_ARROWLINK:
799 case UNARY_DOTDOTDOT:
800 goto error;
801 default:
802 break;
803 }
804
805 src_string = node->u.unary_expression.u.string;
806
807 switch (i) {
808 case 0:
809 if (strcmp("clock", src_string)) {
810 goto error;
811 }
812 break;
813 case 1:
814 name = src_string;
815 break;
816 case 2:
817 if (strcmp("value", src_string)) {
818 goto error;
819 }
820 break;
821 default:
822 /* Extra identifier, unknown */
823 goto error;
824 }
825
826 i++;
827 }
828
829 return name;
830
831error:
832 return NULL;
833}
834
835static
836int is_unary_unsigned(struct bt_list_head *head)
837{
838 int ret = TRUE;
839 struct ctf_node *node;
840
841 bt_list_for_each_entry(node, head, siblings) {
842 if (node->type != NODE_UNARY_EXPRESSION) {
843 ret = FALSE;
844 }
845
846 if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
847 ret = FALSE;
848 }
849 }
850
851 return ret;
852}
853
854static
855int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
856{
857 int i = 0;
858 int ret = 0;
859 struct ctf_node *node;
860
d82c602e
JG
861 if (bt_list_empty(head)) {
862 ret = -1;
863 goto end;
864 }
865
e98a2d6e
PP
866 bt_list_for_each_entry(node, head, siblings) {
867 int uexpr_type = node->u.unary_expression.type;
868 int uexpr_link = node->u.unary_expression.link;
869 int cond = node->type != NODE_UNARY_EXPRESSION ||
870 uexpr_type != UNARY_UNSIGNED_CONSTANT ||
871 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
872 if (cond) {
28973adf 873 _BT_LOGE_NODE(node, "Invalid constant unsigned integer.");
e98a2d6e
PP
874 ret = -EINVAL;
875 goto end;
876 }
877
878 *value = node->u.unary_expression.u.unsigned_constant;
879 i++;
880 }
881
882end:
883 return ret;
884}
885
886static
887int is_unary_signed(struct bt_list_head *head)
888{
889 int ret = TRUE;
890 struct ctf_node *node;
891
892 bt_list_for_each_entry(node, head, siblings) {
893 if (node->type != NODE_UNARY_EXPRESSION) {
894 ret = FALSE;
895 }
896
897 if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
898 ret = FALSE;
899 }
900 }
901
902 return ret;
903}
904
905static
906int get_unary_signed(struct bt_list_head *head, int64_t *value)
907{
908 int i = 0;
909 int ret = 0;
910 struct ctf_node *node;
911
912 bt_list_for_each_entry(node, head, siblings) {
913 int uexpr_type = node->u.unary_expression.type;
914 int uexpr_link = node->u.unary_expression.link;
915 int cond = node->type != NODE_UNARY_EXPRESSION ||
916 (uexpr_type != UNARY_UNSIGNED_CONSTANT) ||
917 (uexpr_type != UNARY_UNSIGNED_CONSTANT &&
918 uexpr_type != UNARY_SIGNED_CONSTANT) ||
919 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
920 if (cond) {
921 ret = -EINVAL;
922 goto end;
923 }
924
925 switch (node->u.unary_expression.type) {
926 case UNARY_UNSIGNED_CONSTANT:
927 *value = (int64_t)
928 node->u.unary_expression.u.unsigned_constant;
929 break;
930 case UNARY_SIGNED_CONSTANT:
931 *value = node->u.unary_expression.u.signed_constant;
932 break;
933 default:
934 ret = -EINVAL;
935 goto end;
936 }
937
938 i++;
939 }
940
941end:
942 return ret;
943}
944
945static
946int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
947{
948 int i = 0;
949 int ret = 0;
950 struct ctf_node *node;
951
952 bt_list_for_each_entry(node, head, siblings) {
953 int uexpr_type = node->u.unary_expression.type;
954 int uexpr_link = node->u.unary_expression.link;
955 const char *src_string;
956
957 if (node->type != NODE_UNARY_EXPRESSION ||
958 uexpr_type != UNARY_STRING ||
959 uexpr_link != UNARY_LINK_UNKNOWN ||
960 i != 0) {
961 ret = -EINVAL;
962 goto end;
963 }
964
965 src_string = node->u.unary_expression.u.string;
966 ret = bt_uuid_parse(src_string, uuid);
967 if (ret) {
28973adf
PP
968 _BT_LOGE_NODE(node,
969 "Cannot parse UUID: uuid=\"%s\"", src_string);
e98a2d6e
PP
970 goto end;
971 }
972 }
973
974end:
975 return ret;
976}
977
978static
55314f2a 979int get_boolean(struct ctf_node *unary_expr)
e98a2d6e
PP
980{
981 int ret = 0;
982
983 if (unary_expr->type != NODE_UNARY_EXPRESSION) {
28973adf
PP
984 _BT_LOGE_NODE(unary_expr,
985 "Expecting unary expression: node-type=%d",
08da4f77 986 unary_expr->type);
e98a2d6e
PP
987 ret = -EINVAL;
988 goto end;
989 }
990
991 switch (unary_expr->u.unary_expression.type) {
992 case UNARY_UNSIGNED_CONSTANT:
993 ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0);
994 break;
995 case UNARY_SIGNED_CONSTANT:
996 ret = (unary_expr->u.unary_expression.u.signed_constant != 0);
997 break;
998 case UNARY_STRING:
999 {
1000 const char *str = unary_expr->u.unary_expression.u.string;
1001
1002 if (!strcmp(str, "true") || !strcmp(str, "TRUE")) {
1003 ret = TRUE;
1004 } else if (!strcmp(str, "false") || !strcmp(str, "FALSE")) {
1005 ret = FALSE;
1006 } else {
28973adf
PP
1007 _BT_LOGE_NODE(unary_expr,
1008 "Unexpected boolean value: value=\"%s\"", str);
e98a2d6e
PP
1009 ret = -EINVAL;
1010 goto end;
1011 }
1012 break;
1013 }
1014 default:
28973adf
PP
1015 _BT_LOGE_NODE(unary_expr,
1016 "Unexpected unary expression type: node-type=%d",
08da4f77 1017 unary_expr->u.unary_expression.type);
e98a2d6e
PP
1018 ret = -EINVAL;
1019 goto end;
1020 }
1021
1022end:
1023 return ret;
1024}
1025
1026static
55314f2a 1027enum bt_ctf_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
e98a2d6e
PP
1028{
1029 const char *str;
1030 enum bt_ctf_byte_order bo = BT_CTF_BYTE_ORDER_UNKNOWN;
1031
1032 if (unary_expr->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
1033 _BT_LOGE_NODE(unary_expr,
1034 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
e98a2d6e
PP
1035 goto end;
1036 }
1037
1038 str = unary_expr->u.unary_expression.u.string;
1039
1040 if (!strcmp(str, "be") || !strcmp(str, "network")) {
1041 bo = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1042 } else if (!strcmp(str, "le")) {
1043 bo = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
1044 } else if (!strcmp(str, "native")) {
1045 bo = BT_CTF_BYTE_ORDER_NATIVE;
1046 } else {
28973adf
PP
1047 _BT_LOGE_NODE(unary_expr,
1048 "Unexpected \"byte_order\" attribute value: "
08da4f77 1049 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
e98a2d6e
PP
1050 str);
1051 goto end;
1052 }
1053
1054end:
1055 return bo;
1056}
1057
1058static
1059enum bt_ctf_byte_order get_real_byte_order(struct ctx *ctx,
1060 struct ctf_node *uexpr)
1061{
55314f2a 1062 enum bt_ctf_byte_order bo = byte_order_from_unary_expr(uexpr);
e98a2d6e
PP
1063
1064 if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
8a716c8d 1065 bo = bt_ctf_trace_get_native_byte_order(ctx->trace);
e98a2d6e
PP
1066 }
1067
1068 return bo;
1069}
1070
1071static
1072int is_align_valid(uint64_t align)
1073{
1074 return (align != 0) && !(align & (align - 1));
1075}
1076
1077static
1078int get_type_specifier_name(struct ctx *ctx, struct ctf_node *type_specifier,
1079 GString *str)
1080{
1081 int ret = 0;
1082
1083 if (type_specifier->type != NODE_TYPE_SPECIFIER) {
28973adf
PP
1084 _BT_LOGE_NODE(type_specifier,
1085 "Unexpected node type: node-type=%d",
1086 type_specifier->type);
e98a2d6e
PP
1087 ret = -EINVAL;
1088 goto end;
1089 }
1090
1091 switch (type_specifier->u.type_specifier.type) {
1092 case TYPESPEC_VOID:
1093 g_string_append(str, "void");
1094 break;
1095 case TYPESPEC_CHAR:
1096 g_string_append(str, "char");
1097 break;
1098 case TYPESPEC_SHORT:
1099 g_string_append(str, "short");
1100 break;
1101 case TYPESPEC_INT:
1102 g_string_append(str, "int");
1103 break;
1104 case TYPESPEC_LONG:
1105 g_string_append(str, "long");
1106 break;
1107 case TYPESPEC_FLOAT:
1108 g_string_append(str, "float");
1109 break;
1110 case TYPESPEC_DOUBLE:
1111 g_string_append(str, "double");
1112 break;
1113 case TYPESPEC_SIGNED:
1114 g_string_append(str, "signed");
1115 break;
1116 case TYPESPEC_UNSIGNED:
1117 g_string_append(str, "unsigned");
1118 break;
1119 case TYPESPEC_BOOL:
1120 g_string_append(str, "bool");
1121 break;
1122 case TYPESPEC_COMPLEX:
1123 g_string_append(str, "_Complex");
1124 break;
1125 case TYPESPEC_IMAGINARY:
1126 g_string_append(str, "_Imaginary");
1127 break;
1128 case TYPESPEC_CONST:
1129 g_string_append(str, "const");
1130 break;
1131 case TYPESPEC_ID_TYPE:
1132 if (type_specifier->u.type_specifier.id_type) {
1133 g_string_append(str,
1134 type_specifier->u.type_specifier.id_type);
1135 }
1136 break;
1137 case TYPESPEC_STRUCT:
1138 {
1139 struct ctf_node *node = type_specifier->u.type_specifier.node;
1140
1141 if (!node->u._struct.name) {
28973adf 1142 _BT_LOGE_NODE(node, "Unexpected empty structure field type name.");
e98a2d6e
PP
1143 ret = -EINVAL;
1144 goto end;
1145 }
1146
1147 g_string_append(str, "struct ");
1148 g_string_append(str, node->u._struct.name);
1149 break;
1150 }
1151 case TYPESPEC_VARIANT:
1152 {
1153 struct ctf_node *node = type_specifier->u.type_specifier.node;
1154
1155 if (!node->u.variant.name) {
28973adf 1156 _BT_LOGE_NODE(node, "Unexpected empty variant field type name.");
e98a2d6e
PP
1157 ret = -EINVAL;
1158 goto end;
1159 }
1160
1161 g_string_append(str, "variant ");
1162 g_string_append(str, node->u.variant.name);
1163 break;
1164 }
1165 case TYPESPEC_ENUM:
1166 {
1167 struct ctf_node *node = type_specifier->u.type_specifier.node;
1168
1169 if (!node->u._enum.enum_id) {
28973adf
PP
1170 _BT_LOGE_NODE(node,
1171 "Unexpected empty enumeration field type (`enum`) name.");
e98a2d6e
PP
1172 ret = -EINVAL;
1173 goto end;
1174 }
1175
1176 g_string_append(str, "enum ");
1177 g_string_append(str, node->u._enum.enum_id);
1178 break;
1179 }
1180 case TYPESPEC_FLOATING_POINT:
1181 case TYPESPEC_INTEGER:
1182 case TYPESPEC_STRING:
1183 default:
28973adf
PP
1184 _BT_LOGE_NODE(type_specifier->u.type_specifier.node,
1185 "Unexpected type specifier type: %d",
08da4f77 1186 type_specifier->u.type_specifier.type);
e98a2d6e
PP
1187 ret = -EINVAL;
1188 goto end;
1189 }
1190
1191end:
1192 return ret;
1193}
1194
1195static
1196int get_type_specifier_list_name(struct ctx *ctx,
1197 struct ctf_node *type_specifier_list, GString *str)
1198{
502b0402 1199 int ret = 0;
e98a2d6e
PP
1200 struct ctf_node *iter;
1201 int alias_item_nr = 0;
1202 struct bt_list_head *head =
1203 &type_specifier_list->u.type_specifier_list.head;
1204
1205 bt_list_for_each_entry(iter, head, siblings) {
1206 if (alias_item_nr != 0) {
1207 g_string_append(str, " ");
1208 }
1209
1210 alias_item_nr++;
1211 ret = get_type_specifier_name(ctx, iter, str);
1212 if (ret) {
1213 goto end;
1214 }
1215 }
1216
1217end:
1218 return ret;
1219}
1220
1221static
1222GQuark create_typealias_identifier(struct ctx *ctx,
1223 struct ctf_node *type_specifier_list,
1224 struct ctf_node *node_type_declarator)
1225{
1226 int ret;
1227 char *str_c;
1228 GString *str;
1229 GQuark qalias = 0;
1230 struct ctf_node *iter;
1231 struct bt_list_head *pointers =
1232 &node_type_declarator->u.type_declarator.pointers;
1233
1234 str = g_string_new("");
1235 ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
1236 if (ret) {
1237 g_string_free(str, TRUE);
1238 goto end;
1239 }
1240
1241 bt_list_for_each_entry(iter, pointers, siblings) {
1242 g_string_append(str, " *");
1243
1244 if (iter->u.pointer.const_qualifier) {
1245 g_string_append(str, " const");
1246 }
1247 }
1248
1249 str_c = g_string_free(str, FALSE);
1250 qalias = g_quark_from_string(str_c);
1251 g_free(str_c);
1252
1253end:
1254 return qalias;
1255}
1256
1257static
1258int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
1259 GQuark *field_name, struct ctf_node *node_type_declarator,
1260 struct bt_ctf_field_type **field_decl,
1261 struct bt_ctf_field_type *nested_decl)
1262{
1263 /*
1264 * During this whole function, nested_decl is always OURS,
1265 * whereas field_decl is an output which we create, but
1266 * belongs to the caller (it is moved).
1267 */
1268
1269 int ret = 0;
1270 *field_decl = NULL;
1271
1272 /* Validate type declarator node */
1273 if (node_type_declarator) {
1274 if (node_type_declarator->u.type_declarator.type ==
1275 TYPEDEC_UNKNOWN) {
28973adf
PP
1276 _BT_LOGE_NODE(node_type_declarator,
1277 "Unexpected type declarator type: type=%d",
08da4f77 1278 node_type_declarator->u.type_declarator.type);
e98a2d6e
PP
1279 ret = -EINVAL;
1280 goto error;
1281 }
1282
1283 /* TODO: GCC bitfields not supported yet */
1284 if (node_type_declarator->u.type_declarator.bitfield_len !=
1285 NULL) {
28973adf
PP
1286 _BT_LOGE_NODE(node_type_declarator,
1287 "GCC bitfields are not supported as of this version.");
e98a2d6e
PP
1288 ret = -EPERM;
1289 goto error;
1290 }
1291 }
1292
1293 /* Find the right nested declaration if not provided */
1294 if (!nested_decl) {
1295 struct bt_list_head *pointers =
1296 &node_type_declarator->u.type_declarator.pointers;
1297
1298 if (node_type_declarator && !bt_list_empty(pointers)) {
1299 GQuark qalias;
1300 _BT_CTF_FIELD_TYPE_INIT(nested_decl_copy);
1301
1302 /*
1303 * If we have a pointer declarator, it HAS to
1304 * be present in the typealiases (else fail).
1305 */
1306 qalias = create_typealias_identifier(ctx,
1307 type_specifier_list, node_type_declarator);
1308 nested_decl =
1309 ctx_decl_scope_lookup_alias(ctx->current_scope,
1310 g_quark_to_string(qalias), -1);
1311 if (!nested_decl) {
28973adf
PP
1312 _BT_LOGE_NODE(node_type_declarator,
1313 "Cannot find type alias: name=\"%s\"",
e98a2d6e
PP
1314 g_quark_to_string(qalias));
1315 ret = -EINVAL;
1316 goto error;
1317 }
1318
1319 /* Make a copy of it */
1320 nested_decl_copy = bt_ctf_field_type_copy(nested_decl);
1321 BT_PUT(nested_decl);
1322 if (!nested_decl_copy) {
28973adf
PP
1323 _BT_LOGE_NODE(node_type_declarator,
1324 "Cannot copy nested field type.");
e98a2d6e
PP
1325 ret = -EINVAL;
1326 goto error;
1327 }
1328
1329 BT_MOVE(nested_decl, nested_decl_copy);
1330
1331 /* Force integer's base to 16 since it's a pointer */
1332 if (bt_ctf_field_type_is_integer(nested_decl)) {
28973adf
PP
1333 ret = bt_ctf_field_type_integer_set_base(
1334 nested_decl,
e98a2d6e 1335 BT_CTF_INTEGER_BASE_HEXADECIMAL);
28973adf 1336 assert(ret == 0);
e98a2d6e
PP
1337 }
1338 } else {
1339 ret = visit_type_specifier_list(ctx,
1340 type_specifier_list, &nested_decl);
1341 if (ret) {
1342 assert(!nested_decl);
1343 goto error;
1344 }
1345 }
1346 }
1347
1348 assert(nested_decl);
1349
1350 if (!node_type_declarator) {
1351 BT_MOVE(*field_decl, nested_decl);
1352 goto end;
1353 }
1354
1355 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
1356 if (node_type_declarator->u.type_declarator.u.id) {
1357 const char *id =
1358 node_type_declarator->u.type_declarator.u.id;
1359
1360 *field_name = g_quark_from_string(id);
1361 } else {
1362 *field_name = 0;
1363 }
1364
1365 BT_MOVE(*field_decl, nested_decl);
1366 goto end;
1367 } else {
1368 struct ctf_node *first;
1369 _BT_CTF_FIELD_TYPE_INIT(decl);
1370 _BT_CTF_FIELD_TYPE_INIT(outer_field_decl);
1371 struct bt_list_head *length =
1372 &node_type_declarator->
1373 u.type_declarator.u.nested.length;
1374
1375 /* Create array/sequence, pass nested_decl as child */
1376 if (bt_list_empty(length)) {
28973adf
PP
1377 _BT_LOGE_NODE(node_type_declarator,
1378 "Expecting length field reference or value.");
e98a2d6e
PP
1379 ret = -EINVAL;
1380 goto error;
1381 }
1382
1383 first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings);
1384 if (first->type != NODE_UNARY_EXPRESSION) {
28973adf
PP
1385 _BT_LOGE_NODE(first,
1386 "Unexpected node type: node-type=%d",
1387 first->type);
e98a2d6e
PP
1388 ret = -EINVAL;
1389 goto error;
1390 }
1391
1392 switch (first->u.unary_expression.type) {
1393 case UNARY_UNSIGNED_CONSTANT:
1394 {
1395 size_t len;
1396 _BT_CTF_FIELD_TYPE_INIT(array_decl);
1397
1398 len = first->u.unary_expression.u.unsigned_constant;
1399 array_decl = bt_ctf_field_type_array_create(nested_decl,
1400 len);
1401 BT_PUT(nested_decl);
1402 if (!array_decl) {
28973adf
PP
1403 _BT_LOGE_NODE(first,
1404 "Cannot create array field type.");
e98a2d6e
PP
1405 ret = -ENOMEM;
1406 goto error;
1407 }
1408
1409 BT_MOVE(decl, array_decl);
1410 break;
1411 }
1412 case UNARY_STRING:
1413 {
1414 /* Lookup unsigned integer definition, create seq. */
1415 _BT_CTF_FIELD_TYPE_INIT(seq_decl);
1416 char *length_name = concatenate_unary_strings(length);
1417
1418 if (!length_name) {
28973adf
PP
1419 _BT_LOGE_NODE(node_type_declarator,
1420 "Cannot concatenate unary strings.");
e98a2d6e
PP
1421 ret = -EINVAL;
1422 goto error;
1423 }
1424
1425 seq_decl = bt_ctf_field_type_sequence_create(
1426 nested_decl, length_name);
1427 g_free(length_name);
1428 BT_PUT(nested_decl);
1429 if (!seq_decl) {
28973adf
PP
1430 _BT_LOGE_NODE(node_type_declarator,
1431 "Cannot create sequence field type.");
e98a2d6e
PP
1432 ret = -ENOMEM;
1433 goto error;
1434 }
1435
1436 BT_MOVE(decl, seq_decl);
1437 break;
1438 }
1439 default:
1440 ret = -EINVAL;
1441 goto error;
1442 }
1443
1444 assert(!nested_decl);
1445 assert(decl);
1446 assert(!*field_decl);
1447
1448 /*
1449 * At this point, we found the next nested declaration.
1450 * We currently own this (and lost the ownership of
1451 * nested_decl in the meantime). Pass this next
1452 * nested declaration as the content of the outer
1453 * container, MOVING its ownership.
1454 */
1455 ret = visit_type_declarator(ctx, type_specifier_list,
1456 field_name,
1457 node_type_declarator->
1458 u.type_declarator.u.nested.type_declarator,
1459 &outer_field_decl, decl);
1460 decl = NULL;
1461 if (ret) {
1462 assert(!outer_field_decl);
1463 ret = -EINVAL;
1464 goto error;
1465 }
1466
1467 assert(outer_field_decl);
1468 BT_MOVE(*field_decl, outer_field_decl);
1469 }
1470
1471end:
1472 BT_PUT(nested_decl);
1473 assert(*field_decl);
1474
1475 return 0;
1476
1477error:
1478 BT_PUT(nested_decl);
1479 BT_PUT(*field_decl);
1480
1481 return ret;
1482}
1483
1484static
1485int visit_struct_decl_field(struct ctx *ctx,
1486 struct bt_ctf_field_type *struct_decl,
1487 struct ctf_node *type_specifier_list,
1488 struct bt_list_head *type_declarators)
1489{
1490 int ret = 0;
1491 struct ctf_node *iter;
1492 _BT_CTF_FIELD_TYPE_INIT(field_decl);
1493
1494 bt_list_for_each_entry(iter, type_declarators, siblings) {
1495 field_decl = NULL;
1496 GQuark qfield_name;
1497 const char *field_name;
1498 _BT_CTF_FIELD_TYPE_INIT(efield_decl);
1499
1500 ret = visit_type_declarator(ctx, type_specifier_list,
1501 &qfield_name, iter, &field_decl, NULL);
1502 if (ret) {
1503 assert(!field_decl);
28973adf
PP
1504 _BT_LOGE_NODE(type_specifier_list,
1505 "Cannot visit type declarator: ret=%d", ret);
e98a2d6e
PP
1506 goto error;
1507 }
1508
1509 assert(field_decl);
1510 field_name = g_quark_to_string(qfield_name);
1511
1512 /* Check if field with same name already exists */
1513 efield_decl =
1514 bt_ctf_field_type_structure_get_field_type_by_name(
1515 struct_decl, field_name);
1516 if (efield_decl) {
1517 BT_PUT(efield_decl);
28973adf
PP
1518 _BT_LOGE_NODE(type_specifier_list,
1519 "Duplicate field in structure field type: "
08da4f77 1520 "field-name=\"%s\"", field_name);
e98a2d6e
PP
1521 ret = -EINVAL;
1522 goto error;
1523 }
1524
1525 /* Add field to structure */
1526 ret = bt_ctf_field_type_structure_add_field(struct_decl,
1527 field_decl, field_name);
1528 BT_PUT(field_decl);
1529 if (ret) {
28973adf
PP
1530 _BT_LOGE_NODE(type_specifier_list,
1531 "Cannot add field to structure field type: "
08da4f77
PP
1532 "field-name=\"%s\", ret=%d",
1533 g_quark_to_string(qfield_name), ret);
e98a2d6e
PP
1534 goto error;
1535 }
1536 }
1537
1538 return 0;
1539
1540error:
1541 BT_PUT(field_decl);
1542
1543 return ret;
1544}
1545
1546static
1547int visit_variant_decl_field(struct ctx *ctx,
1548 struct bt_ctf_field_type *variant_decl,
1549 struct ctf_node *type_specifier_list,
1550 struct bt_list_head *type_declarators)
1551{
1552 int ret = 0;
1553 struct ctf_node *iter;
1554 _BT_CTF_FIELD_TYPE_INIT(field_decl);
1555
1556 bt_list_for_each_entry(iter, type_declarators, siblings) {
1557 field_decl = NULL;
1558 GQuark qfield_name;
1559 const char *field_name;
1560 _BT_CTF_FIELD_TYPE_INIT(efield_decl);
1561
1562 ret = visit_type_declarator(ctx, type_specifier_list,
1563 &qfield_name, iter, &field_decl, NULL);
1564 if (ret) {
1565 assert(!field_decl);
28973adf
PP
1566 _BT_LOGE_NODE(type_specifier_list,
1567 "Cannot visit type declarator: ret=%d", ret);
e98a2d6e
PP
1568 goto error;
1569 }
1570
1571 assert(field_decl);
1572 field_name = g_quark_to_string(qfield_name);
1573
1574 /* Check if field with same name already exists */
1575 efield_decl =
1576 bt_ctf_field_type_variant_get_field_type_by_name(
1577 variant_decl, field_name);
1578 if (efield_decl) {
1579 BT_PUT(efield_decl);
28973adf
PP
1580 _BT_LOGE_NODE(type_specifier_list,
1581 "Duplicate field in variant field type: "
08da4f77 1582 "field-name=\"%s\"", field_name);
e98a2d6e
PP
1583 ret = -EINVAL;
1584 goto error;
1585 }
1586
1587 /* Add field to structure */
1588 ret = bt_ctf_field_type_variant_add_field(variant_decl,
1589 field_decl, field_name);
1590 BT_PUT(field_decl);
1591 if (ret) {
28973adf
PP
1592 _BT_LOGE_NODE(type_specifier_list,
1593 "Cannot add field to variant field type: "
08da4f77
PP
1594 "field-name=\"%s\", ret=%d",
1595 g_quark_to_string(qfield_name), ret);
e98a2d6e
PP
1596 goto error;
1597 }
1598 }
1599
1600 return 0;
1601
1602error:
1603 BT_PUT(field_decl);
1604
1605 return ret;
1606}
1607
1608static
1609int visit_typedef(struct ctx *ctx, struct ctf_node *type_specifier_list,
1610 struct bt_list_head *type_declarators)
1611{
1612 int ret = 0;
1613 GQuark qidentifier;
1614 struct ctf_node *iter;
1615 _BT_CTF_FIELD_TYPE_INIT(type_decl);
1616
1617 bt_list_for_each_entry(iter, type_declarators, siblings) {
1618 ret = visit_type_declarator(ctx, type_specifier_list,
1619 &qidentifier, iter, &type_decl, NULL);
1620 if (ret) {
28973adf
PP
1621 _BT_LOGE_NODE(iter,
1622 "Cannot visit type declarator: ret=%d", ret);
e98a2d6e
PP
1623 ret = -EINVAL;
1624 goto end;
1625 }
1626
1627 /* Do not allow typedef and typealias of untagged variants */
1628 if (bt_ctf_field_type_is_variant(type_decl)) {
1629 if (bt_ctf_field_type_variant_get_tag_name(type_decl)) {
28973adf
PP
1630 _BT_LOGE_NODE(iter,
1631 "Type definition of untagged variant field type is not allowed.");
e98a2d6e
PP
1632 ret = -EPERM;
1633 goto end;
1634 }
1635 }
1636
1637 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1638 g_quark_to_string(qidentifier), type_decl);
1639 if (ret) {
28973adf
PP
1640 _BT_LOGE_NODE(iter,
1641 "Cannot register type definition: name=\"%s\"",
e98a2d6e
PP
1642 g_quark_to_string(qidentifier));
1643 goto end;
1644 }
1645 }
1646
1647end:
1648 BT_PUT(type_decl);
1649
1650 return ret;
1651}
1652
1653static
1654int visit_typealias(struct ctx *ctx, struct ctf_node *target,
1655 struct ctf_node *alias)
1656{
1657 int ret = 0;
1658 GQuark qalias;
1659 struct ctf_node *node;
1660 GQuark qdummy_field_name;
1661 _BT_CTF_FIELD_TYPE_INIT(type_decl);
1662
1663 /* Create target type declaration */
1664 if (bt_list_empty(&target->u.typealias_target.type_declarators)) {
1665 node = NULL;
1666 } else {
1667 node = _BT_LIST_FIRST_ENTRY(
1668 &target->u.typealias_target.type_declarators,
1669 struct ctf_node, siblings);
1670 }
1671
1672 ret = visit_type_declarator(ctx,
1673 target->u.typealias_target.type_specifier_list,
1674 &qdummy_field_name, node, &type_decl, NULL);
1675 if (ret) {
1676 assert(!type_decl);
28973adf
PP
1677 _BT_LOGE_NODE(node,
1678 "Cannot visit type declarator: ret=%d", ret);
e98a2d6e
PP
1679 goto end;
1680 }
1681
1682 /* Do not allow typedef and typealias of untagged variants */
1683 if (bt_ctf_field_type_is_variant(type_decl)) {
1684 if (bt_ctf_field_type_variant_get_tag_name(type_decl)) {
28973adf
PP
1685 _BT_LOGE_NODE(node,
1686 "Type definition of untagged variant field type is not allowed.");
e98a2d6e
PP
1687 ret = -EPERM;
1688 goto end;
1689 }
1690 }
1691
1692 /*
1693 * The semantic validator does not check whether the target is
1694 * abstract or not (if it has an identifier). Check it here.
1695 */
1696 if (qdummy_field_name != 0) {
28973adf
PP
1697 _BT_LOGE_NODE(node,
1698 "Expecting empty identifier: id=\"%s\"",
08da4f77 1699 g_quark_to_string(qdummy_field_name));
e98a2d6e
PP
1700 ret = -EINVAL;
1701 goto end;
1702 }
1703
1704 /* Create alias identifier */
1705 node = _BT_LIST_FIRST_ENTRY(&alias->u.typealias_alias.type_declarators,
1706 struct ctf_node, siblings);
1707 qalias = create_typealias_identifier(ctx,
1708 alias->u.typealias_alias.type_specifier_list, node);
1709 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1710 g_quark_to_string(qalias), type_decl);
1711 if (ret) {
28973adf
PP
1712 _BT_LOGE_NODE(node,
1713 "Cannot register type alias: name=\"%s\"",
e98a2d6e
PP
1714 g_quark_to_string(qalias));
1715 goto end;
1716 }
1717
1718end:
1719 BT_PUT(type_decl);
1720
1721 return ret;
1722}
1723
1724static
1725int visit_struct_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1726 struct bt_ctf_field_type *struct_decl)
1727{
1728 int ret = 0;
1729
1730 switch (entry_node->type) {
1731 case NODE_TYPEDEF:
1732 ret = visit_typedef(ctx,
1733 entry_node->u._typedef.type_specifier_list,
1734 &entry_node->u._typedef.type_declarators);
1735 if (ret) {
28973adf
PP
1736 _BT_LOGE_NODE(entry_node,
1737 "Cannot add type definition found in structure field type: ret=%d",
08da4f77 1738 ret);
e98a2d6e
PP
1739 goto end;
1740 }
1741 break;
1742 case NODE_TYPEALIAS:
1743 ret = visit_typealias(ctx, entry_node->u.typealias.target,
1744 entry_node->u.typealias.alias);
1745 if (ret) {
28973adf
PP
1746 _BT_LOGE_NODE(entry_node,
1747 "Cannot add type alias found in structure field type: ret=%d",
08da4f77 1748 ret);
e98a2d6e
PP
1749 goto end;
1750 }
1751 break;
1752 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1753 /* Field */
1754 ret = visit_struct_decl_field(ctx, struct_decl,
1755 entry_node->u.struct_or_variant_declaration.
1756 type_specifier_list,
1757 &entry_node->u.struct_or_variant_declaration.
1758 type_declarators);
1759 if (ret) {
1760 goto end;
1761 }
1762 break;
1763 default:
28973adf
PP
1764 _BT_LOGE_NODE(entry_node,
1765 "Unexpected node type: node-type=%d", entry_node->type);
e98a2d6e
PP
1766 ret = -EINVAL;
1767 goto end;
1768 }
1769
1770end:
1771 return ret;
1772}
1773
1774static
1775int visit_variant_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1776 struct bt_ctf_field_type *variant_decl)
1777{
1778 int ret = 0;
1779
1780 switch (entry_node->type) {
1781 case NODE_TYPEDEF:
1782 ret = visit_typedef(ctx,
1783 entry_node->u._typedef.type_specifier_list,
1784 &entry_node->u._typedef.type_declarators);
1785 if (ret) {
28973adf
PP
1786 _BT_LOGE_NODE(entry_node,
1787 "Cannot add type definition found in variant field type: ret=%d",
08da4f77 1788 ret);
e98a2d6e
PP
1789 goto end;
1790 }
1791 break;
1792 case NODE_TYPEALIAS:
1793 ret = visit_typealias(ctx, entry_node->u.typealias.target,
1794 entry_node->u.typealias.alias);
1795 if (ret) {
28973adf
PP
1796 _BT_LOGE_NODE(entry_node,
1797 "Cannot add type alias found in variant field type: ret=%d",
08da4f77 1798 ret);
e98a2d6e
PP
1799 goto end;
1800 }
1801 break;
1802 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1803 /* Field */
1804 ret = visit_variant_decl_field(ctx, variant_decl,
1805 entry_node->u.struct_or_variant_declaration.
1806 type_specifier_list,
1807 &entry_node->u.struct_or_variant_declaration.
1808 type_declarators);
1809 if (ret) {
1810 goto end;
1811 }
1812 break;
1813 default:
28973adf
PP
1814 _BT_LOGE_NODE(entry_node,
1815 "Unexpected node type: node-type=%d",
08da4f77 1816 entry_node->type);
e98a2d6e
PP
1817 ret = -EINVAL;
1818 goto end;
1819 }
1820
1821end:
1822 return ret;
1823}
1824
1825static
1826int visit_struct_decl(struct ctx *ctx, const char *name,
1827 struct bt_list_head *decl_list, int has_body,
1828 struct bt_list_head *min_align,
1829 struct bt_ctf_field_type **struct_decl)
1830{
1831 int ret = 0;
1832
1833 *struct_decl = NULL;
1834
1835 /* For named struct (without body), lookup in declaration scope */
1836 if (!has_body) {
1837 _BT_CTF_FIELD_TYPE_INIT(struct_decl_copy);
1838
1839 if (!name) {
28973adf 1840 BT_LOGE_STR("Bodyless structure field type: missing name.");
e98a2d6e
PP
1841 ret = -EPERM;
1842 goto error;
1843 }
1844
1845 *struct_decl = ctx_decl_scope_lookup_struct(ctx->current_scope,
1846 name, -1);
1847 if (!*struct_decl) {
08da4f77
PP
1848 BT_LOGE("Cannot find structure field type: name=\"struct %s\"",
1849 name);
e98a2d6e
PP
1850 ret = -EINVAL;
1851 goto error;
1852 }
1853
1854 /* Make a copy of it */
1855 struct_decl_copy = bt_ctf_field_type_copy(*struct_decl);
1856 if (!struct_decl_copy) {
08da4f77 1857 BT_LOGE_STR("Cannot create copy of structure field type.");
e98a2d6e
PP
1858 ret = -EINVAL;
1859 goto error;
1860 }
1861
1862 BT_MOVE(*struct_decl, struct_decl_copy);
1863 } else {
1864 struct ctf_node *entry_node;
1865 uint64_t min_align_value = 0;
1866
1867 if (name) {
1868 _BT_CTF_FIELD_TYPE_INIT(estruct_decl);
1869
1870 estruct_decl = ctx_decl_scope_lookup_struct(
1871 ctx->current_scope, name, 1);
1872 if (estruct_decl) {
1873 BT_PUT(estruct_decl);
08da4f77
PP
1874 BT_LOGE("Structure field type already declared in local scope: "
1875 "name=\"struct %s\"", name);
e98a2d6e
PP
1876 ret = -EINVAL;
1877 goto error;
1878 }
1879 }
1880
1881 if (!bt_list_empty(min_align)) {
1882 ret = get_unary_unsigned(min_align, &min_align_value);
1883 if (ret) {
08da4f77
PP
1884 BT_LOGE("Unexpected unary expression for structure field type's `align` attribute: "
1885 "ret=%d", ret);
e98a2d6e
PP
1886 goto error;
1887 }
1888 }
1889
1890 *struct_decl = bt_ctf_field_type_structure_create();
1891 if (!*struct_decl) {
08da4f77 1892 BT_LOGE_STR("Cannot create empty structure field type.");
e98a2d6e
PP
1893 ret = -ENOMEM;
1894 goto error;
1895 }
1896
539fd01b
JG
1897 if (min_align_value != 0) {
1898 ret = bt_ctf_field_type_set_alignment(*struct_decl,
1899 min_align_value);
1900 if (ret) {
08da4f77
PP
1901 BT_LOGE("Cannot set structure field type's alignment: "
1902 "ret=%d", ret);
539fd01b
JG
1903 goto error;
1904 }
1905 }
1906
e98a2d6e
PP
1907 ret = ctx_push_scope(ctx);
1908 if (ret) {
08da4f77 1909 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
1910 goto error;
1911 }
1912
1913 bt_list_for_each_entry(entry_node, decl_list, siblings) {
1914 ret = visit_struct_decl_entry(ctx, entry_node,
1915 *struct_decl);
1916 if (ret) {
28973adf
PP
1917 _BT_LOGE_NODE(entry_node,
1918 "Cannot visit structure field type entry: "
1919 "ret=%d", ret);
e98a2d6e
PP
1920 ctx_pop_scope(ctx);
1921 goto error;
1922 }
1923 }
1924
1925 ctx_pop_scope(ctx);
1926
1927 if (name) {
1928 ret = ctx_decl_scope_register_struct(ctx->current_scope,
1929 name, *struct_decl);
1930 if (ret) {
08da4f77
PP
1931 BT_LOGE("Cannot register structure field type in declaration scope: "
1932 "name=\"struct %s\", ret=%d", name, ret);
e98a2d6e
PP
1933 goto error;
1934 }
1935 }
1936 }
1937
1938 return 0;
1939
1940error:
1941 BT_PUT(*struct_decl);
1942
1943 return ret;
1944}
1945
1946static
1947int visit_variant_decl(struct ctx *ctx, const char *name,
1948 const char *tag, struct bt_list_head *decl_list,
1949 int has_body, struct bt_ctf_field_type **variant_decl)
1950{
1951 int ret = 0;
1952 _BT_CTF_FIELD_TYPE_INIT(untagged_variant_decl);
1953
1954 *variant_decl = NULL;
1955
1956 /* For named variant (without body), lookup in declaration scope */
1957 if (!has_body) {
1958 _BT_CTF_FIELD_TYPE_INIT(variant_decl_copy);
1959
1960 if (!name) {
28973adf 1961 BT_LOGE_STR("Bodyless variant field type: missing name.");
e98a2d6e
PP
1962 ret = -EPERM;
1963 goto error;
1964 }
1965
1966 untagged_variant_decl =
1967 ctx_decl_scope_lookup_variant(ctx->current_scope,
1968 name, -1);
1969 if (!untagged_variant_decl) {
08da4f77
PP
1970 BT_LOGE("Cannot find variant field type: name=\"variant %s\"",
1971 name);
e98a2d6e
PP
1972 ret = -EINVAL;
1973 goto error;
1974 }
1975
1976 /* Make a copy of it */
1977 variant_decl_copy = bt_ctf_field_type_copy(
1978 untagged_variant_decl);
1979 if (!variant_decl_copy) {
08da4f77 1980 BT_LOGE_STR("Cannot create copy of variant field type.");
e98a2d6e
PP
1981 ret = -EINVAL;
1982 goto error;
1983 }
1984
1985 BT_MOVE(untagged_variant_decl, variant_decl_copy);
1986 } else {
1987 struct ctf_node *entry_node;
1988
1989 if (name) {
1990 struct bt_ctf_field_type *evariant_decl =
1991 ctx_decl_scope_lookup_struct(ctx->current_scope,
1992 name, 1);
1993
1994 if (evariant_decl) {
1995 BT_PUT(evariant_decl);
08da4f77
PP
1996 BT_LOGE("Variant field type already declared in local scope: "
1997 "name=\"variant %s\"", name);
e98a2d6e
PP
1998 ret = -EINVAL;
1999 goto error;
2000 }
2001 }
2002
2003 untagged_variant_decl = bt_ctf_field_type_variant_create(NULL,
2004 NULL);
2005 if (!untagged_variant_decl) {
08da4f77 2006 BT_LOGE_STR("Cannot create empty variant field type.");
e98a2d6e
PP
2007 ret = -ENOMEM;
2008 goto error;
2009 }
2010
2011 ret = ctx_push_scope(ctx);
2012 if (ret) {
08da4f77 2013 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
2014 goto error;
2015 }
2016
2017 bt_list_for_each_entry(entry_node, decl_list, siblings) {
2018 ret = visit_variant_decl_entry(ctx, entry_node,
2019 untagged_variant_decl);
2020 if (ret) {
28973adf
PP
2021 _BT_LOGE_NODE(entry_node,
2022 "Cannot visit variant field type entry: "
2023 "ret=%d", ret);
e98a2d6e
PP
2024 ctx_pop_scope(ctx);
2025 goto error;
2026 }
2027 }
2028
2029 ctx_pop_scope(ctx);
2030
2031 if (name) {
2032 ret = ctx_decl_scope_register_variant(
2033 ctx->current_scope, name,
2034 untagged_variant_decl);
2035 if (ret) {
08da4f77
PP
2036 BT_LOGE("Cannot register variant field type in declaration scope: "
2037 "name=\"variant %s\", ret=%d", name, ret);
e98a2d6e
PP
2038 goto error;
2039 }
2040 }
2041 }
2042
2043 /*
2044 * If tagged, create tagged variant and return; otherwise
2045 * return untagged variant.
2046 */
2047 if (!tag) {
2048 BT_MOVE(*variant_decl, untagged_variant_decl);
2049 } else {
2050 /*
2051 * At this point, we have a fresh untagged variant; nobody
2052 * else owns it. Set its tag now.
2053 */
2054 ret = bt_ctf_field_type_variant_set_tag_name(
2055 untagged_variant_decl, tag);
2056 if (ret) {
28973adf
PP
2057 BT_LOGE("Cannot set variant field type's tag name: "
2058 "tag-name=\"%s\"", tag);
e98a2d6e
PP
2059 goto error;
2060 }
2061
2062 BT_MOVE(*variant_decl, untagged_variant_decl);
2063 }
2064
2065 assert(!untagged_variant_decl);
2066 assert(*variant_decl);
2067
2068 return 0;
2069
2070error:
2071 BT_PUT(untagged_variant_decl);
2072 BT_PUT(*variant_decl);
2073
2074 return ret;
2075}
2076
2077static
2078int visit_enum_decl_entry(struct ctx *ctx, struct ctf_node *enumerator,
2079 struct bt_ctf_field_type *enum_decl, int64_t *last, int is_signed)
2080{
2081 int ret = 0;
2082 int nr_vals = 0;
2083 struct ctf_node *iter;
2084 int64_t start = 0, end = 0;
2085 const char *label = enumerator->u.enumerator.id;
2086 struct bt_list_head *values = &enumerator->u.enumerator.values;
2087
2088 bt_list_for_each_entry(iter, values, siblings) {
2089 int64_t *target;
2090
2091 if (iter->type != NODE_UNARY_EXPRESSION) {
28973adf
PP
2092 _BT_LOGE_NODE(iter,
2093 "Wrong expression for enumeration field type label: "
08da4f77 2094 "node-type=%d, label=\"%s\"", iter->type,
e98a2d6e
PP
2095 label);
2096 ret = -EINVAL;
2097 goto error;
2098 }
2099
2100 if (nr_vals == 0) {
2101 target = &start;
2102 } else {
2103 target = &end;
2104 }
2105
2106 switch (iter->u.unary_expression.type) {
2107 case UNARY_SIGNED_CONSTANT:
2108 *target = iter->u.unary_expression.u.signed_constant;
2109 break;
2110 case UNARY_UNSIGNED_CONSTANT:
2111 *target = (int64_t)
2112 iter->u.unary_expression.u.unsigned_constant;
2113 break;
2114 default:
28973adf
PP
2115 _BT_LOGE_NODE(iter,
2116 "Invalid enumeration field type entry: "
08da4f77
PP
2117 "expecting constant signed or unsigned integer: "
2118 "node-type=%d, label=\"%s\"",
2119 iter->u.unary_expression.type, label);
e98a2d6e
PP
2120 ret = -EINVAL;
2121 goto error;
2122 }
2123
2124 if (nr_vals > 1) {
28973adf
PP
2125 _BT_LOGE_NODE(iter,
2126 "Invalid enumeration field type entry: label=\"%s\"",
e98a2d6e
PP
2127 label);
2128 ret = -EINVAL;
2129 goto error;
2130 }
2131
2132 nr_vals++;
2133 }
2134
2135 if (nr_vals == 0) {
2136 start = *last;
2137 }
2138
2139 if (nr_vals <= 1) {
2140 end = start;
2141 }
2142
2143 *last = end + 1;
2144
2145 if (is_signed) {
2146 ret = bt_ctf_field_type_enumeration_add_mapping(enum_decl, label,
2147 start, end);
2148 } else {
2149 ret = bt_ctf_field_type_enumeration_add_mapping_unsigned(enum_decl,
2150 label, (uint64_t) start, (uint64_t) end);
2151 }
2152 if (ret) {
28973adf
PP
2153 _BT_LOGE_NODE(enumerator,
2154 "Cannot add mapping to enumeration field type: "
08da4f77
PP
2155 "label=\"%s\", ret=%d, "
2156 "start-value-unsigned=%" PRIu64 ", "
2157 "end-value-unsigned=%" PRIu64, label, ret,
2158 (uint64_t) start, (uint64_t) end);
e98a2d6e
PP
2159 goto error;
2160 }
2161
2162 return 0;
2163
2164error:
2165 return ret;
2166}
2167
2168static
2169int visit_enum_decl(struct ctx *ctx, const char *name,
2170 struct ctf_node *container_type,
2171 struct bt_list_head *enumerator_list,
2172 int has_body,
2173 struct bt_ctf_field_type **enum_decl)
2174{
2175 int ret = 0;
2176 GQuark qdummy_id;
2177 _BT_CTF_FIELD_TYPE_INIT(integer_decl);
2178
2179 *enum_decl = NULL;
2180
2181 /* For named enum (without body), lookup in declaration scope */
2182 if (!has_body) {
2183 _BT_CTF_FIELD_TYPE_INIT(enum_decl_copy);
2184
2185 if (!name) {
28973adf 2186 BT_LOGE_STR("Bodyless enumeration field type: missing name.");
e98a2d6e
PP
2187 ret = -EPERM;
2188 goto error;
2189 }
2190
2191 *enum_decl = ctx_decl_scope_lookup_enum(ctx->current_scope,
2192 name, -1);
2193 if (!*enum_decl) {
08da4f77
PP
2194 BT_LOGE("Cannot find enumeration field type: "
2195 "name=\"enum %s\"", name);
e98a2d6e
PP
2196 ret = -EINVAL;
2197 goto error;
2198 }
2199
2200 /* Make a copy of it */
2201 enum_decl_copy = bt_ctf_field_type_copy(*enum_decl);
2202 if (!enum_decl_copy) {
08da4f77 2203 BT_LOGE_STR("Cannot create copy of enumeration field type.");
e98a2d6e
PP
2204 ret = -EINVAL;
2205 goto error;
2206 }
2207
2208 BT_PUT(*enum_decl);
2209 BT_MOVE(*enum_decl, enum_decl_copy);
2210 } else {
2211 struct ctf_node *iter;
2212 int64_t last_value = 0;
2213
2214 if (name) {
2215 _BT_CTF_FIELD_TYPE_INIT(eenum_decl);
2216
2217 eenum_decl = ctx_decl_scope_lookup_enum(
2218 ctx->current_scope, name, 1);
2219 if (eenum_decl) {
2220 BT_PUT(eenum_decl);
08da4f77
PP
2221 BT_LOGE("Enumeration field type already declared in local scope: "
2222 "name=\"enum %s\"", name);
e98a2d6e
PP
2223 ret = -EINVAL;
2224 goto error;
2225 }
2226 }
2227
2228 if (!container_type) {
2229 integer_decl = ctx_decl_scope_lookup_alias(
2230 ctx->current_scope, "int", -1);
2231 if (!integer_decl) {
08da4f77 2232 BT_LOGE_STR("Cannot find implicit `int` field type alias for enumeration field type.");
e98a2d6e
PP
2233 ret = -EINVAL;
2234 goto error;
2235 }
2236 } else {
2237 ret = visit_type_declarator(ctx, container_type,
2238 &qdummy_id, NULL, &integer_decl, NULL);
2239 if (ret) {
2240 assert(!integer_decl);
2241 ret = -EINVAL;
2242 goto error;
2243 }
2244 }
2245
2246 assert(integer_decl);
2247
2248 if (!bt_ctf_field_type_is_integer(integer_decl)) {
08da4f77
PP
2249 BT_LOGE("Container field type for enumeration field type is not an integer field type: "
2250 "ft-id=%s",
2251 bt_ctf_field_type_id_string(
2252 bt_ctf_field_type_get_type_id(integer_decl)));
e98a2d6e
PP
2253 ret = -EINVAL;
2254 goto error;
2255 }
2256
2257 *enum_decl = bt_ctf_field_type_enumeration_create(integer_decl);
2258 if (!*enum_decl) {
08da4f77 2259 BT_LOGE_STR("Cannot create enumeration field type.");
e98a2d6e
PP
2260 ret = -ENOMEM;
2261 goto error;
2262 }
2263
2264 bt_list_for_each_entry(iter, enumerator_list, siblings) {
2265 ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
2266 &last_value,
2267 bt_ctf_field_type_integer_get_signed(integer_decl));
2268 if (ret) {
28973adf
PP
2269 _BT_LOGE_NODE(iter,
2270 "Cannot visit enumeration field type entry: "
2271 "ret=%d", ret);
e98a2d6e
PP
2272 goto error;
2273 }
2274 }
2275
2276 if (name) {
2277 ret = ctx_decl_scope_register_enum(ctx->current_scope,
2278 name, *enum_decl);
2279 if (ret) {
28973adf
PP
2280 BT_LOGE("Cannot register enumeration field type in declaration scope: "
2281 "ret=%d", ret);
e98a2d6e
PP
2282 goto error;
2283 }
2284 }
2285 }
2286
2287 BT_PUT(integer_decl);
2288
2289 return 0;
2290
2291error:
2292 BT_PUT(integer_decl);
2293 BT_PUT(*enum_decl);
2294
2295 return ret;
2296}
2297
2298static
2299int visit_type_specifier(struct ctx *ctx,
2300 struct ctf_node *type_specifier_list,
2301 struct bt_ctf_field_type **decl)
2302{
2303 int ret = 0;
2304 GString *str = NULL;
2305 _BT_CTF_FIELD_TYPE_INIT(decl_copy);
2306
2307 *decl = NULL;
2308 str = g_string_new("");
2309 ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
2310 if (ret) {
28973adf
PP
2311 _BT_LOGE_NODE(type_specifier_list,
2312 "Cannot get type specifier list's name: ret=%d", ret);
e98a2d6e
PP
2313 goto error;
2314 }
2315
2316 *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1);
2317 if (!*decl) {
28973adf
PP
2318 _BT_LOGE_NODE(type_specifier_list,
2319 "Cannot find type alias: name=\"%s\"", str->str);
e98a2d6e
PP
2320 ret = -EINVAL;
2321 goto error;
2322 }
2323
2324 /* Make a copy of the type declaration */
2325 decl_copy = bt_ctf_field_type_copy(*decl);
2326 if (!decl_copy) {
28973adf
PP
2327 _BT_LOGE_NODE(type_specifier_list,
2328 "Cannot create field type copy.");
e98a2d6e
PP
2329 ret = -EINVAL;
2330 goto error;
2331 }
2332
2333 BT_MOVE(*decl, decl_copy);
2334 (void) g_string_free(str, TRUE);
2335 str = NULL;
2336
2337 return 0;
2338
2339error:
2340 if (str) {
2341 (void) g_string_free(str, TRUE);
2342 }
2343
2344 BT_PUT(*decl);
2345
2346 return ret;
2347}
2348
2349static
2350int visit_integer_decl(struct ctx *ctx,
2351 struct bt_list_head *expressions,
2352 struct bt_ctf_field_type **integer_decl)
2353{
2354 int set = 0;
2355 int ret = 0;
2356 int signedness = 0;
2357 struct ctf_node *expression;
2358 uint64_t alignment = 0, size = 0;
ac0c6bdd 2359 struct bt_ctf_clock_class *mapped_clock = NULL;
e98a2d6e
PP
2360 enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_NONE;
2361 enum bt_ctf_integer_base base = BT_CTF_INTEGER_BASE_DECIMAL;
2362 enum bt_ctf_byte_order byte_order =
8a716c8d 2363 bt_ctf_trace_get_native_byte_order(ctx->trace);
e98a2d6e
PP
2364
2365 *integer_decl = NULL;
2366
2367 bt_list_for_each_entry(expression, expressions, siblings) {
2368 struct ctf_node *left, *right;
2369
2370 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2371 struct ctf_node, siblings);
2372 right = _BT_LIST_FIRST_ENTRY(
2373 &expression->u.ctf_expression.right, struct ctf_node,
2374 siblings);
2375
2376 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2377 _BT_LOGE_NODE(left,
2378 "Unexpected unary expression type: type=%d",
2379 left->u.unary_expression.type);
e98a2d6e
PP
2380 ret = -EINVAL;
2381 goto error;
2382 }
2383
2384 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
2385 if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
28973adf 2386 _BT_LOGE_DUP_ATTR(left, "signed",
08da4f77 2387 "integer field type");
e98a2d6e
PP
2388 ret = -EPERM;
2389 goto error;
2390 }
2391
55314f2a 2392 signedness = get_boolean(right);
e98a2d6e 2393 if (signedness < 0) {
28973adf
PP
2394 _BT_LOGE_NODE(right,
2395 "Invalid boolean value for integer field type's `signed` attribute: "
2396 "ret=%d", ret);
e98a2d6e
PP
2397 ret = -EINVAL;
2398 goto error;
2399 }
2400
2401 _SET(&set, _INTEGER_SIGNED_SET);
2402 } else if (!strcmp(left->u.unary_expression.u.string,
2403 "byte_order")) {
2404 if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
28973adf 2405 _BT_LOGE_DUP_ATTR(left, "byte_order",
08da4f77 2406 "integer field type");
e98a2d6e
PP
2407 ret = -EPERM;
2408 goto error;
2409 }
2410
2411 byte_order = get_real_byte_order(ctx, right);
2412 if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
28973adf
PP
2413 _BT_LOGE_NODE(right,
2414 "Invalid `byte_order` attribute in integer field type: "
08da4f77 2415 "ret=%d", ret);
e98a2d6e
PP
2416 ret = -EINVAL;
2417 goto error;
2418 }
2419
2420 _SET(&set, _INTEGER_BYTE_ORDER_SET);
2421 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
2422 if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
28973adf 2423 _BT_LOGE_DUP_ATTR(left, "size",
08da4f77 2424 "integer field type");
e98a2d6e
PP
2425 ret = -EPERM;
2426 goto error;
2427 }
2428
2429 if (right->u.unary_expression.type !=
2430 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2431 _BT_LOGE_NODE(right,
2432 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2433 "expecting unsigned constant integer: "
2434 "node-type=%d",
2435 right->u.unary_expression.type);
e98a2d6e
PP
2436 ret = -EINVAL;
2437 goto error;
2438 }
2439
2440 size = right->u.unary_expression.u.unsigned_constant;
2441 if (size == 0) {
28973adf
PP
2442 _BT_LOGE_NODE(right,
2443 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2444 "expecting positive constant integer: "
2445 "size=%" PRIu64, size);
e98a2d6e
PP
2446 ret = -EINVAL;
2447 goto error;
2448 } else if (size > 64) {
28973adf
PP
2449 _BT_LOGE_NODE(right,
2450 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2451 "integer fields over 64 bits are not supported as of this version: "
2452 "size=%" PRIu64, size);
e98a2d6e
PP
2453 ret = -EINVAL;
2454 goto error;
2455 }
2456
2457 _SET(&set, _INTEGER_SIZE_SET);
2458 } else if (!strcmp(left->u.unary_expression.u.string,
2459 "align")) {
2460 if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
28973adf 2461 _BT_LOGE_DUP_ATTR(left, "align",
08da4f77 2462 "integer field type");
e98a2d6e
PP
2463 ret = -EPERM;
2464 goto error;
2465 }
2466
2467 if (right->u.unary_expression.type !=
2468 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2469 _BT_LOGE_NODE(right,
2470 "Invalid `align` attribute in integer field type: "
08da4f77
PP
2471 "expecting unsigned constant integer: "
2472 "node-type=%d",
2473 right->u.unary_expression.type);
e98a2d6e
PP
2474 ret = -EINVAL;
2475 goto error;
2476 }
2477
2478 alignment =
2479 right->u.unary_expression.u.unsigned_constant;
2480 if (!is_align_valid(alignment)) {
28973adf
PP
2481 _BT_LOGE_NODE(right,
2482 "Invalid `align` attribute in integer field type: "
08da4f77
PP
2483 "expecting power of two: "
2484 "align=%" PRIu64, alignment);
e98a2d6e
PP
2485 ret = -EINVAL;
2486 goto error;
2487 }
2488
2489 _SET(&set, _INTEGER_ALIGN_SET);
2490 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
2491 if (_IS_SET(&set, _INTEGER_BASE_SET)) {
28973adf
PP
2492 _BT_LOGE_DUP_ATTR(left, "base",
2493 "integer field type");
e98a2d6e
PP
2494 ret = -EPERM;
2495 goto error;
2496 }
2497
2498 switch (right->u.unary_expression.type) {
2499 case UNARY_UNSIGNED_CONSTANT:
2500 {
2501 uint64_t constant = right->u.unary_expression.
2502 u.unsigned_constant;
2503
2504 switch (constant) {
2505 case 2:
2506 base = BT_CTF_INTEGER_BASE_BINARY;
2507 break;
2508 case 8:
2509 base = BT_CTF_INTEGER_BASE_OCTAL;
2510 break;
2511 case 10:
2512 base = BT_CTF_INTEGER_BASE_DECIMAL;
2513 break;
2514 case 16:
2515 base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
2516 break;
2517 default:
28973adf
PP
2518 _BT_LOGE_NODE(right,
2519 "Invalid `base` attribute in integer field type: "
08da4f77 2520 "base=%" PRIu64,
e98a2d6e
PP
2521 right->u.unary_expression.u.unsigned_constant);
2522 ret = -EINVAL;
2523 goto error;
2524 }
2525 break;
2526 }
2527 case UNARY_STRING:
2528 {
2529 char *s_right = concatenate_unary_strings(
2530 &expression->u.ctf_expression.right);
2531 if (!s_right) {
28973adf
PP
2532 _BT_LOGE_NODE(right,
2533 "Unexpected unary expression for integer field type's `base` attribute.");
e98a2d6e
PP
2534 ret = -EINVAL;
2535 goto error;
2536 }
2537
2538 if (!strcmp(s_right, "decimal") ||
2539 !strcmp(s_right, "dec") ||
2540 !strcmp(s_right, "d") ||
2541 !strcmp(s_right, "i") ||
2542 !strcmp(s_right, "u")) {
2543 base = BT_CTF_INTEGER_BASE_DECIMAL;
2544 } else if (!strcmp(s_right, "hexadecimal") ||
2545 !strcmp(s_right, "hex") ||
2546 !strcmp(s_right, "x") ||
2547 !strcmp(s_right, "X") ||
2548 !strcmp(s_right, "p")) {
2549 base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
2550 } else if (!strcmp(s_right, "octal") ||
2551 !strcmp(s_right, "oct") ||
2552 !strcmp(s_right, "o")) {
2553 base = BT_CTF_INTEGER_BASE_OCTAL;
2554 } else if (!strcmp(s_right, "binary") ||
2555 !strcmp(s_right, "b")) {
2556 base = BT_CTF_INTEGER_BASE_BINARY;
2557 } else {
28973adf
PP
2558 _BT_LOGE_NODE(right,
2559 "Unexpected unary expression for integer field type's `base` attribute: "
08da4f77 2560 "base=\"%s\"", s_right);
e98a2d6e
PP
2561 g_free(s_right);
2562 ret = -EINVAL;
2563 goto error;
2564 }
2565
2566 g_free(s_right);
2567 break;
2568 }
2569 default:
28973adf
PP
2570 _BT_LOGE_NODE(right,
2571 "Invalid `base` attribute in integer field type: "
08da4f77 2572 "expecting unsigned constant integer or unary string.");
e98a2d6e
PP
2573 ret = -EINVAL;
2574 goto error;
2575 }
2576
2577 _SET(&set, _INTEGER_BASE_SET);
2578 } else if (!strcmp(left->u.unary_expression.u.string,
2579 "encoding")) {
2580 char *s_right;
2581
2582 if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
28973adf 2583 _BT_LOGE_DUP_ATTR(left, "encoding",
08da4f77 2584 "integer field type");
e98a2d6e
PP
2585 ret = -EPERM;
2586 goto error;
2587 }
2588
2589 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2590 _BT_LOGE_NODE(right,
2591 "Invalid `encoding` attribute in integer field type: "
08da4f77 2592 "expecting unary string.");
e98a2d6e
PP
2593 ret = -EINVAL;
2594 goto error;
2595 }
2596
2597 s_right = concatenate_unary_strings(
2598 &expression->u.ctf_expression.right);
2599 if (!s_right) {
28973adf
PP
2600 _BT_LOGE_NODE(right,
2601 "Unexpected unary expression for integer field type's `encoding` attribute.");
e98a2d6e
PP
2602 ret = -EINVAL;
2603 goto error;
2604 }
2605
2606 if (!strcmp(s_right, "UTF8") ||
2607 !strcmp(s_right, "utf8") ||
2608 !strcmp(s_right, "utf-8") ||
2609 !strcmp(s_right, "UTF-8")) {
2610 encoding = BT_CTF_STRING_ENCODING_UTF8;
2611 } else if (!strcmp(s_right, "ASCII") ||
2612 !strcmp(s_right, "ascii")) {
2613 encoding = BT_CTF_STRING_ENCODING_ASCII;
2614 } else if (!strcmp(s_right, "none")) {
2615 encoding = BT_CTF_STRING_ENCODING_NONE;
2616 } else {
28973adf
PP
2617 _BT_LOGE_NODE(right,
2618 "Invalid `encoding` attribute in integer field type: "
08da4f77 2619 "unknown encoding: encoding=\"%s\"",
e98a2d6e
PP
2620 s_right);
2621 g_free(s_right);
2622 ret = -EINVAL;
2623 goto error;
2624 }
2625
2626 g_free(s_right);
2627 _SET(&set, _INTEGER_ENCODING_SET);
2628 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
2629 const char *clock_name;
2630
2631 if (_IS_SET(&set, _INTEGER_MAP_SET)) {
28973adf
PP
2632 _BT_LOGE_DUP_ATTR(left, "map",
2633 "integer field type");
e98a2d6e
PP
2634 ret = -EPERM;
2635 goto error;
2636 }
2637
2638 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2639 _BT_LOGE_NODE(right,
2640 "Invalid `map` attribute in integer field type: "
08da4f77 2641 "expecting unary string.");
e98a2d6e
PP
2642 ret = -EINVAL;
2643 goto error;
2644 }
2645
2646 clock_name =
2647 get_map_clock_name_value(
2648 &expression->u.ctf_expression.right);
2649 if (!clock_name) {
2650 char *s_right = concatenate_unary_strings(
2651 &expression->u.ctf_expression.right);
2652
2653 if (!s_right) {
28973adf
PP
2654 _BT_LOGE_NODE(right,
2655 "Unexpected unary expression for integer field type's `map` attribute.");
e98a2d6e
PP
2656 ret = -EINVAL;
2657 goto error;
2658 }
2659
28973adf
PP
2660 _BT_LOGE_NODE(right,
2661 "Invalid `map` attribute in integer field type: "
08da4f77 2662 "cannot find clock class at this point: name=\"%s\"",
e98a2d6e
PP
2663 s_right);
2664 _SET(&set, _INTEGER_MAP_SET);
2665 g_free(s_right);
2666 continue;
2667 }
2668
ac0c6bdd 2669 mapped_clock = bt_ctf_trace_get_clock_class_by_name(
e98a2d6e
PP
2670 ctx->trace, clock_name);
2671 if (!mapped_clock) {
28973adf
PP
2672 _BT_LOGE_NODE(right,
2673 "Invalid `map` attribute in integer field type: "
08da4f77 2674 "cannot find clock class at this point: name=\"%s\"",
e98a2d6e
PP
2675 clock_name);
2676 ret = -EINVAL;
2677 goto error;
2678 }
2679
2680 _SET(&set, _INTEGER_MAP_SET);
2681 } else {
28973adf
PP
2682 _BT_LOGW_NODE(left,
2683 "Unknown attribute in integer field type: "
08da4f77 2684 "attr-name=\"%s\"",
e98a2d6e
PP
2685 left->u.unary_expression.u.string);
2686 }
2687 }
2688
2689 if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
08da4f77 2690 BT_LOGE_STR("Missing `size` attribute in integer field type.");
e98a2d6e
PP
2691 ret = -EPERM;
2692 goto error;
2693 }
2694
2695 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2696 if (size % CHAR_BIT) {
2697 /* Bit-packed alignment */
2698 alignment = 1;
2699 } else {
2700 /* Byte-packed alignment */
2701 alignment = CHAR_BIT;
2702 }
2703 }
2704
2705 *integer_decl = bt_ctf_field_type_integer_create((unsigned int) size);
2706 if (!*integer_decl) {
08da4f77 2707 BT_LOGE_STR("Cannot create integer field type.");
e98a2d6e
PP
2708 ret = -ENOMEM;
2709 goto error;
2710 }
2711
2712 ret = bt_ctf_field_type_integer_set_signed(*integer_decl, signedness);
2713 ret |= bt_ctf_field_type_integer_set_base(*integer_decl, base);
2714 ret |= bt_ctf_field_type_integer_set_encoding(*integer_decl, encoding);
2715 ret |= bt_ctf_field_type_set_alignment(*integer_decl,
2716 (unsigned int) alignment);
2717 ret |= bt_ctf_field_type_set_byte_order(*integer_decl, byte_order);
2718
2719 if (mapped_clock) {
2720 /* Move clock */
ac0c6bdd 2721 ret |= bt_ctf_field_type_integer_set_mapped_clock_class(
e98a2d6e
PP
2722 *integer_decl, mapped_clock);
2723 bt_put(mapped_clock);
2724 mapped_clock = NULL;
2725 }
2726
2727 if (ret) {
08da4f77 2728 BT_LOGE_STR("Cannot configure integer field type.");
e98a2d6e
PP
2729 ret = -EINVAL;
2730 goto error;
2731 }
2732
2733 return 0;
2734
2735error:
2736 if (mapped_clock) {
2737 bt_put(mapped_clock);
2738 }
2739
2740 BT_PUT(*integer_decl);
2741
2742 return ret;
2743}
2744
2745static
2746int visit_floating_point_number_decl(struct ctx *ctx,
2747 struct bt_list_head *expressions,
2748 struct bt_ctf_field_type **float_decl)
2749{
2750 int set = 0;
2751 int ret = 0;
2752 struct ctf_node *expression;
2753 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
2754 enum bt_ctf_byte_order byte_order =
8a716c8d 2755 bt_ctf_trace_get_native_byte_order(ctx->trace);
e98a2d6e
PP
2756
2757 *float_decl = NULL;
2758
2759 bt_list_for_each_entry(expression, expressions, siblings) {
2760 struct ctf_node *left, *right;
2761
2762 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2763 struct ctf_node, siblings);
2764 right = _BT_LIST_FIRST_ENTRY(
2765 &expression->u.ctf_expression.right, struct ctf_node,
2766 siblings);
2767
2768 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2769 _BT_LOGE_NODE(left,
2770 "Unexpected unary expression type: type=%d",
2771 left->u.unary_expression.type);
e98a2d6e
PP
2772 ret = -EINVAL;
2773 goto error;
2774 }
2775
2776 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
2777 if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
28973adf 2778 _BT_LOGE_DUP_ATTR(left, "byte_order",
08da4f77 2779 "floating point number field type");
e98a2d6e
PP
2780 ret = -EPERM;
2781 goto error;
2782 }
2783
2784 byte_order = get_real_byte_order(ctx, right);
2785 if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
28973adf
PP
2786 _BT_LOGE_NODE(right,
2787 "Invalid `byte_order` attribute in floating point number field type: "
08da4f77 2788 "ret=%d", ret);
e98a2d6e
PP
2789 ret = -EINVAL;
2790 goto error;
2791 }
2792
2793 _SET(&set, _FLOAT_BYTE_ORDER_SET);
2794 } else if (!strcmp(left->u.unary_expression.u.string,
2795 "exp_dig")) {
2796 if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
28973adf 2797 _BT_LOGE_DUP_ATTR(left, "exp_dig",
08da4f77 2798 "floating point number field type");
e98a2d6e
PP
2799 ret = -EPERM;
2800 goto error;
2801 }
2802
2803 if (right->u.unary_expression.type !=
2804 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2805 _BT_LOGE_NODE(right,
2806 "Invalid `exp_dig` attribute in floating point number field type: "
08da4f77
PP
2807 "expecting unsigned constant integer: "
2808 "node-type=%d",
2809 right->u.unary_expression.type);
e98a2d6e
PP
2810 ret = -EINVAL;
2811 goto error;
2812 }
2813
2814 exp_dig = right->u.unary_expression.u.unsigned_constant;
2815 _SET(&set, _FLOAT_EXP_DIG_SET);
2816 } else if (!strcmp(left->u.unary_expression.u.string,
2817 "mant_dig")) {
2818 if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
28973adf 2819 _BT_LOGE_DUP_ATTR(left, "mant_dig",
08da4f77 2820 "floating point number field type");
e98a2d6e
PP
2821 ret = -EPERM;
2822 goto error;
2823 }
2824
2825 if (right->u.unary_expression.type !=
2826 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2827 _BT_LOGE_NODE(right,
2828 "Invalid `mant_dig` attribute in floating point number field type: "
08da4f77
PP
2829 "expecting unsigned constant integer: "
2830 "node-type=%d",
2831 right->u.unary_expression.type);
e98a2d6e
PP
2832 ret = -EINVAL;
2833 goto error;
2834 }
2835
2836 mant_dig = right->u.unary_expression.u.
2837 unsigned_constant;
2838 _SET(&set, _FLOAT_MANT_DIG_SET);
2839 } else if (!strcmp(left->u.unary_expression.u.string,
2840 "align")) {
2841 if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
28973adf 2842 _BT_LOGE_DUP_ATTR(left, "align",
08da4f77 2843 "floating point number field type");
e98a2d6e
PP
2844 ret = -EPERM;
2845 goto error;
2846 }
2847
2848 if (right->u.unary_expression.type !=
2849 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2850 _BT_LOGE_NODE(right,
2851 "Invalid `align` attribute in floating point number field type: "
08da4f77
PP
2852 "expecting unsigned constant integer: "
2853 "node-type=%d",
2854 right->u.unary_expression.type);
e98a2d6e
PP
2855 ret = -EINVAL;
2856 goto error;
2857 }
2858
2859 alignment = right->u.unary_expression.u.
2860 unsigned_constant;
2861
2862 if (!is_align_valid(alignment)) {
28973adf
PP
2863 _BT_LOGE_NODE(right,
2864 "Invalid `align` attribute in floating point number field type: "
08da4f77
PP
2865 "expecting power of two: "
2866 "align=%" PRIu64, alignment);
e98a2d6e
PP
2867 ret = -EINVAL;
2868 goto error;
2869 }
2870
2871 _SET(&set, _FLOAT_ALIGN_SET);
2872 } else {
28973adf
PP
2873 _BT_LOGW_NODE(left,
2874 "Unknown attribute in floating point number field type: "
08da4f77 2875 "attr-name=\"%s\"",
e98a2d6e
PP
2876 left->u.unary_expression.u.string);
2877 }
2878 }
2879
2880 if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
08da4f77 2881 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field type.");
e98a2d6e
PP
2882 ret = -EPERM;
2883 goto error;
2884 }
2885
2886 if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
08da4f77 2887 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field type.");
e98a2d6e
PP
2888 ret = -EPERM;
2889 goto error;
2890 }
2891
2892 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2893 if ((mant_dig + exp_dig) % CHAR_BIT) {
2894 /* Bit-packed alignment */
2895 alignment = 1;
2896 } else {
2897 /* Byte-packed alignment */
2898 alignment = CHAR_BIT;
2899 }
2900 }
2901
2902 *float_decl = bt_ctf_field_type_floating_point_create();
2903 if (!*float_decl) {
08da4f77 2904 BT_LOGE_STR("Cannot create floating point number field type.");
e98a2d6e
PP
2905 ret = -ENOMEM;
2906 goto error;
2907 }
2908
2909 ret = bt_ctf_field_type_floating_point_set_exponent_digits(
2910 *float_decl, exp_dig);
2911 ret |= bt_ctf_field_type_floating_point_set_mantissa_digits(
2912 *float_decl, mant_dig);
2913 ret |= bt_ctf_field_type_set_byte_order(*float_decl, byte_order);
2914 ret |= bt_ctf_field_type_set_alignment(*float_decl, alignment);
2915 if (ret) {
08da4f77 2916 BT_LOGE_STR("Cannot configure floating point number field type.");
e98a2d6e
PP
2917 ret = -EINVAL;
2918 goto error;
2919 }
2920
2921 return 0;
2922
2923error:
2924 BT_PUT(*float_decl);
2925
2926 return ret;
2927}
2928
2929static
2930int visit_string_decl(struct ctx *ctx,
2931 struct bt_list_head *expressions,
2932 struct bt_ctf_field_type **string_decl)
2933{
2934 int set = 0;
2935 int ret = 0;
2936 struct ctf_node *expression;
2937 enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_UTF8;
2938
2939 *string_decl = NULL;
2940
2941 bt_list_for_each_entry(expression, expressions, siblings) {
2942 struct ctf_node *left, *right;
2943
2944 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2945 struct ctf_node, siblings);
2946 right = _BT_LIST_FIRST_ENTRY(
2947 &expression->u.ctf_expression.right, struct ctf_node,
2948 siblings);
2949
2950 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2951 _BT_LOGE_NODE(left,
2952 "Unexpected unary expression type: type=%d",
2953 left->u.unary_expression.type);
e98a2d6e
PP
2954 ret = -EINVAL;
2955 goto error;
2956 }
2957
2958 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
2959 char *s_right;
2960
2961 if (_IS_SET(&set, _STRING_ENCODING_SET)) {
28973adf 2962 _BT_LOGE_DUP_ATTR(left, "encoding",
08da4f77 2963 "string field type");
e98a2d6e
PP
2964 ret = -EPERM;
2965 goto error;
2966 }
2967
2968 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2969 _BT_LOGE_NODE(right,
2970 "Invalid `encoding` attribute in string field type: "
08da4f77 2971 "expecting unary string.");
e98a2d6e
PP
2972 ret = -EINVAL;
2973 goto error;
2974 }
2975
2976 s_right = concatenate_unary_strings(
2977 &expression->u.ctf_expression.right);
2978 if (!s_right) {
28973adf
PP
2979 _BT_LOGE_NODE(right,
2980 "Unexpected unary expression for string field type's `encoding` attribute.");
e98a2d6e
PP
2981 ret = -EINVAL;
2982 goto error;
2983 }
2984
2985 if (!strcmp(s_right, "UTF8") ||
2986 !strcmp(s_right, "utf8") ||
2987 !strcmp(s_right, "utf-8") ||
2988 !strcmp(s_right, "UTF-8")) {
2989 encoding = BT_CTF_STRING_ENCODING_UTF8;
2990 } else if (!strcmp(s_right, "ASCII") ||
2991 !strcmp(s_right, "ascii")) {
2992 encoding = BT_CTF_STRING_ENCODING_ASCII;
2993 } else if (!strcmp(s_right, "none")) {
2994 encoding = BT_CTF_STRING_ENCODING_NONE;
2995 } else {
28973adf
PP
2996 _BT_LOGE_NODE(right,
2997 "Invalid `encoding` attribute in string field type: "
08da4f77 2998 "unknown encoding: encoding=\"%s\"",
e98a2d6e
PP
2999 s_right);
3000 g_free(s_right);
3001 ret = -EINVAL;
3002 goto error;
3003 }
3004
3005 g_free(s_right);
3006 _SET(&set, _STRING_ENCODING_SET);
3007 } else {
28973adf
PP
3008 _BT_LOGW_NODE(left,
3009 "Unknown attribute in string field type: "
08da4f77 3010 "attr-name=\"%s\"",
e98a2d6e
PP
3011 left->u.unary_expression.u.string);
3012 }
3013 }
3014
3015 *string_decl = bt_ctf_field_type_string_create();
3016 if (!*string_decl) {
08da4f77 3017 BT_LOGE_STR("Cannot create string field type.");
e98a2d6e
PP
3018 ret = -ENOMEM;
3019 goto error;
3020 }
3021
3022 ret = bt_ctf_field_type_string_set_encoding(*string_decl, encoding);
3023 if (ret) {
08da4f77 3024 BT_LOGE_STR("Cannot configure string field type.");
e98a2d6e
PP
3025 ret = -EINVAL;
3026 goto error;
3027 }
3028
3029 return 0;
3030
3031error:
3032 BT_PUT(*string_decl);
3033
3034 return ret;
3035}
3036
3037static
3038int visit_type_specifier_list(struct ctx *ctx,
3039 struct ctf_node *ts_list,
3040 struct bt_ctf_field_type **decl)
3041{
3042 int ret = 0;
3043 struct ctf_node *first, *node;
3044
3045 *decl = NULL;
3046
3047 if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
28973adf
PP
3048 _BT_LOGE_NODE(ts_list,
3049 "Unexpected node type: node-type=%d", ts_list->type);
e98a2d6e
PP
3050 ret = -EINVAL;
3051 goto error;
3052 }
3053
3054 first = _BT_LIST_FIRST_ENTRY(&ts_list->u.type_specifier_list.head,
3055 struct ctf_node, siblings);
3056 if (first->type != NODE_TYPE_SPECIFIER) {
28973adf
PP
3057 _BT_LOGE_NODE(first,
3058 "Unexpected node type: node-type=%d", first->type);
e98a2d6e
PP
3059 ret = -EINVAL;
3060 goto error;
3061 }
3062
3063 node = first->u.type_specifier.node;
3064
3065 switch (first->u.type_specifier.type) {
3066 case TYPESPEC_INTEGER:
3067 ret = visit_integer_decl(ctx, &node->u.integer.expressions,
3068 decl);
3069 if (ret) {
3070 assert(!*decl);
3071 goto error;
3072 }
3073 break;
3074 case TYPESPEC_FLOATING_POINT:
3075 ret = visit_floating_point_number_decl(ctx,
3076 &node->u.floating_point.expressions, decl);
3077 if (ret) {
3078 assert(!*decl);
3079 goto error;
3080 }
3081 break;
3082 case TYPESPEC_STRING:
3083 ret = visit_string_decl(ctx,
3084 &node->u.string.expressions, decl);
3085 if (ret) {
3086 assert(!*decl);
3087 goto error;
3088 }
3089 break;
3090 case TYPESPEC_STRUCT:
3091 ret = visit_struct_decl(ctx, node->u._struct.name,
3092 &node->u._struct.declaration_list,
3093 node->u._struct.has_body,
3094 &node->u._struct.min_align, decl);
3095 if (ret) {
3096 assert(!*decl);
3097 goto error;
3098 }
3099 break;
3100 case TYPESPEC_VARIANT:
3101 ret = visit_variant_decl(ctx, node->u.variant.name,
3102 node->u.variant.choice,
3103 &node->u.variant.declaration_list,
3104 node->u.variant.has_body, decl);
3105 if (ret) {
3106 assert(!*decl);
3107 goto error;
3108 }
3109 break;
3110 case TYPESPEC_ENUM:
3111 ret = visit_enum_decl(ctx, node->u._enum.enum_id,
3112 node->u._enum.container_type,
3113 &node->u._enum.enumerator_list,
3114 node->u._enum.has_body, decl);
3115 if (ret) {
3116 assert(!*decl);
3117 goto error;
3118 }
3119 break;
3120 case TYPESPEC_VOID:
3121 case TYPESPEC_CHAR:
3122 case TYPESPEC_SHORT:
3123 case TYPESPEC_INT:
3124 case TYPESPEC_LONG:
3125 case TYPESPEC_FLOAT:
3126 case TYPESPEC_DOUBLE:
3127 case TYPESPEC_SIGNED:
3128 case TYPESPEC_UNSIGNED:
3129 case TYPESPEC_BOOL:
3130 case TYPESPEC_COMPLEX:
3131 case TYPESPEC_IMAGINARY:
3132 case TYPESPEC_CONST:
3133 case TYPESPEC_ID_TYPE:
3134 ret = visit_type_specifier(ctx, ts_list, decl);
3135 if (ret) {
28973adf
PP
3136 _BT_LOGE_NODE(first,
3137 "Cannot visit type specifier: ret=%d",
3138 ret);
e98a2d6e
PP
3139 assert(!*decl);
3140 goto error;
3141 }
3142 break;
3143 default:
28973adf
PP
3144 _BT_LOGE_NODE(first,
3145 "Unexpected type specifier type: node-type=%d",
08da4f77 3146 first->u.type_specifier.type);
e98a2d6e
PP
3147 ret = -EINVAL;
3148 goto error;
3149 }
3150
3151 assert(*decl);
3152
3153 return 0;
3154
3155error:
3156 BT_PUT(*decl);
3157
3158 return ret;
3159}
3160
3161static
3162int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
3163 struct bt_ctf_event_class *event_class, int64_t *stream_id,
3164 int *set)
3165{
3166 int ret = 0;
3167 char *left = NULL;
3168 _BT_CTF_FIELD_TYPE_INIT(decl);
3169
3170 switch (node->type) {
3171 case NODE_TYPEDEF:
3172 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3173 &node->u._typedef.type_declarators);
3174 if (ret) {
28973adf
PP
3175 _BT_LOGE_NODE(node,
3176 "Cannot add type definition found in event class.");
e98a2d6e
PP
3177 goto error;
3178 }
3179 break;
3180 case NODE_TYPEALIAS:
3181 ret = visit_typealias(ctx, node->u.typealias.target,
3182 node->u.typealias.alias);
3183 if (ret) {
28973adf
PP
3184 _BT_LOGE_NODE(node,
3185 "Cannot add type alias found in event class.");
e98a2d6e
PP
3186 goto error;
3187 }
3188 break;
3189 case NODE_CTF_EXPRESSION:
3190 {
3191 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3192 if (!left) {
28973adf 3193 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
3194 ret = -EINVAL;
3195 goto error;
3196 }
3197
3198 if (!strcmp(left, "name")) {
3199 /* This is already known at this stage */
3200 if (_IS_SET(set, _EVENT_NAME_SET)) {
28973adf
PP
3201 _BT_LOGE_DUP_ATTR(node, "name",
3202 "event class");
e98a2d6e
PP
3203 ret = -EPERM;
3204 goto error;
3205 }
3206
3207 _SET(set, _EVENT_NAME_SET);
3208 } else if (!strcmp(left, "id")) {
3209 int64_t id;
3210
3211 if (_IS_SET(set, _EVENT_ID_SET)) {
28973adf
PP
3212 _BT_LOGE_DUP_ATTR(node, "id",
3213 "event class");
e98a2d6e
PP
3214 ret = -EPERM;
3215 goto error;
3216 }
3217
3218 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3219 (uint64_t *) &id);
5eae0c3c
JG
3220 /* Only read "id" if get_unary_unsigned() succeeded. */
3221 if (ret || (!ret && id < 0)) {
28973adf
PP
3222 _BT_LOGE_NODE(node,
3223 "Unexpected unary expression for event class's `id` attribute.");
e98a2d6e
PP
3224 ret = -EINVAL;
3225 goto error;
3226 }
3227
3228 ret = bt_ctf_event_class_set_id(event_class, id);
3229 if (ret) {
28973adf
PP
3230 _BT_LOGE_NODE(node,
3231 "Cannot set event class's ID: "
08da4f77 3232 "id=%" PRId64, id);
e98a2d6e
PP
3233 goto error;
3234 }
3235
3236 _SET(set, _EVENT_ID_SET);
3237 } else if (!strcmp(left, "stream_id")) {
3238 if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
28973adf 3239 _BT_LOGE_DUP_ATTR(node, "stream_id",
08da4f77 3240 "event class");
e98a2d6e
PP
3241 ret = -EPERM;
3242 goto error;
3243 }
3244
3245 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3246 (uint64_t *) stream_id);
5eae0c3c
JG
3247 /*
3248 * Only read "stream_id" if get_unary_unsigned()
3249 * succeeded.
3250 */
3251 if (ret || (!ret && *stream_id < 0)) {
28973adf
PP
3252 _BT_LOGE_NODE(node,
3253 "Unexpected unary expression for event class's `stream_id` attribute.");
e98a2d6e
PP
3254 ret = -EINVAL;
3255 goto error;
3256 }
3257
3258 _SET(set, _EVENT_STREAM_ID_SET);
3259 } else if (!strcmp(left, "context")) {
3260 if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
28973adf
PP
3261 _BT_LOGE_NODE(node,
3262 "Duplicate `context` entry in event class.");
e98a2d6e
PP
3263 ret = -EPERM;
3264 goto error;
3265 }
3266
3267 ret = visit_type_specifier_list(ctx,
3268 _BT_LIST_FIRST_ENTRY(
3269 &node->u.ctf_expression.right,
3270 struct ctf_node, siblings),
3271 &decl);
3272 if (ret) {
28973adf
PP
3273 _BT_LOGE_NODE(node,
3274 "Cannot create event class's context field type.");
e98a2d6e
PP
3275 goto error;
3276 }
3277
3278 assert(decl);
3279 ret = bt_ctf_event_class_set_context_type(
3280 event_class, decl);
3281 BT_PUT(decl);
3282 if (ret) {
28973adf
PP
3283 _BT_LOGE_NODE(node,
3284 "Cannot set event class's context field type.");
e98a2d6e
PP
3285 goto error;
3286 }
3287
3288 _SET(set, _EVENT_CONTEXT_SET);
3289 } else if (!strcmp(left, "fields")) {
3290 if (_IS_SET(set, _EVENT_FIELDS_SET)) {
28973adf
PP
3291 _BT_LOGE_NODE(node,
3292 "Duplicate `fields` entry in event class.");
e98a2d6e
PP
3293 ret = -EPERM;
3294 goto error;
3295 }
3296
3297 ret = visit_type_specifier_list(ctx,
3298 _BT_LIST_FIRST_ENTRY(
3299 &node->u.ctf_expression.right,
3300 struct ctf_node, siblings),
3301 &decl);
3302 if (ret) {
28973adf
PP
3303 _BT_LOGE_NODE(node,
3304 "Cannot create event class's payload field type.");
e98a2d6e
PP
3305 goto error;
3306 }
3307
3308 assert(decl);
3309 ret = bt_ctf_event_class_set_payload_type(
3310 event_class, decl);
3311 BT_PUT(decl);
3312 if (ret) {
28973adf
PP
3313 _BT_LOGE_NODE(node,
3314 "Cannot set event class's payload field type.");
e98a2d6e
PP
3315 goto error;
3316 }
3317
3318 _SET(set, _EVENT_FIELDS_SET);
3319 } else if (!strcmp(left, "loglevel")) {
c3c30b08
MD
3320 uint64_t loglevel_value;
3321 const char *loglevel_str;
3322 struct bt_value *value_obj, *str_obj;
e98a2d6e
PP
3323
3324 if (_IS_SET(set, _EVENT_LOGLEVEL_SET)) {
28973adf 3325 _BT_LOGE_DUP_ATTR(node, "loglevel",
08da4f77 3326 "event class");
e98a2d6e
PP
3327 ret = -EPERM;
3328 goto error;
3329 }
3330
3331 ret = get_unary_unsigned(&node->u.ctf_expression.right,
c3c30b08 3332 &loglevel_value);
e98a2d6e 3333 if (ret) {
28973adf
PP
3334 _BT_LOGE_NODE(node,
3335 "Unexpected unary expression for event class's `loglevel` attribute.");
e98a2d6e
PP
3336 ret = -EINVAL;
3337 goto error;
3338 }
c3c30b08
MD
3339 value_obj = bt_value_integer_create_init(loglevel_value);
3340 if (!value_obj) {
28973adf
PP
3341 _BT_LOGE_NODE(node,
3342 "Cannot create integer value object.");
c3c30b08
MD
3343 ret = -ENOMEM;
3344 goto error;
3345 }
3346 if (bt_ctf_event_class_set_attribute(event_class,
08da4f77 3347 "loglevel", value_obj) != BT_VALUE_STATUS_OK) {
28973adf
PP
3348 _BT_LOGE_NODE(node,
3349 "Cannot set event class's `loglevel` attribute.");
c3c30b08
MD
3350 ret = -EINVAL;
3351 bt_put(value_obj);
3352 goto error;
3353 }
3354 loglevel_str = print_loglevel(loglevel_value);
3355 if (loglevel_str) {
3356 str_obj = bt_value_string_create_init(loglevel_str);
3357 if (bt_ctf_event_class_set_attribute(event_class,
3358 "loglevel_string", str_obj) != BT_VALUE_STATUS_OK) {
28973adf
PP
3359 _BT_LOGE_NODE(node,
3360 "Cannot set event class's `loglevel_string` attribute.");
c3c30b08
MD
3361 ret = -EINVAL;
3362 bt_put(str_obj);
3363 goto error;
3364 }
3365 bt_put(str_obj);
3366 }
3367 bt_put(value_obj);
e98a2d6e
PP
3368 _SET(set, _EVENT_LOGLEVEL_SET);
3369 } else if (!strcmp(left, "model.emf.uri")) {
3370 char *right;
28973adf 3371 struct bt_value *str_obj;
e98a2d6e
PP
3372
3373 if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
28973adf
PP
3374 _BT_LOGE_DUP_ATTR(node, "model.emf.uri",
3375 "event class");
e98a2d6e
PP
3376 ret = -EPERM;
3377 goto error;
3378 }
3379
3380 right = concatenate_unary_strings(
3381 &node->u.ctf_expression.right);
3382 if (!right) {
28973adf
PP
3383 _BT_LOGE_NODE(node,
3384 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
e98a2d6e
PP
3385 ret = -EINVAL;
3386 goto error;
3387 }
3388
28973adf
PP
3389 str_obj = bt_value_string_create_init(right);
3390 if (bt_ctf_event_class_set_attribute(event_class,
3391 "model.emf.uri", str_obj) != BT_VALUE_STATUS_OK) {
3392 _BT_LOGE_NODE(node,
3393 "Cannot set event class's `model.emf.uri` attribute.");
3394 ret = -EINVAL;
3395 bt_put(str_obj);
3396 goto error;
3397 }
3398 bt_put(str_obj);
e98a2d6e
PP
3399 g_free(right);
3400 _SET(set, _EVENT_MODEL_EMF_URI_SET);
3401 } else {
28973adf
PP
3402 _BT_LOGW_NODE(node,
3403 "Unknown attribute in event class: "
08da4f77 3404 "attr-name=\"%s\"", left);
e98a2d6e
PP
3405 }
3406
3407 g_free(left);
3408 left = NULL;
3409 break;
3410 }
3411 default:
3412 ret = -EPERM;
3413 goto error;
3414 }
3415
3416 return 0;
3417
3418error:
3419 if (left) {
3420 g_free(left);
3421 }
3422
3423 BT_PUT(decl);
3424
3425 return ret;
3426}
3427
3428static
3429char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node)
3430{
3431 char *left = NULL;
3432 char *name = NULL;
3433 struct ctf_node *iter;
3434 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3435
3436 bt_list_for_each_entry(iter, decl_list, siblings) {
3437 if (iter->type != NODE_CTF_EXPRESSION) {
3438 continue;
3439 }
3440
3441 left = concatenate_unary_strings(&iter->u.ctf_expression.left);
3442 if (!left) {
28973adf
PP
3443 _BT_LOGE_NODE(iter,
3444 "Cannot concatenate unary strings.");
e98a2d6e
PP
3445 goto error;
3446 }
3447
3448 if (!strcmp(left, "name")) {
3449 name = concatenate_unary_strings(
3450 &iter->u.ctf_expression.right);
3451 if (!name) {
28973adf
PP
3452 _BT_LOGE_NODE(iter,
3453 "Unexpected unary expression for event class's `name` attribute.");
e98a2d6e
PP
3454 goto error;
3455 }
3456 }
3457
3458 g_free(left);
3459 left = NULL;
3460
3461 if (name) {
3462 break;
3463 }
3464 }
3465
3466 return name;
3467
3468error:
3469 g_free(left);
3470
3471 return NULL;
3472}
3473
3474static
3475int reset_event_decl_types(struct ctx *ctx,
3476 struct bt_ctf_event_class *event_class)
3477{
3478 int ret = 0;
e98a2d6e 3479
835b2d10
JG
3480 /* Context type. */
3481 ret = bt_ctf_event_class_set_context_type(event_class, NULL);
e98a2d6e 3482 if (ret) {
28973adf
PP
3483 BT_LOGE("Cannot reset initial event class's context field type: "
3484 "event-name=\"%s\"",
3485 bt_ctf_event_class_get_name(event_class));
835b2d10 3486 goto end;
e98a2d6e
PP
3487 }
3488
835b2d10
JG
3489 /* Event payload. */
3490 ret = bt_ctf_event_class_set_payload_type(event_class, NULL);
e98a2d6e 3491 if (ret) {
28973adf
PP
3492 BT_LOGE("Cannot reset initial event class's payload field type: "
3493 "event-name=\"%s\"",
3494 bt_ctf_event_class_get_name(event_class));
835b2d10 3495 goto end;
e98a2d6e 3496 }
835b2d10 3497end:
e98a2d6e
PP
3498 return ret;
3499}
3500
3501static
3502int reset_stream_decl_types(struct ctx *ctx,
3503 struct bt_ctf_stream_class *stream_class)
3504{
3505 int ret = 0;
e98a2d6e 3506
835b2d10
JG
3507 /* Packet context. */
3508 ret = bt_ctf_stream_class_set_packet_context_type(stream_class, NULL);
e98a2d6e 3509 if (ret) {
08da4f77 3510 BT_LOGE_STR("Cannot reset initial stream class's packet context field type.");
835b2d10 3511 goto end;
e98a2d6e
PP
3512 }
3513
835b2d10
JG
3514 /* Event header. */
3515 ret = bt_ctf_stream_class_set_event_header_type(stream_class, NULL);
e98a2d6e 3516 if (ret) {
08da4f77 3517 BT_LOGE_STR("Cannot reset initial stream class's event header field type.");
835b2d10 3518 goto end;
e98a2d6e
PP
3519 }
3520
835b2d10
JG
3521 /* Event context. */
3522 ret = bt_ctf_stream_class_set_event_context_type(stream_class, NULL);
e98a2d6e 3523 if (ret) {
08da4f77 3524 BT_LOGE_STR("Cannot reset initial stream class's event context field type.");
835b2d10 3525 goto end;
e98a2d6e 3526 }
835b2d10 3527end:
e98a2d6e
PP
3528 return ret;
3529}
3530
3531static
3532struct bt_ctf_stream_class *create_reset_stream_class(struct ctx *ctx)
3533{
3534 int ret;
3535 struct bt_ctf_stream_class *stream_class;
3536
08da4f77 3537 stream_class = bt_ctf_stream_class_create_empty(NULL);
e98a2d6e 3538 if (!stream_class) {
08da4f77 3539 BT_LOGE_STR("Cannot create empty stream class.");
e98a2d6e
PP
3540 goto error;
3541 }
3542
3543 /*
835b2d10
JG
3544 * Set packet context, event header, and event context to NULL to
3545 * override the default ones.
e98a2d6e
PP
3546 */
3547 ret = reset_stream_decl_types(ctx, stream_class);
3548 if (ret) {
3549 goto error;
3550 }
3551
3552 return stream_class;
3553
3554error:
3555 BT_PUT(stream_class);
3556
3557 return NULL;
3558}
3559
3560static
3561int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
3562{
3563 int ret = 0;
3564 int set = 0;
3565 int64_t event_id;
3566 struct ctf_node *iter;
3567 int64_t stream_id = -1;
3568 char *event_name = NULL;
3569 struct bt_ctf_event_class *event_class = NULL;
3570 struct bt_ctf_event_class *eevent_class;
1e649dff 3571 struct bt_ctf_stream_class *stream_class = NULL;
e98a2d6e 3572 struct bt_list_head *decl_list = &node->u.event.declaration_list;
1e649dff 3573 bool pop_scope = false;
e98a2d6e
PP
3574
3575 if (node->visited) {
3576 goto end;
3577 }
3578
3579 node->visited = TRUE;
3580 event_name = get_event_decl_name(ctx, node);
3581 if (!event_name) {
28973adf
PP
3582 _BT_LOGE_NODE(node,
3583 "Missing `name` attribute in event class.");
e98a2d6e
PP
3584 ret = -EPERM;
3585 goto error;
3586 }
3587
3588 event_class = bt_ctf_event_class_create(event_name);
3589
3590 /*
835b2d10 3591 * Unset context and fields to override the default ones.
e98a2d6e
PP
3592 */
3593 ret = reset_event_decl_types(ctx, event_class);
3594 if (ret) {
28973adf
PP
3595 _BT_LOGE_NODE(node,
3596 "Cannot reset event class's field types: "
3597 "ret=%d", ret);
e98a2d6e
PP
3598 goto error;
3599 }
3600
e98a2d6e
PP
3601 ret = ctx_push_scope(ctx);
3602 if (ret) {
08da4f77 3603 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
3604 goto error;
3605 }
3606
1e649dff
PP
3607 pop_scope = true;
3608
e98a2d6e
PP
3609 bt_list_for_each_entry(iter, decl_list, siblings) {
3610 ret = visit_event_decl_entry(ctx, iter, event_class,
3611 &stream_id, &set);
3612 if (ret) {
28973adf
PP
3613 _BT_LOGE_NODE(iter, "Cannot visit event class's entry: "
3614 "ret=%d", ret);
e98a2d6e
PP
3615 goto error;
3616 }
3617 }
3618
3619 if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
3620 GList *keys = NULL;
3621 struct bt_ctf_stream_class *new_stream_class;
1e649dff
PP
3622 size_t stream_class_count =
3623 g_hash_table_size(ctx->stream_classes) +
3624 bt_ctf_trace_get_stream_class_count(ctx->trace);
e98a2d6e 3625
1e649dff
PP
3626 /*
3627 * Allow missing stream_id if there is only a single
3628 * stream class.
3629 */
3630 switch (stream_class_count) {
e98a2d6e 3631 case 0:
1e649dff 3632 /* Create implicit stream class if there's none */
e98a2d6e
PP
3633 new_stream_class = create_reset_stream_class(ctx);
3634 if (!new_stream_class) {
28973adf
PP
3635 _BT_LOGE_NODE(node,
3636 "Cannot create empty stream class.");
e98a2d6e
PP
3637 ret = -EINVAL;
3638 goto error;
3639 }
3640
3641 ret = bt_ctf_stream_class_set_id(new_stream_class, 0);
3642 if (ret) {
28973adf
PP
3643 _BT_LOGE_NODE(node,
3644 "Cannot set stream class's ID: "
08da4f77 3645 "id=0, ret=%d", ret);
e98a2d6e
PP
3646 BT_PUT(new_stream_class);
3647 goto error;
3648 }
3649
3650 stream_id = 0;
3651
3652 /* Move reference to visitor's context */
3653 g_hash_table_insert(ctx->stream_classes,
3654 (gpointer) stream_id, new_stream_class);
3655 new_stream_class = NULL;
e98a2d6e
PP
3656 break;
3657 case 1:
1e649dff
PP
3658 /* Single stream class: get its ID */
3659 if (g_hash_table_size(ctx->stream_classes) == 1) {
3660 keys = g_hash_table_get_keys(ctx->stream_classes);
3661 stream_id = (int64_t) keys->data;
3662 g_list_free(keys);
3663 } else {
3664 assert(bt_ctf_trace_get_stream_class_count(
3665 ctx->trace) == 1);
9ac68eb1
PP
3666 stream_class =
3667 bt_ctf_trace_get_stream_class_by_index(
3668 ctx->trace, 0);
1e649dff
PP
3669 assert(stream_class);
3670 stream_id = bt_ctf_stream_class_get_id(
3671 stream_class);
3672 BT_PUT(stream_class);
3673 }
e98a2d6e
PP
3674 break;
3675 default:
28973adf
PP
3676 _BT_LOGE_NODE(node,
3677 "Missing `stream_id` attribute in event class.");
e98a2d6e
PP
3678 ret = -EPERM;
3679 goto error;
3680 }
3681 }
3682
e98a2d6e
PP
3683 assert(stream_id >= 0);
3684
1e649dff 3685 /* We have the stream ID now; get the stream class if found */
e98a2d6e
PP
3686 stream_class = g_hash_table_lookup(ctx->stream_classes,
3687 (gpointer) stream_id);
1e649dff 3688 bt_get(stream_class);
e98a2d6e 3689 if (!stream_class) {
1e649dff 3690 stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
e98a2d6e 3691 stream_id);
1e649dff 3692 if (!stream_class) {
28973adf
PP
3693 _BT_LOGE_NODE(node,
3694 "Cannot find stream class at this point: "
08da4f77 3695 "id=%" PRId64, stream_id);
1e649dff
PP
3696 ret = -EINVAL;
3697 goto error;
3698 }
e98a2d6e
PP
3699 }
3700
1e649dff
PP
3701 assert(stream_class);
3702
e98a2d6e
PP
3703 if (!_IS_SET(&set, _EVENT_ID_SET)) {
3704 /* Allow only one event without ID per stream */
3705 if (bt_ctf_stream_class_get_event_class_count(stream_class) !=
3706 0) {
28973adf
PP
3707 _BT_LOGE_NODE(node,
3708 "Missing `id` attribute in event class.");
e98a2d6e
PP
3709 ret = -EPERM;
3710 goto error;
3711 }
3712
3713 /* Automatic ID */
3714 ret = bt_ctf_event_class_set_id(event_class, 0);
3715 if (ret) {
28973adf
PP
3716 _BT_LOGE_NODE(node,
3717 "Cannot set event class's ID: id=0, ret=%d",
08da4f77 3718 ret);
e98a2d6e
PP
3719 goto error;
3720 }
3721 }
3722
3723 event_id = bt_ctf_event_class_get_id(event_class);
3724 if (event_id < 0) {
28973adf 3725 _BT_LOGE_NODE(node, "Cannot get event class's ID.");
e98a2d6e
PP
3726 ret = -EINVAL;
3727 goto error;
3728 }
3729
3730 eevent_class = bt_ctf_stream_class_get_event_class_by_id(stream_class,
3731 event_id);
3732 if (eevent_class) {
3733 BT_PUT(eevent_class);
28973adf
PP
3734 _BT_LOGE_NODE(node,
3735 "Duplicate event class (same ID) in the same stream class: "
08da4f77 3736 "id=%" PRId64, event_id);
e98a2d6e
PP
3737 ret = -EEXIST;
3738 goto error;
3739 }
3740
e98a2d6e
PP
3741 ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
3742 BT_PUT(event_class);
e98a2d6e 3743 if (ret) {
28973adf
PP
3744 _BT_LOGE_NODE(node,
3745 "Cannot add event class to stream class: ret=%d", ret);
e98a2d6e
PP
3746 goto error;
3747 }
3748
1e649dff 3749 goto end;
e98a2d6e
PP
3750
3751error:
1e649dff 3752 bt_put(event_class);
e98a2d6e 3753
1e649dff
PP
3754end:
3755 if (pop_scope) {
3756 ctx_pop_scope(ctx);
3757 }
e98a2d6e 3758
1e649dff
PP
3759 g_free(event_name);
3760 bt_put(stream_class);
e98a2d6e
PP
3761 return ret;
3762}
3763
56b43721
PP
3764static
3765int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
3766 struct bt_ctf_field_type *packet_context_field_type,
3767 const char **field_names)
3768{
3769 _BT_CTF_FIELD_TYPE_INIT(ft);
3770 struct bt_ctf_clock_class *clock_class = NULL;
3771 struct bt_ctf_clock_class *mapped_clock_class = NULL;
3772 int ret = 0;
3773 const char **field_name;
3774
3775 if (ctx->decoder_config.strict) {
3776 goto end;
3777 }
3778
3779 if (!packet_context_field_type) {
3780 goto end;
3781 }
3782
3783 if (!bt_ctf_field_type_is_structure(packet_context_field_type)) {
3784 goto end;
3785 }
3786
3787 if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 1) {
3788 goto end;
3789 }
3790
3791 clock_class = bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0);
3792 assert(clock_class);
3793
3794 for (field_name = field_names; *field_name; field_name++) {
3795 ft = bt_ctf_field_type_structure_get_field_type_by_name(
3796 packet_context_field_type, *field_name);
3797
3798 if (ft && bt_ctf_field_type_is_integer(ft)) {
3799 mapped_clock_class =
3800 bt_ctf_field_type_integer_get_mapped_clock_class(ft);
3801
3802 if (!mapped_clock_class) {
3803 ret = bt_ctf_field_type_integer_set_mapped_clock_class(
3804 ft, clock_class);
3805 if (ret) {
3806 BT_LOGE("Cannot map field type's field to trace's clock class: "
3807 "field-name=\"%s\", ret=%d",
3808 *field_name, ret);
3809 goto end;
3810 }
3811 }
3812 }
3813
3814 BT_PUT(mapped_clock_class);
3815 BT_PUT(ft);
3816 }
3817
3818end:
3819 bt_put(mapped_clock_class);
3820 bt_put(clock_class);
3821 bt_put(ft);
3822 return ret;
3823}
3824
e98a2d6e
PP
3825static
3826int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
3827 struct bt_ctf_stream_class *stream_class, int *set)
3828{
3829 int ret = 0;
3830 char *left = NULL;
3831 _BT_CTF_FIELD_TYPE_INIT(decl);
3832
3833 switch (node->type) {
3834 case NODE_TYPEDEF:
3835 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3836 &node->u._typedef.type_declarators);
3837 if (ret) {
28973adf
PP
3838 _BT_LOGE_NODE(node,
3839 "Cannot add type definition found in stream class.");
e98a2d6e
PP
3840 goto error;
3841 }
3842 break;
3843 case NODE_TYPEALIAS:
3844 ret = visit_typealias(ctx, node->u.typealias.target,
3845 node->u.typealias.alias);
3846 if (ret) {
28973adf
PP
3847 _BT_LOGE_NODE(node,
3848 "Cannot add type alias found in stream class.");
e98a2d6e
PP
3849 goto error;
3850 }
3851 break;
3852 case NODE_CTF_EXPRESSION:
3853 {
3854 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3855 if (!left) {
28973adf 3856 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
3857 ret = -EINVAL;
3858 goto error;
3859 }
3860
3861 if (!strcmp(left, "id")) {
3862 int64_t id;
3863 gpointer ptr;
3864
3865 if (_IS_SET(set, _STREAM_ID_SET)) {
28973adf
PP
3866 _BT_LOGE_DUP_ATTR(node, "id",
3867 "stream declaration");
e98a2d6e
PP
3868 ret = -EPERM;
3869 goto error;
3870 }
3871
3872 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3873 (uint64_t *) &id);
5eae0c3c
JG
3874 /* Only read "id" if get_unary_unsigned() succeeded. */
3875 if (ret || (!ret && id < 0)) {
28973adf
PP
3876 _BT_LOGE_NODE(node,
3877 "Unexpected unary expression for stream class's `id` attribute.");
e98a2d6e
PP
3878 ret = -EINVAL;
3879 goto error;
3880 }
3881
3882 ptr = g_hash_table_lookup(ctx->stream_classes,
3883 (gpointer) id);
3884 if (ptr) {
28973adf
PP
3885 _BT_LOGE_NODE(node,
3886 "Duplicate stream class (same ID): id=%" PRId64,
e98a2d6e
PP
3887 id);
3888 ret = -EEXIST;
3889 goto error;
3890 }
3891
3892 ret = bt_ctf_stream_class_set_id(stream_class, id);
3893 if (ret) {
28973adf
PP
3894 _BT_LOGE_NODE(node,
3895 "Cannot set stream class's ID: "
08da4f77 3896 "id=%" PRId64 ", ret=%d", id, ret);
e98a2d6e
PP
3897 goto error;
3898 }
3899
3900 _SET(set, _STREAM_ID_SET);
3901 } else if (!strcmp(left, "event.header")) {
56b43721
PP
3902 const char *field_names[] = {
3903 "timestamp",
3904 "ts",
3905 NULL,
3906 };
3907
e98a2d6e 3908 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
28973adf
PP
3909 _BT_LOGE_NODE(node,
3910 "Duplicate `event.header` entry in stream class.");
e98a2d6e
PP
3911 ret = -EPERM;
3912 goto error;
3913 }
3914
3915 ret = visit_type_specifier_list(ctx,
3916 _BT_LIST_FIRST_ENTRY(
3917 &node->u.ctf_expression.right,
3918 struct ctf_node, siblings),
3919 &decl);
3920 if (ret) {
28973adf
PP
3921 _BT_LOGE_NODE(node,
3922 "Cannot create stream class's event header field type.");
e98a2d6e
PP
3923 goto error;
3924 }
3925
3926 assert(decl);
56b43721
PP
3927 ret = auto_map_fields_to_trace_clock_class(ctx,
3928 decl, field_names);
3929 if (ret) {
3930 _BT_LOGE_NODE(node,
3931 "Cannot automatically map specific event header field type fields to trace's clock class.");
3932 goto error;
3933 }
e98a2d6e
PP
3934
3935 ret = bt_ctf_stream_class_set_event_header_type(
3936 stream_class, decl);
3937 BT_PUT(decl);
3938 if (ret) {
28973adf
PP
3939 _BT_LOGE_NODE(node,
3940 "Cannot set stream class's event header field type.");
e98a2d6e
PP
3941 goto error;
3942 }
3943
3944 _SET(set, _STREAM_EVENT_HEADER_SET);
3945 } else if (!strcmp(left, "event.context")) {
3946 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
28973adf
PP
3947 _BT_LOGE_NODE(node,
3948 "Duplicate `event.context` entry in stream class.");
e98a2d6e
PP
3949 ret = -EPERM;
3950 goto error;
3951 }
3952
3953 ret = visit_type_specifier_list(ctx,
3954 _BT_LIST_FIRST_ENTRY(
3955 &node->u.ctf_expression.right,
3956 struct ctf_node, siblings),
3957 &decl);
3958 if (ret) {
28973adf
PP
3959 _BT_LOGE_NODE(node,
3960 "Cannot create stream class's event context field type.");
e98a2d6e
PP
3961 goto error;
3962 }
3963
3964 assert(decl);
3965
3966 ret = bt_ctf_stream_class_set_event_context_type(
3967 stream_class, decl);
3968 BT_PUT(decl);
3969 if (ret) {
28973adf
PP
3970 _BT_LOGE_NODE(node,
3971 "Cannot set stream class's event context field type.");
e98a2d6e
PP
3972 goto error;
3973 }
3974
3975 _SET(set, _STREAM_EVENT_CONTEXT_SET);
3976 } else if (!strcmp(left, "packet.context")) {
56b43721
PP
3977 const char *field_names[] = {
3978 "timestamp_begin",
3979 "timestamp_end",
3980 NULL,
3981 };
3982
e98a2d6e 3983 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
28973adf
PP
3984 _BT_LOGE_NODE(node,
3985 "Duplicate `packet.context` entry in stream class.");
e98a2d6e
PP
3986 ret = -EPERM;
3987 goto error;
3988 }
3989
3990 ret = visit_type_specifier_list(ctx,
3991 _BT_LIST_FIRST_ENTRY(
3992 &node->u.ctf_expression.right,
3993 struct ctf_node, siblings),
3994 &decl);
3995 if (ret) {
28973adf
PP
3996 _BT_LOGE_NODE(node,
3997 "Cannot create stream class's packet context field type.");
e98a2d6e
PP
3998 goto error;
3999 }
4000
4001 assert(decl);
56b43721
PP
4002 ret = auto_map_fields_to_trace_clock_class(ctx,
4003 decl, field_names);
4004 if (ret) {
4005 _BT_LOGE_NODE(node,
4006 "Cannot automatically map specific packet context field type fields to trace's clock class.");
4007 goto error;
4008 }
e98a2d6e
PP
4009
4010 ret = bt_ctf_stream_class_set_packet_context_type(
4011 stream_class, decl);
4012 BT_PUT(decl);
4013 if (ret) {
28973adf
PP
4014 _BT_LOGE_NODE(node,
4015 "Cannot set stream class's packet context field type.");
e98a2d6e
PP
4016 goto error;
4017 }
4018
4019 _SET(set, _STREAM_PACKET_CONTEXT_SET);
4020 } else {
28973adf
PP
4021 _BT_LOGW_NODE(node,
4022 "Unknown attribute in stream class: "
08da4f77 4023 "attr-name=\"%s\"", left);
e98a2d6e
PP
4024 }
4025
4026 g_free(left);
4027 left = NULL;
4028 break;
4029 }
4030
4031 default:
4032 ret = -EPERM;
4033 goto error;
4034 }
4035
4036 return 0;
4037
4038error:
4039 g_free(left);
4040 BT_PUT(decl);
4041
4042 return ret;
4043}
4044
4045static
4046int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
4047{
4048 int64_t id;
4049 int set = 0;
4050 int ret = 0;
4051 struct ctf_node *iter;
4052 struct bt_ctf_stream_class *stream_class = NULL;
1e649dff 4053 struct bt_ctf_stream_class *existing_stream_class = NULL;
e98a2d6e
PP
4054 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
4055
4056 if (node->visited) {
4057 goto end;
4058 }
4059
4060 node->visited = TRUE;
4061 stream_class = create_reset_stream_class(ctx);
4062 if (!stream_class) {
28973adf 4063 _BT_LOGE_NODE(node, "Cannot create empty stream class.");
e98a2d6e
PP
4064 ret = -EINVAL;
4065 goto error;
4066 }
4067
4068 ret = ctx_push_scope(ctx);
4069 if (ret) {
08da4f77 4070 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4071 goto error;
4072 }
4073
4074 bt_list_for_each_entry(iter, decl_list, siblings) {
4075 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
4076 if (ret) {
28973adf
PP
4077 _BT_LOGE_NODE(iter,
4078 "Cannot visit stream class's entry: "
4079 "ret=%d", ret);
e98a2d6e
PP
4080 ctx_pop_scope(ctx);
4081 goto error;
4082 }
4083 }
4084
4085 ctx_pop_scope(ctx);
4086
4087 if (_IS_SET(&set, _STREAM_ID_SET)) {
4088 /* Check that packet header has stream_id field */
4089 _BT_CTF_FIELD_TYPE_INIT(stream_id_decl);
4090 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4091
4092 packet_header_decl =
4093 bt_ctf_trace_get_packet_header_type(ctx->trace);
4094 if (!packet_header_decl) {
28973adf
PP
4095 _BT_LOGE_NODE(node,
4096 "Stream class has a `id` attribute, "
08da4f77 4097 "but trace has no packet header field type.");
e98a2d6e
PP
4098 goto error;
4099 }
4100
4101 stream_id_decl =
4102 bt_ctf_field_type_structure_get_field_type_by_name(
4103 packet_header_decl, "stream_id");
4104 BT_PUT(packet_header_decl);
4105 if (!stream_id_decl) {
28973adf
PP
4106 _BT_LOGE_NODE(node,
4107 "Stream class has a `id` attribute, "
08da4f77 4108 "but trace's packet header field type has no `stream_id` field.");
e98a2d6e
PP
4109 goto error;
4110 }
4111
4112 if (!bt_ctf_field_type_is_integer(stream_id_decl)) {
4113 BT_PUT(stream_id_decl);
28973adf
PP
4114 _BT_LOGE_NODE(node,
4115 "Stream class has a `id` attribute, "
08da4f77 4116 "but trace's packet header field type's `stream_id` field is not an integer field type.");
e98a2d6e
PP
4117 goto error;
4118 }
4119
4120 BT_PUT(stream_id_decl);
4121 } else {
4122 /* Allow only _one_ ID-less stream */
4123 if (g_hash_table_size(ctx->stream_classes) != 0) {
28973adf
PP
4124 _BT_LOGE_NODE(node,
4125 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
e98a2d6e
PP
4126 ret = -EPERM;
4127 goto error;
4128 }
4129
4130 /* Automatic ID: 0 */
4131 ret = bt_ctf_stream_class_set_id(stream_class, 0);
08da4f77 4132 assert(ret == 0);
e98a2d6e
PP
4133 }
4134
4135 id = bt_ctf_stream_class_get_id(stream_class);
4136 if (id < 0) {
28973adf
PP
4137 _BT_LOGE_NODE(node,
4138 "Cannot get stream class's ID.");
e98a2d6e
PP
4139 ret = -EINVAL;
4140 goto error;
4141 }
4142
1e649dff
PP
4143 /*
4144 * Make sure that this stream class's ID is currently unique in
4145 * the trace.
4146 */
1e649dff
PP
4147 existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
4148 id);
08da4f77
PP
4149 if (g_hash_table_lookup(ctx->stream_classes, (gpointer) id) ||
4150 existing_stream_class) {
28973adf
PP
4151 _BT_LOGE_NODE(node,
4152 "Duplicate stream class (same ID): id=%" PRId64,
08da4f77 4153 id);
1e649dff
PP
4154 ret = -EINVAL;
4155 goto error;
4156 }
4157
e98a2d6e
PP
4158 /* Move reference to visitor's context */
4159 g_hash_table_insert(ctx->stream_classes, (gpointer) (int64_t) id,
4160 stream_class);
4161 stream_class = NULL;
1e649dff 4162 goto end;
e98a2d6e
PP
4163
4164error:
1e649dff 4165 bt_put(stream_class);
e98a2d6e 4166
1e649dff
PP
4167end:
4168 bt_put(existing_stream_class);
e98a2d6e
PP
4169 return ret;
4170}
4171
4172static
4173int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
4174{
4175 int ret = 0;
4176 char *left = NULL;
4177 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4178
4179 switch (node->type) {
4180 case NODE_TYPEDEF:
4181 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
4182 &node->u._typedef.type_declarators);
4183 if (ret) {
28973adf
PP
4184 _BT_LOGE_NODE(node,
4185 "Cannot add type definition found in trace (`trace` block).");
e98a2d6e
PP
4186 goto error;
4187 }
4188 break;
4189 case NODE_TYPEALIAS:
4190 ret = visit_typealias(ctx, node->u.typealias.target,
4191 node->u.typealias.alias);
4192 if (ret) {
28973adf
PP
4193 _BT_LOGE_NODE(node,
4194 "Cannot add type alias found in trace (`trace` block).");
e98a2d6e
PP
4195 goto error;
4196 }
4197 break;
4198 case NODE_CTF_EXPRESSION:
4199 {
4200 left = concatenate_unary_strings(&node->u.ctf_expression.left);
4201 if (!left) {
28973adf 4202 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4203 ret = -EINVAL;
4204 goto error;
4205 }
4206
4207 if (!strcmp(left, "major")) {
4208 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
28973adf 4209 _BT_LOGE_DUP_ATTR(node, "major", "trace");
e98a2d6e
PP
4210 ret = -EPERM;
4211 goto error;
4212 }
4213
4214 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4215 &ctx->trace_major);
4216 if (ret) {
28973adf
PP
4217 _BT_LOGE_NODE(node,
4218 "Unexpected unary expression for trace's `major` attribute.");
e98a2d6e
PP
4219 ret = -EINVAL;
4220 goto error;
4221 }
4222
4223 _SET(set, _TRACE_MAJOR_SET);
4224 } else if (!strcmp(left, "minor")) {
4225 if (_IS_SET(set, _TRACE_MINOR_SET)) {
28973adf 4226 _BT_LOGE_DUP_ATTR(node, "minor", "trace");
e98a2d6e
PP
4227 ret = -EPERM;
4228 goto error;
4229 }
4230
4231 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4232 &ctx->trace_minor);
4233 if (ret) {
28973adf
PP
4234 _BT_LOGE_NODE(node,
4235 "Unexpected unary expression for trace's `minor` attribute.");
e98a2d6e
PP
4236 ret = -EINVAL;
4237 goto error;
4238 }
4239
4240 _SET(set, _TRACE_MINOR_SET);
4241 } else if (!strcmp(left, "uuid")) {
4242 if (_IS_SET(set, _TRACE_UUID_SET)) {
28973adf 4243 _BT_LOGE_DUP_ATTR(node, "uuid", "trace");
e98a2d6e
PP
4244 ret = -EPERM;
4245 goto error;
4246 }
4247
4248 ret = get_unary_uuid(&node->u.ctf_expression.right,
4249 ctx->trace_uuid);
4250 if (ret) {
28973adf
PP
4251 _BT_LOGE_NODE(node,
4252 "Invalid trace's `uuid` attribute.");
e98a2d6e
PP
4253 goto error;
4254 }
4255
892a5b6c
PP
4256 ret = bt_ctf_trace_set_uuid(ctx->trace, ctx->trace_uuid);
4257 if (ret) {
28973adf 4258 _BT_LOGE_NODE(node, "Cannot set trace's UUID.");
892a5b6c
PP
4259 goto error;
4260 }
4261
e98a2d6e
PP
4262 _SET(set, _TRACE_UUID_SET);
4263 } else if (!strcmp(left, "byte_order")) {
4264 /* Native byte order is already known at this stage */
4265 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4266 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4267 "trace");
e98a2d6e
PP
4268 ret = -EPERM;
4269 goto error;
4270 }
4271
4272 _SET(set, _TRACE_BYTE_ORDER_SET);
4273 } else if (!strcmp(left, "packet.header")) {
4274 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
28973adf
PP
4275 _BT_LOGE_NODE(node,
4276 "Duplicate `packet.header` entry in trace.");
e98a2d6e
PP
4277 ret = -EPERM;
4278 goto error;
4279 }
4280
4281 ret = visit_type_specifier_list(ctx,
4282 _BT_LIST_FIRST_ENTRY(
4283 &node->u.ctf_expression.right,
4284 struct ctf_node, siblings),
4285 &packet_header_decl);
4286 if (ret) {
28973adf
PP
4287 _BT_LOGE_NODE(node,
4288 "Cannot create trace's packet header field type.");
e98a2d6e
PP
4289 goto error;
4290 }
4291
4292 assert(packet_header_decl);
4293 ret = bt_ctf_trace_set_packet_header_type(ctx->trace,
4294 packet_header_decl);
4295 BT_PUT(packet_header_decl);
4296 if (ret) {
28973adf
PP
4297 _BT_LOGE_NODE(node,
4298 "Cannot set trace's packet header field type.");
e98a2d6e
PP
4299 goto error;
4300 }
4301
4302 _SET(set, _TRACE_PACKET_HEADER_SET);
4303 } else {
28973adf
PP
4304 _BT_LOGW_NODE(node,
4305 "Unknown attribute in stream class: "
08da4f77 4306 "attr-name=\"%s\"", left);
e98a2d6e
PP
4307 }
4308
4309 g_free(left);
4310 left = NULL;
4311 break;
4312 }
4313 default:
28973adf 4314 _BT_LOGE_NODE(node, "Unknown expression in trace.");
e98a2d6e
PP
4315 ret = -EINVAL;
4316 goto error;
4317 }
4318
4319 return 0;
4320
4321error:
4322 g_free(left);
4323 BT_PUT(packet_header_decl);
4324
4325 return ret;
4326}
4327
4328static
4329int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
4330{
4331 int ret = 0;
4332 int set = 0;
4333 struct ctf_node *iter;
4334 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
4335
4336 if (node->visited) {
4337 goto end;
4338 }
4339
4340 node->visited = TRUE;
4341
4342 if (ctx->is_trace_visited) {
28973adf 4343 _BT_LOGE_NODE(node, "Duplicate trace (`trace` block).");
e98a2d6e
PP
4344 ret = -EEXIST;
4345 goto error;
4346 }
4347
4348 ret = ctx_push_scope(ctx);
4349 if (ret) {
08da4f77 4350 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4351 goto error;
4352 }
4353
4354 bt_list_for_each_entry(iter, decl_list, siblings) {
4355 ret = visit_trace_decl_entry(ctx, iter, &set);
4356 if (ret) {
28973adf
PP
4357 _BT_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
4358 "ret=%d", ret);
e98a2d6e
PP
4359 ctx_pop_scope(ctx);
4360 goto error;
4361 }
4362 }
4363
4364 ctx_pop_scope(ctx);
4365
4366 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
28973adf
PP
4367 _BT_LOGE_NODE(node,
4368 "Missing `major` attribute in trace (`trace` block).");
e98a2d6e
PP
4369 ret = -EPERM;
4370 goto error;
4371 }
4372
4373 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
28973adf
PP
4374 _BT_LOGE_NODE(node,
4375 "Missing `minor` attribute in trace (`trace` block).");
e98a2d6e
PP
4376 ret = -EPERM;
4377 goto error;
4378 }
4379
4380 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4381 _BT_LOGE_NODE(node,
4382 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4383 ret = -EPERM;
4384 goto error;
4385 }
4386
4387 ctx->is_trace_visited = TRUE;
4388
4389end:
4390 return 0;
4391
4392error:
4393 return ret;
4394}
4395
4396static
4397int visit_env(struct ctx *ctx, struct ctf_node *node)
4398{
4399 int ret = 0;
4400 char *left = NULL;
4401 struct ctf_node *entry_node;
4402 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4403
4404 if (node->visited) {
4405 goto end;
4406 }
4407
4408 node->visited = TRUE;
4409
4410 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4411 struct bt_list_head *right_head =
4412 &entry_node->u.ctf_expression.right;
4413
4414 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4415 _BT_LOGE_NODE(entry_node,
4416 "Wrong expression in environment entry: "
08da4f77 4417 "node-type=%d", entry_node->type);
e98a2d6e
PP
4418 ret = -EPERM;
4419 goto error;
4420 }
4421
4422 left = concatenate_unary_strings(
4423 &entry_node->u.ctf_expression.left);
4424 if (!left) {
28973adf
PP
4425 _BT_LOGE_NODE(entry_node,
4426 "Cannot get environment entry's name.");
e98a2d6e
PP
4427 ret = -EINVAL;
4428 goto error;
4429 }
4430
4431 if (is_unary_string(right_head)) {
4432 char *right = concatenate_unary_strings(right_head);
4433
4434 if (!right) {
28973adf
PP
4435 _BT_LOGE_NODE(entry_node,
4436 "Unexpected unary expression for environment entry's value: "
08da4f77 4437 "name=\"%s\"", left);
e98a2d6e
PP
4438 ret = -EINVAL;
4439 goto error;
4440 }
4441
a2a54545
PP
4442 if (!ctx->decoder_config.strict) {
4443 if (strcmp(left, "tracer_name") == 0) {
4444 if (strncmp(right, "lttng", 5) == 0) {
4445 BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: "
4446 "tracer-name=\"%s\"",
4447 left, right);
4448 ctx->is_lttng = 1;
4449 }
f4421ff3
PP
4450 }
4451 }
4452
e98a2d6e
PP
4453 ret = bt_ctf_trace_set_environment_field_string(
4454 ctx->trace, left, right);
4455 g_free(right);
4456
4457 if (ret) {
28973adf
PP
4458 _BT_LOGE_NODE(entry_node,
4459 "Cannot add string environment entry to trace: "
08da4f77 4460 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4461 goto error;
4462 }
4463 } else if (is_unary_unsigned(right_head) ||
4464 is_unary_signed(right_head)) {
4465 int64_t v;
4466
4467 if (is_unary_unsigned(right_head)) {
4468 ret = get_unary_unsigned(right_head,
4469 (uint64_t *) &v);
4470 } else {
4471 ret = get_unary_signed(right_head, &v);
4472 }
4473 if (ret) {
28973adf
PP
4474 _BT_LOGE_NODE(entry_node,
4475 "Unexpected unary expression for environment entry's value: "
08da4f77 4476 "name=\"%s\"", left);
e98a2d6e
PP
4477 ret = -EINVAL;
4478 goto error;
4479 }
4480
e98a2d6e
PP
4481 ret = bt_ctf_trace_set_environment_field_integer(
4482 ctx->trace, left, v);
4483 if (ret) {
28973adf
PP
4484 _BT_LOGE_NODE(entry_node,
4485 "Cannot add integer environment entry to trace: "
08da4f77 4486 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4487 goto error;
4488 }
4489 } else {
28973adf
PP
4490 _BT_LOGW_NODE(entry_node,
4491 "Environment entry has unknown type: "
08da4f77 4492 "name=\"%s\"", left);
e98a2d6e
PP
4493 }
4494
4495 g_free(left);
4496 left = NULL;
4497 }
4498
4499end:
4500 return 0;
4501
4502error:
4503 g_free(left);
4504
4505 return ret;
4506}
4507
4508static
4509int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4510{
4511 int ret = 0;
4512 int set = 0;
4513 char *left = NULL;
4514 struct ctf_node *node;
4515 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4516
4517 bt_list_for_each_entry(node, decl_list, siblings) {
4518 if (node->type == NODE_CTF_EXPRESSION) {
4519 struct ctf_node *right_node;
4520
4521 left = concatenate_unary_strings(
4522 &node->u.ctf_expression.left);
4523 if (!left) {
28973adf
PP
4524 _BT_LOGE_NODE(node,
4525 "Cannot concatenate unary strings.");
e98a2d6e
PP
4526 ret = -EINVAL;
4527 goto error;
4528 }
4529
4530 if (!strcmp(left, "byte_order")) {
4531 enum bt_ctf_byte_order bo;
4532
4533 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4534 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4535 "trace");
e98a2d6e
PP
4536 ret = -EPERM;
4537 goto error;
4538 }
4539
4540 _SET(&set, _TRACE_BYTE_ORDER_SET);
4541 right_node = _BT_LIST_FIRST_ENTRY(
4542 &node->u.ctf_expression.right,
4543 struct ctf_node, siblings);
55314f2a 4544 bo = byte_order_from_unary_expr(right_node);
e98a2d6e 4545 if (bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
28973adf
PP
4546 _BT_LOGE_NODE(node,
4547 "Invalid `byte_order` attribute in trace (`trace` block): "
4548 "expecting `le`, `be`, or `network`.");
e98a2d6e
PP
4549 ret = -EINVAL;
4550 goto error;
4551 } else if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
28973adf
PP
4552 _BT_LOGE_NODE(node,
4553 "Invalid `byte_order` attribute in trace (`trace` block): "
08da4f77 4554 "cannot be set to `native` here.");
e98a2d6e
PP
4555 ret = -EPERM;
4556 goto error;
4557 }
4558
1e649dff 4559 ctx->trace_bo = bo;
391c8f0d 4560 ret = bt_ctf_trace_set_native_byte_order(
e98a2d6e
PP
4561 ctx->trace, bo);
4562 if (ret) {
28973adf
PP
4563 _BT_LOGE_NODE(node,
4564 "Cannot set trace's byte order: "
08da4f77 4565 "ret=%d", ret);
e98a2d6e
PP
4566 goto error;
4567 }
4568 }
4569
4570 g_free(left);
4571 left = NULL;
4572 }
4573 }
4574
4575 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4576 _BT_LOGE_NODE(trace_node,
4577 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4578 ret = -EINVAL;
4579 goto error;
4580 }
4581
4582 return 0;
4583
4584error:
4585 g_free(left);
4586
4587 return ret;
4588}
4589
4590static
4591int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
ac0c6bdd 4592 struct bt_ctf_clock_class *clock, int *set)
e98a2d6e
PP
4593{
4594 int ret = 0;
4595 char *left = NULL;
4596
4597 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4598 _BT_LOGE_NODE(entry_node,
4599 "Unexpected node type: node-type=%d",
4600 entry_node->type);
e98a2d6e
PP
4601 ret = -EPERM;
4602 goto error;
4603 }
4604
4605 left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4606 if (!left) {
28973adf 4607 _BT_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4608 ret = -EINVAL;
4609 goto error;
4610 }
4611
4612 if (!strcmp(left, "name")) {
4613 char *right;
4614
4615 if (_IS_SET(set, _CLOCK_NAME_SET)) {
28973adf 4616 _BT_LOGE_DUP_ATTR(entry_node, "name", "clock class");
e98a2d6e
PP
4617 ret = -EPERM;
4618 goto error;
4619 }
4620
4621 right = concatenate_unary_strings(
4622 &entry_node->u.ctf_expression.right);
4623 if (!right) {
28973adf
PP
4624 _BT_LOGE_NODE(entry_node,
4625 "Unexpected unary expression for clock class's `name` attribute.");
e98a2d6e
PP
4626 ret = -EINVAL;
4627 goto error;
4628 }
4629
ac0c6bdd 4630 ret = bt_ctf_clock_class_set_name(clock, right);
e98a2d6e 4631 if (ret) {
28973adf
PP
4632 _BT_LOGE_NODE(entry_node,
4633 "cannot set clock class's name");
e98a2d6e
PP
4634 g_free(right);
4635 goto error;
4636 }
4637
4638 g_free(right);
4639 _SET(set, _CLOCK_NAME_SET);
4640 } else if (!strcmp(left, "uuid")) {
4641 unsigned char uuid[BABELTRACE_UUID_LEN];
4642
4643 if (_IS_SET(set, _CLOCK_UUID_SET)) {
28973adf 4644 _BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
e98a2d6e
PP
4645 ret = -EPERM;
4646 goto error;
4647 }
4648
4649 ret = get_unary_uuid(&entry_node->u.ctf_expression.right, uuid);
4650 if (ret) {
28973adf
PP
4651 _BT_LOGE_NODE(entry_node,
4652 "Invalid clock class's `uuid` attribute.");
e98a2d6e
PP
4653 goto error;
4654 }
4655
ac0c6bdd 4656 ret = bt_ctf_clock_class_set_uuid(clock, uuid);
e98a2d6e 4657 if (ret) {
28973adf
PP
4658 _BT_LOGE_NODE(entry_node,
4659 "Cannot set clock class's UUID.");
e98a2d6e
PP
4660 goto error;
4661 }
4662
4663 _SET(set, _CLOCK_UUID_SET);
4664 } else if (!strcmp(left, "description")) {
4665 char *right;
4666
4667 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
28973adf
PP
4668 _BT_LOGE_DUP_ATTR(entry_node, "description",
4669 "clock class");
e98a2d6e
PP
4670 ret = -EPERM;
4671 goto error;
4672 }
4673
4674 right = concatenate_unary_strings(
4675 &entry_node->u.ctf_expression.right);
4676 if (!right) {
28973adf
PP
4677 _BT_LOGE_NODE(entry_node,
4678 "Unexpected unary expression for clock class's `description` attribute.");
e98a2d6e
PP
4679 ret = -EINVAL;
4680 goto error;
4681 }
4682
ac0c6bdd 4683 ret = bt_ctf_clock_class_set_description(clock, right);
e98a2d6e 4684 if (ret) {
28973adf
PP
4685 _BT_LOGE_NODE(entry_node,
4686 "Cannot set clock class's description.");
e98a2d6e
PP
4687 g_free(right);
4688 goto error;
4689 }
4690
4691 g_free(right);
4692 _SET(set, _CLOCK_DESCRIPTION_SET);
4693 } else if (!strcmp(left, "freq")) {
4694 uint64_t freq;
4695
4696 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
28973adf 4697 _BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
e98a2d6e
PP
4698 ret = -EPERM;
4699 goto error;
4700 }
4701
4702 ret = get_unary_unsigned(
4703 &entry_node->u.ctf_expression.right, &freq);
4704 if (ret) {
28973adf
PP
4705 _BT_LOGE_NODE(entry_node,
4706 "Unexpected unary expression for clock class's `freq` attribute.");
e98a2d6e
PP
4707 ret = -EINVAL;
4708 goto error;
4709 }
4710
ac0c6bdd 4711 ret = bt_ctf_clock_class_set_frequency(clock, freq);
e98a2d6e 4712 if (ret) {
28973adf
PP
4713 _BT_LOGE_NODE(entry_node,
4714 "Cannot set clock class's frequency.");
e98a2d6e
PP
4715 goto error;
4716 }
4717
4718 _SET(set, _CLOCK_FREQ_SET);
4719 } else if (!strcmp(left, "precision")) {
4720 uint64_t precision;
4721
4722 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
28973adf
PP
4723 _BT_LOGE_DUP_ATTR(entry_node, "precision",
4724 "clock class");
e98a2d6e
PP
4725 ret = -EPERM;
4726 goto error;
4727 }
4728
4729 ret = get_unary_unsigned(
4730 &entry_node->u.ctf_expression.right, &precision);
4731 if (ret) {
28973adf
PP
4732 _BT_LOGE_NODE(entry_node,
4733 "Unexpected unary expression for clock class's `precision` attribute.");
e98a2d6e
PP
4734 ret = -EINVAL;
4735 goto error;
4736 }
4737
ac0c6bdd 4738 ret = bt_ctf_clock_class_set_precision(clock, precision);
e98a2d6e 4739 if (ret) {
28973adf
PP
4740 _BT_LOGE_NODE(entry_node,
4741 "Cannot set clock class's precision.");
e98a2d6e
PP
4742 goto error;
4743 }
4744
4745 _SET(set, _CLOCK_PRECISION_SET);
4746 } else if (!strcmp(left, "offset_s")) {
4747 uint64_t offset_s;
4748
4749 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
28973adf
PP
4750 _BT_LOGE_DUP_ATTR(entry_node, "offset_s",
4751 "clock class");
e98a2d6e
PP
4752 ret = -EPERM;
4753 goto error;
4754 }
4755
4756 ret = get_unary_unsigned(
4757 &entry_node->u.ctf_expression.right, &offset_s);
4758 if (ret) {
28973adf
PP
4759 _BT_LOGE_NODE(entry_node,
4760 "Unexpected unary expression for clock class's `offset_s` attribute.");
e98a2d6e
PP
4761 ret = -EINVAL;
4762 goto error;
4763 }
4764
ac0c6bdd 4765 ret = bt_ctf_clock_class_set_offset_s(clock, offset_s);
e98a2d6e 4766 if (ret) {
28973adf
PP
4767 _BT_LOGE_NODE(entry_node,
4768 "Cannot set clock class's offset in seconds.");
e98a2d6e
PP
4769 goto error;
4770 }
4771
4772 _SET(set, _CLOCK_OFFSET_S_SET);
4773 } else if (!strcmp(left, "offset")) {
4774 uint64_t offset;
4775
4776 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
28973adf 4777 _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
e98a2d6e
PP
4778 ret = -EPERM;
4779 goto error;
4780 }
4781
4782 ret = get_unary_unsigned(
4783 &entry_node->u.ctf_expression.right, &offset);
4784 if (ret) {
28973adf
PP
4785 _BT_LOGE_NODE(entry_node,
4786 "Unexpected unary expression for clock class's `offset` attribute.");
e98a2d6e
PP
4787 ret = -EINVAL;
4788 goto error;
4789 }
4790
ac0c6bdd 4791 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset);
e98a2d6e 4792 if (ret) {
28973adf
PP
4793 _BT_LOGE_NODE(entry_node,
4794 "Cannot set clock class's offset in cycles.");
e98a2d6e
PP
4795 goto error;
4796 }
4797
4798 _SET(set, _CLOCK_OFFSET_SET);
4799 } else if (!strcmp(left, "absolute")) {
4800 struct ctf_node *right;
4801
4802 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
28973adf
PP
4803 _BT_LOGE_DUP_ATTR(entry_node, "absolute",
4804 "clock class");
e98a2d6e
PP
4805 ret = -EPERM;
4806 goto error;
4807 }
4808
4809 right = _BT_LIST_FIRST_ENTRY(
4810 &entry_node->u.ctf_expression.right,
4811 struct ctf_node, siblings);
55314f2a 4812 ret = get_boolean(right);
e98a2d6e 4813 if (ret < 0) {
28973adf
PP
4814 _BT_LOGE_NODE(entry_node,
4815 "Unexpected unary expression for clock class's `absolute` attribute.");
e98a2d6e
PP
4816 ret = -EINVAL;
4817 goto error;
4818 }
4819
ac0c6bdd 4820 ret = bt_ctf_clock_class_set_is_absolute(clock, ret);
e98a2d6e 4821 if (ret) {
28973adf
PP
4822 _BT_LOGE_NODE(entry_node,
4823 "Cannot set clock class's absolute flag.");
e98a2d6e
PP
4824 goto error;
4825 }
4826
4827 _SET(set, _CLOCK_ABSOLUTE_SET);
4828 } else {
28973adf
PP
4829 _BT_LOGW_NODE(entry_node,
4830 "Unknown attribute in clock class: attr-name=\"%s\"",
e98a2d6e
PP
4831 left);
4832 }
4833
4834 g_free(left);
4835 left = NULL;
4836
4837 return 0;
4838
4839error:
4840 g_free(left);
4841
4842 return ret;
4843}
4844
4845static
55314f2a 4846int64_t cycles_from_ns(uint64_t frequency, int64_t ns)
92540773 4847{
55314f2a 4848 int64_t cycles;
92540773
JD
4849
4850 /* 1GHz */
4851 if (frequency == 1000000000ULL) {
4852 cycles = ns;
4853 } else {
4854 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
4855 }
4856
4857 return cycles;
4858}
4859
4860static
1e649dff 4861int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
92540773
JD
4862{
4863 int ret;
4864 uint64_t freq;
4865 int64_t offset_cycles;
a2a54545 4866 int64_t offset_to_apply;
92540773
JD
4867
4868 freq = bt_ctf_clock_class_get_frequency(clock);
4869 if (freq == -1ULL) {
08da4f77 4870 BT_LOGE_STR("Cannot get clock class's frequency.");
92540773
JD
4871 ret = -1;
4872 goto end;
4873 }
4874
4875 ret = bt_ctf_clock_class_get_offset_cycles(clock, &offset_cycles);
4876 if (ret) {
08da4f77 4877 BT_LOGE_STR("Cannot get clock class's offset in cycles.");
92540773
JD
4878 ret = -1;
4879 goto end;
4880 }
4881
a2a54545
PP
4882 offset_to_apply =
4883 ctx->decoder_config.clock_class_offset_s * 1000000000LL +
4884 ctx->decoder_config.clock_class_offset_ns;
4885 offset_cycles += cycles_from_ns(freq, offset_to_apply);
92540773
JD
4886 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
4887
4888end:
4889 return ret;
4890}
4891
4892static
1e649dff 4893int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
e98a2d6e
PP
4894{
4895 int ret = 0;
4896 int set = 0;
ac0c6bdd 4897 struct bt_ctf_clock_class *clock;
e98a2d6e
PP
4898 struct ctf_node *entry_node;
4899 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
f4421ff3 4900 const char *clock_class_name;
e98a2d6e
PP
4901
4902 if (clock_node->visited) {
4903 return 0;
4904 }
4905
4906 clock_node->visited = TRUE;
ac0c6bdd 4907 clock = bt_ctf_clock_class_create(NULL);
e98a2d6e 4908 if (!clock) {
28973adf
PP
4909 _BT_LOGE_NODE(clock_node,
4910 "Cannot create default clock class.");
e98a2d6e
PP
4911 ret = -ENOMEM;
4912 goto error;
4913 }
4914
4915 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4916 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set);
4917 if (ret) {
28973adf
PP
4918 _BT_LOGE_NODE(entry_node,
4919 "Cannot visit clock class's entry: ret=%d",
4920 ret);
e98a2d6e
PP
4921 goto error;
4922 }
4923 }
4924
4925 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
28973adf
PP
4926 _BT_LOGE_NODE(clock_node,
4927 "Missing `name` attribute in clock class.");
e98a2d6e
PP
4928 ret = -EPERM;
4929 goto error;
4930 }
4931
f4421ff3
PP
4932 clock_class_name = bt_ctf_clock_class_get_name(clock);
4933 assert(clock_class_name);
4934 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
4935 /*
4936 * Old versions of LTTng forgot to set its clock class
4937 * as absolute, even if it is. This is important because
4938 * it's a condition to be able to sort notifications
4939 * from different sources.
4940 */
4941 ret = bt_ctf_clock_class_set_is_absolute(clock, 1);
4942 if (ret) {
28973adf
PP
4943 _BT_LOGE_NODE(clock_node,
4944 "Cannot set clock class's absolute flag.");
f4421ff3
PP
4945 goto error;
4946 }
e98a2d6e
PP
4947 }
4948
1e649dff 4949 ret = apply_clock_class_offset(ctx, clock);
92540773 4950 if (ret) {
28973adf
PP
4951 _BT_LOGE_NODE(clock_node,
4952 "Cannot apply clock class's custom offset.");
92540773
JD
4953 goto error;
4954 }
4955
ac0c6bdd 4956 ret = bt_ctf_trace_add_clock_class(ctx->trace, clock);
e98a2d6e 4957 if (ret) {
28973adf
PP
4958 _BT_LOGE_NODE(clock_node,
4959 "Cannot add clock class to trace.");
e98a2d6e
PP
4960 goto error;
4961 }
4962
4963error:
4964 BT_PUT(clock);
4965
4966 return ret;
4967}
4968
4969static
4970int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
4971{
4972 int ret = 0;
4973
4974 if (root_decl_node->visited) {
4975 goto end;
4976 }
4977
4978 root_decl_node->visited = TRUE;
4979
4980 switch (root_decl_node->type) {
4981 case NODE_TYPEDEF:
4982 ret = visit_typedef(ctx,
4983 root_decl_node->u._typedef.type_specifier_list,
4984 &root_decl_node->u._typedef.type_declarators);
4985 if (ret) {
28973adf
PP
4986 _BT_LOGE_NODE(root_decl_node,
4987 "Cannot add type definition found in root scope.");
e98a2d6e
PP
4988 goto end;
4989 }
4990 break;
4991 case NODE_TYPEALIAS:
4992 ret = visit_typealias(ctx, root_decl_node->u.typealias.target,
4993 root_decl_node->u.typealias.alias);
4994 if (ret) {
28973adf
PP
4995 _BT_LOGE_NODE(root_decl_node,
4996 "Cannot add type alias found in root scope.");
e98a2d6e
PP
4997 goto end;
4998 }
4999 break;
5000 case NODE_TYPE_SPECIFIER_LIST:
5001 {
5002 _BT_CTF_FIELD_TYPE_INIT(decl);
5003
5004 /*
5005 * Just add the type specifier to the root
5006 * declaration scope. Put local reference.
5007 */
5008 ret = visit_type_specifier_list(ctx, root_decl_node, &decl);
5009 if (ret) {
28973adf
PP
5010 _BT_LOGE_NODE(root_decl_node,
5011 "Cannot visit root scope's field type: "
5012 "ret=%d", ret);
e98a2d6e
PP
5013 assert(!decl);
5014 goto end;
5015 }
5016
5017 BT_PUT(decl);
5018 break;
5019 }
5020 default:
28973adf
PP
5021 _BT_LOGE_NODE(root_decl_node,
5022 "Unexpected node type: node-type=%d",
5023 root_decl_node->type);
e98a2d6e
PP
5024 ret = -EPERM;
5025 goto end;
5026 }
5027
5028end:
5029 return ret;
5030}
5031
91fd6f6a
PP
5032static
5033int set_trace_name(struct ctx *ctx)
5034{
5035 GString *name;
5036 int ret = 0;
5037 struct bt_value *value = NULL;
5038
5039 assert(bt_ctf_trace_get_stream_class_count(ctx->trace) == 0);
5040 name = g_string_new(NULL);
5041 if (!name) {
28973adf 5042 BT_LOGE_STR("Failed to allocate a GString.");
91fd6f6a
PP
5043 ret = -1;
5044 goto end;
5045 }
5046
5047 /*
5048 * Check if we have a trace environment string value named `hostname`.
5049 * If so, use it as the trace name's prefix.
5050 */
5051 value = bt_ctf_trace_get_environment_field_value_by_name(ctx->trace,
5052 "hostname");
5053 if (bt_value_is_string(value)) {
5054 const char *hostname;
5055
5056 ret = bt_value_string_get(value, &hostname);
5057 assert(ret == 0);
5058 g_string_append(name, hostname);
5059
5060 if (ctx->trace_name_suffix) {
5061 g_string_append_c(name, G_DIR_SEPARATOR);
5062 }
5063 }
5064
5065 if (ctx->trace_name_suffix) {
5066 g_string_append(name, ctx->trace_name_suffix);
5067 }
5068
5069 ret = bt_ctf_trace_set_name(ctx->trace, name->str);
5070 if (ret) {
28973adf 5071 BT_LOGE("Cannot set trace's name: name=\"%s\"", name->str);
91fd6f6a
PP
5072 goto error;
5073 }
5074
5075 goto end;
5076
5077error:
5078 ret = -1;
5079
5080end:
5081 bt_put(value);
5082
5083 if (name) {
5084 g_string_free(name, TRUE);
5085 }
5086
5087 return ret;
5088}
5089
e98a2d6e 5090static
1e649dff 5091int move_ctx_stream_classes_to_trace(struct ctx *ctx)
e98a2d6e 5092{
fde61d26 5093 int ret = 0;
e98a2d6e
PP
5094 GHashTableIter iter;
5095 gpointer key, stream_class;
5096
91fd6f6a
PP
5097 if (g_hash_table_size(ctx->stream_classes) > 0 &&
5098 bt_ctf_trace_get_stream_class_count(ctx->trace) == 0) {
5099 /*
5100 * We're about to add the first stream class to the
5101 * trace. This will freeze the trace, and after this
5102 * we cannot set the name anymore. At this point,
5103 * set the trace name.
5104 */
5105 ret = set_trace_name(ctx);
5106 if (ret) {
28973adf 5107 BT_LOGE_STR("Cannot set trace's name.");
91fd6f6a
PP
5108 goto end;
5109 }
5110 }
5111
e98a2d6e
PP
5112 g_hash_table_iter_init(&iter, ctx->stream_classes);
5113
5114 while (g_hash_table_iter_next(&iter, &key, &stream_class)) {
5115 ret = bt_ctf_trace_add_stream_class(ctx->trace,
5116 stream_class);
5117 if (ret) {
5118 int64_t id = bt_ctf_stream_class_get_id(stream_class);
08da4f77 5119 BT_LOGE("Cannot add stream class to trace: id=%" PRId64,
e98a2d6e
PP
5120 id);
5121 goto end;
5122 }
5123 }
5124
1e649dff
PP
5125 g_hash_table_remove_all(ctx->stream_classes);
5126
e98a2d6e
PP
5127end:
5128 return ret;
5129}
5130
1e649dff 5131BT_HIDDEN
55314f2a 5132struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
a2a54545
PP
5133 const struct ctf_metadata_decoder_config *decoder_config,
5134 const char *name)
e98a2d6e 5135{
1e649dff 5136 int ret;
e98a2d6e 5137 struct ctx *ctx = NULL;
1e649dff 5138 struct bt_ctf_trace *trace;
e98a2d6e 5139
1e649dff
PP
5140 trace = bt_ctf_trace_create();
5141 if (!trace) {
08da4f77 5142 BT_LOGE_STR("Cannot create empty trace.");
e98a2d6e
PP
5143 goto error;
5144 }
5145
835b2d10 5146 /* Set packet header to NULL to override the default one */
1e649dff 5147 ret = bt_ctf_trace_set_packet_header_type(trace, NULL);
e98a2d6e 5148 if (ret) {
08da4f77 5149 BT_LOGE_STR("Cannot reset initial trace's packet header field type.");
e98a2d6e
PP
5150 goto error;
5151 }
5152
1e649dff 5153 /* Create visitor's context */
a2a54545 5154 ctx = ctx_create(trace, decoder_config, name);
e98a2d6e 5155 if (!ctx) {
08da4f77 5156 BT_LOGE_STR("Cannot create visitor's context.");
e98a2d6e
PP
5157 goto error;
5158 }
5159
1e649dff
PP
5160 trace = NULL;
5161 goto end;
5162
5163error:
5164 ctx_destroy(ctx);
5165 ctx = NULL;
5166
5167end:
5168 bt_put(trace);
5169 return (void *) ctx;
5170}
5171
5172BT_HIDDEN
5173void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
5174{
5175 ctx_destroy((void *) visitor);
5176}
5177
5178BT_HIDDEN
5179struct bt_ctf_trace *ctf_visitor_generate_ir_get_trace(
5180 struct ctf_visitor_generate_ir *visitor)
5181{
5182 struct ctx *ctx = (void *) visitor;
5183
5184 assert(ctx);
5185 assert(ctx->trace);
5186 return bt_get(ctx->trace);
5187}
5188
5189BT_HIDDEN
5190int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
5191 struct ctf_node *node)
5192{
5193 int ret = 0;
5194 struct ctx *ctx = (void *) visitor;
5195
08da4f77 5196 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
1e649dff 5197
e98a2d6e
PP
5198 switch (node->type) {
5199 case NODE_ROOT:
5200 {
5201 struct ctf_node *iter;
5202 int got_trace_decl = FALSE;
e98a2d6e
PP
5203
5204 /*
1e649dff
PP
5205 * The first thing we need is the native byte order of
5206 * the trace block, because early type aliases can have
5207 * a `byte_order` attribute set to `native`. If we don't
5208 * have the native byte order yet, and we don't have any
5209 * trace block yet, then fail with EINCOMPLETE.
e98a2d6e 5210 */
1e649dff
PP
5211 if (ctx->trace_bo == BT_CTF_BYTE_ORDER_NATIVE) {
5212 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5213 if (got_trace_decl) {
28973adf
PP
5214 _BT_LOGE_NODE(node,
5215 "Duplicate trace (`trace` block).");
1e649dff
PP
5216 ret = -1;
5217 goto end;
5218 }
e98a2d6e 5219
1e649dff
PP
5220 ret = set_trace_byte_order(ctx, iter);
5221 if (ret) {
28973adf
PP
5222 _BT_LOGE_NODE(node,
5223 "Cannot set trace's native byte order: "
08da4f77 5224 "ret=%d", ret);
1e649dff
PP
5225 goto end;
5226 }
5227
5228 got_trace_decl = TRUE;
e98a2d6e
PP
5229 }
5230
1e649dff 5231 if (!got_trace_decl) {
28973adf 5232 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
1e649dff
PP
5233 ret = -EINCOMPLETE;
5234 goto end;
5235 }
e98a2d6e
PP
5236 }
5237
1e649dff
PP
5238 assert(ctx->trace_bo == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
5239 ctx->trace_bo == BT_CTF_BYTE_ORDER_BIG_ENDIAN);
5240 assert(ctx->current_scope &&
5241 ctx->current_scope->parent_scope == NULL);
e98a2d6e 5242
f4421ff3
PP
5243 /* Environment */
5244 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
5245 ret = visit_env(ctx, iter);
5246 if (ret) {
28973adf
PP
5247 _BT_LOGE_NODE(iter,
5248 "Cannot visit trace's environment (`env` block) entry: "
08da4f77 5249 "ret=%d", ret);
f4421ff3
PP
5250 goto end;
5251 }
5252 }
5253
5254 assert(ctx->current_scope &&
5255 ctx->current_scope->parent_scope == NULL);
5256
e98a2d6e 5257 /*
f4421ff3 5258 * Visit clock blocks.
e98a2d6e
PP
5259 */
5260 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
1e649dff 5261 ret = visit_clock_decl(ctx, iter);
e98a2d6e 5262 if (ret) {
28973adf
PP
5263 _BT_LOGE_NODE(iter,
5264 "Cannot visit clock class: ret=%d",
e98a2d6e 5265 ret);
1e649dff 5266 goto end;
e98a2d6e
PP
5267 }
5268 }
5269
1e649dff
PP
5270 assert(ctx->current_scope &&
5271 ctx->current_scope->parent_scope == NULL);
5272
e98a2d6e
PP
5273 /*
5274 * Visit root declarations next, as they can be used by any
5275 * following entity.
5276 */
5277 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
5278 siblings) {
5279 ret = visit_root_decl(ctx, iter);
5280 if (ret) {
28973adf
PP
5281 _BT_LOGE_NODE(iter,
5282 "Cannot visit root entry: ret=%d",
e98a2d6e 5283 ret);
1e649dff 5284 goto end;
e98a2d6e
PP
5285 }
5286 }
5287
1e649dff
PP
5288 assert(ctx->current_scope &&
5289 ctx->current_scope->parent_scope == NULL);
5290
5291 /* Callsite blocks are not supported */
e98a2d6e 5292 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
28973adf
PP
5293 _BT_LOGW_NODE(iter,
5294 "\"callsite\" blocks are not supported as of this version.");
e98a2d6e
PP
5295 }
5296
1e649dff
PP
5297 assert(ctx->current_scope &&
5298 ctx->current_scope->parent_scope == NULL);
5299
e98a2d6e
PP
5300 /* Trace */
5301 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5302 ret = visit_trace_decl(ctx, iter);
5303 if (ret) {
28973adf
PP
5304 _BT_LOGE_NODE(iter,
5305 "Cannot visit trace (`trace` block): "
08da4f77 5306 "ret=%d", ret);
1e649dff 5307 goto end;
e98a2d6e
PP
5308 }
5309 }
5310
1e649dff
PP
5311 assert(ctx->current_scope &&
5312 ctx->current_scope->parent_scope == NULL);
5313
e98a2d6e
PP
5314 /* Streams */
5315 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
5316 ret = visit_stream_decl(ctx, iter);
5317 if (ret) {
28973adf
PP
5318 _BT_LOGE_NODE(iter,
5319 "Cannot visit stream class: ret=%d",
08da4f77 5320 ret);
1e649dff 5321 goto end;
e98a2d6e
PP
5322 }
5323 }
5324
1e649dff
PP
5325 assert(ctx->current_scope &&
5326 ctx->current_scope->parent_scope == NULL);
5327
e98a2d6e
PP
5328 /* Events */
5329 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
5330 ret = visit_event_decl(ctx, iter);
5331 if (ret) {
28973adf
PP
5332 _BT_LOGE_NODE(iter,
5333 "Cannot visit event class: ret=%d",
08da4f77 5334 ret);
1e649dff 5335 goto end;
e98a2d6e
PP
5336 }
5337 }
1e649dff
PP
5338
5339 assert(ctx->current_scope &&
5340 ctx->current_scope->parent_scope == NULL);
e98a2d6e
PP
5341 break;
5342 }
e98a2d6e 5343 default:
28973adf
PP
5344 _BT_LOGE_NODE(node,
5345 "Unexpected node type: node-type=%d",
08da4f77 5346 node->type);
e98a2d6e 5347 ret = -EINVAL;
1e649dff 5348 goto end;
e98a2d6e
PP
5349 }
5350
1e649dff
PP
5351 /* Move decoded stream classes to trace, if any */
5352 ret = move_ctx_stream_classes_to_trace(ctx);
e98a2d6e 5353 if (ret) {
08da4f77 5354 BT_LOGE("Cannot move stream classes to trace: ret=%d", ret);
e98a2d6e
PP
5355 }
5356
1e649dff 5357end:
e98a2d6e
PP
5358 return ret;
5359}
This page took 0.288703 seconds and 4 git commands to generate.