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