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