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