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