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