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