Fix: Explicit null dereferenced
[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)) {
f828aeda 1653 _BT_LOGE_NODE(target,
28973adf 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) {
f828aeda 1665 _BT_LOGE_NODE(target,
28973adf 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 */
7b4b1ba2 3637 stream_id = 0;
e98a2d6e
PP
3638 new_stream_class = create_reset_stream_class(ctx);
3639 if (!new_stream_class) {
28973adf
PP
3640 _BT_LOGE_NODE(node,
3641 "Cannot create empty stream class.");
e98a2d6e
PP
3642 ret = -EINVAL;
3643 goto error;
3644 }
3645
7b4b1ba2
PP
3646 ret = bt_ctf_stream_class_set_id(new_stream_class,
3647 stream_id);
e98a2d6e 3648 if (ret) {
28973adf
PP
3649 _BT_LOGE_NODE(node,
3650 "Cannot set stream class's ID: "
08da4f77 3651 "id=0, ret=%d", ret);
e98a2d6e
PP
3652 BT_PUT(new_stream_class);
3653 goto error;
3654 }
3655
942c0e8f
MJ
3656 new_stream_id = g_new0(int64_t, 1);
3657 if (!new_stream_id) {
3658 BT_LOGE_STR("Failed to allocate a int64_t.");
3659 ret = -ENOMEM;
3660 goto error;
3661 }
e98a2d6e 3662
7b4b1ba2
PP
3663 *new_stream_id = stream_id;
3664
e98a2d6e
PP
3665 /* Move reference to visitor's context */
3666 g_hash_table_insert(ctx->stream_classes,
942c0e8f
MJ
3667 new_stream_id, new_stream_class);
3668 new_stream_id = NULL;
e98a2d6e 3669 new_stream_class = NULL;
e98a2d6e
PP
3670 break;
3671 case 1:
1e649dff
PP
3672 /* Single stream class: get its ID */
3673 if (g_hash_table_size(ctx->stream_classes) == 1) {
3674 keys = g_hash_table_get_keys(ctx->stream_classes);
942c0e8f 3675 stream_id = *((int64_t *) keys->data);
1e649dff
PP
3676 g_list_free(keys);
3677 } else {
3678 assert(bt_ctf_trace_get_stream_class_count(
3679 ctx->trace) == 1);
9ac68eb1
PP
3680 stream_class =
3681 bt_ctf_trace_get_stream_class_by_index(
3682 ctx->trace, 0);
1e649dff
PP
3683 assert(stream_class);
3684 stream_id = bt_ctf_stream_class_get_id(
3685 stream_class);
3686 BT_PUT(stream_class);
3687 }
e98a2d6e
PP
3688 break;
3689 default:
28973adf
PP
3690 _BT_LOGE_NODE(node,
3691 "Missing `stream_id` attribute in event class.");
e98a2d6e
PP
3692 ret = -EPERM;
3693 goto error;
3694 }
3695 }
3696
e98a2d6e
PP
3697 assert(stream_id >= 0);
3698
1e649dff 3699 /* We have the stream ID now; get the stream class if found */
942c0e8f 3700 stream_class = g_hash_table_lookup(ctx->stream_classes, &stream_id);
1e649dff 3701 bt_get(stream_class);
e98a2d6e 3702 if (!stream_class) {
1e649dff 3703 stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
e98a2d6e 3704 stream_id);
1e649dff 3705 if (!stream_class) {
28973adf
PP
3706 _BT_LOGE_NODE(node,
3707 "Cannot find stream class at this point: "
08da4f77 3708 "id=%" PRId64, stream_id);
1e649dff
PP
3709 ret = -EINVAL;
3710 goto error;
3711 }
e98a2d6e
PP
3712 }
3713
1e649dff
PP
3714 assert(stream_class);
3715
e98a2d6e
PP
3716 if (!_IS_SET(&set, _EVENT_ID_SET)) {
3717 /* Allow only one event without ID per stream */
3718 if (bt_ctf_stream_class_get_event_class_count(stream_class) !=
3719 0) {
28973adf
PP
3720 _BT_LOGE_NODE(node,
3721 "Missing `id` attribute in event class.");
e98a2d6e
PP
3722 ret = -EPERM;
3723 goto error;
3724 }
3725
3726 /* Automatic ID */
3727 ret = bt_ctf_event_class_set_id(event_class, 0);
3728 if (ret) {
28973adf
PP
3729 _BT_LOGE_NODE(node,
3730 "Cannot set event class's ID: id=0, ret=%d",
08da4f77 3731 ret);
e98a2d6e
PP
3732 goto error;
3733 }
3734 }
3735
3736 event_id = bt_ctf_event_class_get_id(event_class);
3737 if (event_id < 0) {
28973adf 3738 _BT_LOGE_NODE(node, "Cannot get event class's ID.");
e98a2d6e
PP
3739 ret = -EINVAL;
3740 goto error;
3741 }
3742
3743 eevent_class = bt_ctf_stream_class_get_event_class_by_id(stream_class,
3744 event_id);
3745 if (eevent_class) {
3746 BT_PUT(eevent_class);
28973adf
PP
3747 _BT_LOGE_NODE(node,
3748 "Duplicate event class (same ID) in the same stream class: "
08da4f77 3749 "id=%" PRId64, event_id);
e98a2d6e
PP
3750 ret = -EEXIST;
3751 goto error;
3752 }
3753
e98a2d6e
PP
3754 ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
3755 BT_PUT(event_class);
e98a2d6e 3756 if (ret) {
28973adf
PP
3757 _BT_LOGE_NODE(node,
3758 "Cannot add event class to stream class: ret=%d", ret);
e98a2d6e
PP
3759 goto error;
3760 }
3761
1e649dff 3762 goto end;
e98a2d6e
PP
3763
3764error:
1e649dff 3765 bt_put(event_class);
e98a2d6e 3766
1e649dff
PP
3767end:
3768 if (pop_scope) {
3769 ctx_pop_scope(ctx);
3770 }
e98a2d6e 3771
1e649dff
PP
3772 g_free(event_name);
3773 bt_put(stream_class);
e98a2d6e
PP
3774 return ret;
3775}
3776
56b43721 3777static
7bf5af54
PP
3778int auto_map_field_to_trace_clock_class(struct ctx *ctx,
3779 struct bt_ctf_field_type *ft)
56b43721 3780{
7bf5af54 3781 struct bt_ctf_clock_class *clock_class_to_map_to = NULL;
56b43721
PP
3782 struct bt_ctf_clock_class *mapped_clock_class = NULL;
3783 int ret = 0;
7bf5af54 3784 int64_t clock_class_count;
56b43721 3785
7bf5af54 3786 if (!ft || !bt_ctf_field_type_is_integer(ft)) {
56b43721
PP
3787 goto end;
3788 }
3789
7bf5af54
PP
3790 mapped_clock_class =
3791 bt_ctf_field_type_integer_get_mapped_clock_class(ft);
3792 if (mapped_clock_class) {
56b43721
PP
3793 goto end;
3794 }
3795
7bf5af54
PP
3796 clock_class_count = bt_ctf_trace_get_clock_class_count(ctx->trace);
3797 assert(clock_class_count >= 0);
3798
3799 switch (clock_class_count) {
3800 case 0:
3801 /*
3802 * No clock class exists in the trace at this
3803 * point. Create an implicit one at 1 GHz,
3804 * named `default`, and use this clock class.
3805 */
f3534905
PP
3806 clock_class_to_map_to = bt_ctf_clock_class_create("default",
3807 1000000000);
7bf5af54
PP
3808 if (!clock_class_to_map_to) {
3809 BT_LOGE_STR("Cannot create a clock class.");
3810 ret = -1;
3811 goto end;
3812 }
3813
7bf5af54
PP
3814 ret = bt_ctf_trace_add_clock_class(ctx->trace,
3815 clock_class_to_map_to);
3816 if (ret) {
3817 BT_LOGE_STR("Cannot add clock class to trace.");
3818 goto end;
3819 }
3820 break;
3821 case 1:
3822 /*
3823 * Only one clock class exists in the trace at
3824 * this point: use this one.
3825 */
3826 clock_class_to_map_to =
3827 bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0);
3828 assert(clock_class_to_map_to);
3829 break;
3830 default:
3831 /*
3832 * Timestamp field not mapped to a clock class
3833 * and there's more than one clock class in the
3834 * trace: this is an error.
3835 */
3836 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3837 "but there's more than one clock class in the trace at this point.");
3838 ret = -1;
56b43721
PP
3839 goto end;
3840 }
3841
7bf5af54
PP
3842 assert(clock_class_to_map_to);
3843 ret = bt_ctf_field_type_integer_set_mapped_clock_class(ft,
3844 clock_class_to_map_to);
3845 if (ret) {
3846 BT_LOGE("Cannot map field type's field to trace's clock class: "
3847 "clock-class-name=\"%s\", ret=%d",
3848 bt_ctf_clock_class_get_name(clock_class_to_map_to),
3849 ret);
56b43721
PP
3850 goto end;
3851 }
3852
7bf5af54
PP
3853end:
3854 bt_put(clock_class_to_map_to);
3855 bt_put(mapped_clock_class);
3856 return ret;
3857}
56b43721 3858
7bf5af54
PP
3859static
3860int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
3861 struct bt_ctf_field_type *root_ft, const char *field_name)
3862{
3863 int ret = 0;
3864 int64_t i, count;
56b43721 3865
7bf5af54
PP
3866 if (!root_ft) {
3867 goto end;
3868 }
56b43721 3869
7bf5af54
PP
3870 if (!bt_ctf_field_type_is_structure(root_ft) &&
3871 !bt_ctf_field_type_is_variant(root_ft)) {
3872 goto end;
3873 }
3874
3875 if (bt_ctf_field_type_is_structure(root_ft)) {
3876 count = bt_ctf_field_type_structure_get_field_count(root_ft);
3877 } else {
3878 count = bt_ctf_field_type_variant_get_field_count(root_ft);
3879 }
3880
3881 assert(count >= 0);
3882
3883 for (i = 0; i < count; i++) {
3884 _BT_CTF_FIELD_TYPE_INIT(ft);
3885 const char *name;
3886
3887 if (bt_ctf_field_type_is_structure(root_ft)) {
3888 ret = bt_ctf_field_type_structure_get_field_by_index(
3889 root_ft, &name, &ft, i);
3890 } else if (bt_ctf_field_type_is_variant(root_ft)) {
3891 ret = bt_ctf_field_type_variant_get_field_by_index(
3892 root_ft, &name, &ft, i);
3893 }
3894
3895 assert(ret == 0);
3896
3897 if (strcmp(name, field_name) == 0) {
3898 ret = auto_map_field_to_trace_clock_class(ctx, ft);
3899 if (ret) {
3900 BT_LOGE("Cannot automatically map field to trace's clock class: "
3901 "field-name=\"%s\"", field_name);
3902 bt_put(ft);
3903 goto end;
56b43721
PP
3904 }
3905 }
3906
7bf5af54
PP
3907 ret = auto_map_fields_to_trace_clock_class(ctx, ft, field_name);
3908 bt_put(ft);
3909 if (ret) {
3910 BT_LOGE("Cannot automatically map structure or variant field type's fields to trace's clock class: "
3911 "field-name=\"%s\", root-field-name=\"%s\"",
3912 field_name, name);
3913 goto end;
3914 }
56b43721
PP
3915 }
3916
3917end:
56b43721
PP
3918 return ret;
3919}
3920
e98a2d6e
PP
3921static
3922int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
3923 struct bt_ctf_stream_class *stream_class, int *set)
3924{
3925 int ret = 0;
3926 char *left = NULL;
3927 _BT_CTF_FIELD_TYPE_INIT(decl);
3928
3929 switch (node->type) {
3930 case NODE_TYPEDEF:
3931 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3932 &node->u._typedef.type_declarators);
3933 if (ret) {
28973adf
PP
3934 _BT_LOGE_NODE(node,
3935 "Cannot add type definition found in stream class.");
e98a2d6e
PP
3936 goto error;
3937 }
3938 break;
3939 case NODE_TYPEALIAS:
3940 ret = visit_typealias(ctx, node->u.typealias.target,
3941 node->u.typealias.alias);
3942 if (ret) {
28973adf
PP
3943 _BT_LOGE_NODE(node,
3944 "Cannot add type alias found in stream class.");
e98a2d6e
PP
3945 goto error;
3946 }
3947 break;
3948 case NODE_CTF_EXPRESSION:
3949 {
3950 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3951 if (!left) {
28973adf 3952 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
3953 ret = -EINVAL;
3954 goto error;
3955 }
3956
3957 if (!strcmp(left, "id")) {
3958 int64_t id;
3959 gpointer ptr;
3960
3961 if (_IS_SET(set, _STREAM_ID_SET)) {
28973adf
PP
3962 _BT_LOGE_DUP_ATTR(node, "id",
3963 "stream declaration");
e98a2d6e
PP
3964 ret = -EPERM;
3965 goto error;
3966 }
3967
3968 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3969 (uint64_t *) &id);
5eae0c3c
JG
3970 /* Only read "id" if get_unary_unsigned() succeeded. */
3971 if (ret || (!ret && id < 0)) {
28973adf
PP
3972 _BT_LOGE_NODE(node,
3973 "Unexpected unary expression for stream class's `id` attribute.");
e98a2d6e
PP
3974 ret = -EINVAL;
3975 goto error;
3976 }
3977
942c0e8f 3978 ptr = g_hash_table_lookup(ctx->stream_classes, &id);
e98a2d6e 3979 if (ptr) {
28973adf
PP
3980 _BT_LOGE_NODE(node,
3981 "Duplicate stream class (same ID): id=%" PRId64,
e98a2d6e
PP
3982 id);
3983 ret = -EEXIST;
3984 goto error;
3985 }
3986
3987 ret = bt_ctf_stream_class_set_id(stream_class, id);
3988 if (ret) {
28973adf
PP
3989 _BT_LOGE_NODE(node,
3990 "Cannot set stream class's ID: "
08da4f77 3991 "id=%" PRId64 ", ret=%d", id, ret);
e98a2d6e
PP
3992 goto error;
3993 }
3994
3995 _SET(set, _STREAM_ID_SET);
3996 } else if (!strcmp(left, "event.header")) {
3997 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
28973adf
PP
3998 _BT_LOGE_NODE(node,
3999 "Duplicate `event.header` entry in stream class.");
e98a2d6e
PP
4000 ret = -EPERM;
4001 goto error;
4002 }
4003
4004 ret = visit_type_specifier_list(ctx,
4005 _BT_LIST_FIRST_ENTRY(
4006 &node->u.ctf_expression.right,
4007 struct ctf_node, siblings),
4008 &decl);
4009 if (ret) {
28973adf
PP
4010 _BT_LOGE_NODE(node,
4011 "Cannot create stream class's event header field type.");
e98a2d6e
PP
4012 goto error;
4013 }
4014
4015 assert(decl);
56b43721 4016 ret = auto_map_fields_to_trace_clock_class(ctx,
7bf5af54 4017 decl, "timestamp");
56b43721
PP
4018 if (ret) {
4019 _BT_LOGE_NODE(node,
7bf5af54 4020 "Cannot automatically map specific event header field type fields named `timestamp` to trace's clock class.");
56b43721
PP
4021 goto error;
4022 }
e98a2d6e
PP
4023
4024 ret = bt_ctf_stream_class_set_event_header_type(
4025 stream_class, decl);
4026 BT_PUT(decl);
4027 if (ret) {
28973adf
PP
4028 _BT_LOGE_NODE(node,
4029 "Cannot set stream class's event header field type.");
e98a2d6e
PP
4030 goto error;
4031 }
4032
4033 _SET(set, _STREAM_EVENT_HEADER_SET);
4034 } else if (!strcmp(left, "event.context")) {
4035 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
28973adf
PP
4036 _BT_LOGE_NODE(node,
4037 "Duplicate `event.context` entry in stream class.");
e98a2d6e
PP
4038 ret = -EPERM;
4039 goto error;
4040 }
4041
4042 ret = visit_type_specifier_list(ctx,
4043 _BT_LIST_FIRST_ENTRY(
4044 &node->u.ctf_expression.right,
4045 struct ctf_node, siblings),
4046 &decl);
4047 if (ret) {
28973adf
PP
4048 _BT_LOGE_NODE(node,
4049 "Cannot create stream class's event context field type.");
e98a2d6e
PP
4050 goto error;
4051 }
4052
4053 assert(decl);
4054
4055 ret = bt_ctf_stream_class_set_event_context_type(
4056 stream_class, decl);
4057 BT_PUT(decl);
4058 if (ret) {
28973adf
PP
4059 _BT_LOGE_NODE(node,
4060 "Cannot set stream class's event context field type.");
e98a2d6e
PP
4061 goto error;
4062 }
4063
4064 _SET(set, _STREAM_EVENT_CONTEXT_SET);
4065 } else if (!strcmp(left, "packet.context")) {
4066 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
28973adf
PP
4067 _BT_LOGE_NODE(node,
4068 "Duplicate `packet.context` entry in stream class.");
e98a2d6e
PP
4069 ret = -EPERM;
4070 goto error;
4071 }
4072
4073 ret = visit_type_specifier_list(ctx,
4074 _BT_LIST_FIRST_ENTRY(
4075 &node->u.ctf_expression.right,
4076 struct ctf_node, siblings),
4077 &decl);
4078 if (ret) {
28973adf
PP
4079 _BT_LOGE_NODE(node,
4080 "Cannot create stream class's packet context field type.");
e98a2d6e
PP
4081 goto error;
4082 }
4083
4084 assert(decl);
56b43721 4085 ret = auto_map_fields_to_trace_clock_class(ctx,
7bf5af54
PP
4086 decl, "timestamp_begin");
4087 if (ret) {
4088 _BT_LOGE_NODE(node,
4089 "Cannot automatically map specific packet context field type fields named `timestamp_begin` to trace's clock class.");
4090 goto error;
4091 }
4092
4093 ret = auto_map_fields_to_trace_clock_class(ctx,
4094 decl, "timestamp_end");
56b43721
PP
4095 if (ret) {
4096 _BT_LOGE_NODE(node,
7bf5af54 4097 "Cannot automatically map specific packet context field type fields named `timestamp_end` to trace's clock class.");
56b43721
PP
4098 goto error;
4099 }
e98a2d6e
PP
4100
4101 ret = bt_ctf_stream_class_set_packet_context_type(
4102 stream_class, decl);
4103 BT_PUT(decl);
4104 if (ret) {
28973adf
PP
4105 _BT_LOGE_NODE(node,
4106 "Cannot set stream class's packet context field type.");
e98a2d6e
PP
4107 goto error;
4108 }
4109
4110 _SET(set, _STREAM_PACKET_CONTEXT_SET);
4111 } else {
28973adf
PP
4112 _BT_LOGW_NODE(node,
4113 "Unknown attribute in stream class: "
08da4f77 4114 "attr-name=\"%s\"", left);
e98a2d6e
PP
4115 }
4116
4117 g_free(left);
4118 left = NULL;
4119 break;
4120 }
4121
4122 default:
4123 ret = -EPERM;
4124 goto error;
4125 }
4126
4127 return 0;
4128
4129error:
4130 g_free(left);
4131 BT_PUT(decl);
4132
4133 return ret;
4134}
4135
4136static
4137int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
4138{
4139 int64_t id;
942c0e8f 4140 int64_t *new_id;
e98a2d6e
PP
4141 int set = 0;
4142 int ret = 0;
4143 struct ctf_node *iter;
4144 struct bt_ctf_stream_class *stream_class = NULL;
1e649dff 4145 struct bt_ctf_stream_class *existing_stream_class = NULL;
e98a2d6e
PP
4146 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
4147
4148 if (node->visited) {
4149 goto end;
4150 }
4151
4152 node->visited = TRUE;
4153 stream_class = create_reset_stream_class(ctx);
4154 if (!stream_class) {
28973adf 4155 _BT_LOGE_NODE(node, "Cannot create empty stream class.");
e98a2d6e
PP
4156 ret = -EINVAL;
4157 goto error;
4158 }
4159
4160 ret = ctx_push_scope(ctx);
4161 if (ret) {
08da4f77 4162 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4163 goto error;
4164 }
4165
4166 bt_list_for_each_entry(iter, decl_list, siblings) {
4167 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
4168 if (ret) {
28973adf
PP
4169 _BT_LOGE_NODE(iter,
4170 "Cannot visit stream class's entry: "
4171 "ret=%d", ret);
e98a2d6e
PP
4172 ctx_pop_scope(ctx);
4173 goto error;
4174 }
4175 }
4176
4177 ctx_pop_scope(ctx);
4178
4179 if (_IS_SET(&set, _STREAM_ID_SET)) {
4180 /* Check that packet header has stream_id field */
4181 _BT_CTF_FIELD_TYPE_INIT(stream_id_decl);
4182 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4183
4184 packet_header_decl =
4185 bt_ctf_trace_get_packet_header_type(ctx->trace);
4186 if (!packet_header_decl) {
28973adf
PP
4187 _BT_LOGE_NODE(node,
4188 "Stream class has a `id` attribute, "
08da4f77 4189 "but trace has no packet header field type.");
e98a2d6e
PP
4190 goto error;
4191 }
4192
4193 stream_id_decl =
4194 bt_ctf_field_type_structure_get_field_type_by_name(
4195 packet_header_decl, "stream_id");
4196 BT_PUT(packet_header_decl);
4197 if (!stream_id_decl) {
28973adf
PP
4198 _BT_LOGE_NODE(node,
4199 "Stream class has a `id` attribute, "
08da4f77 4200 "but trace's packet header field type has no `stream_id` field.");
e98a2d6e
PP
4201 goto error;
4202 }
4203
4204 if (!bt_ctf_field_type_is_integer(stream_id_decl)) {
4205 BT_PUT(stream_id_decl);
28973adf
PP
4206 _BT_LOGE_NODE(node,
4207 "Stream class has a `id` attribute, "
08da4f77 4208 "but trace's packet header field type's `stream_id` field is not an integer field type.");
e98a2d6e
PP
4209 goto error;
4210 }
4211
4212 BT_PUT(stream_id_decl);
4213 } else {
4214 /* Allow only _one_ ID-less stream */
4215 if (g_hash_table_size(ctx->stream_classes) != 0) {
28973adf
PP
4216 _BT_LOGE_NODE(node,
4217 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
e98a2d6e
PP
4218 ret = -EPERM;
4219 goto error;
4220 }
4221
4222 /* Automatic ID: 0 */
4223 ret = bt_ctf_stream_class_set_id(stream_class, 0);
08da4f77 4224 assert(ret == 0);
e98a2d6e
PP
4225 }
4226
4227 id = bt_ctf_stream_class_get_id(stream_class);
4228 if (id < 0) {
28973adf
PP
4229 _BT_LOGE_NODE(node,
4230 "Cannot get stream class's ID.");
e98a2d6e
PP
4231 ret = -EINVAL;
4232 goto error;
4233 }
4234
1e649dff
PP
4235 /*
4236 * Make sure that this stream class's ID is currently unique in
4237 * the trace.
4238 */
1e649dff
PP
4239 existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
4240 id);
942c0e8f 4241 if (g_hash_table_lookup(ctx->stream_classes, &id) ||
08da4f77 4242 existing_stream_class) {
28973adf
PP
4243 _BT_LOGE_NODE(node,
4244 "Duplicate stream class (same ID): id=%" PRId64,
08da4f77 4245 id);
1e649dff
PP
4246 ret = -EINVAL;
4247 goto error;
4248 }
4249
942c0e8f
MJ
4250 new_id = g_new0(int64_t, 1);
4251 if (!new_id) {
4252 BT_LOGE_STR("Failed to allocate a int64_t.");
4253 ret = -ENOMEM;
4254 goto error;
4255 }
4256 *new_id = id;
4257
e98a2d6e 4258 /* Move reference to visitor's context */
942c0e8f 4259 g_hash_table_insert(ctx->stream_classes, new_id,
e98a2d6e
PP
4260 stream_class);
4261 stream_class = NULL;
1e649dff 4262 goto end;
e98a2d6e
PP
4263
4264error:
1e649dff 4265 bt_put(stream_class);
e98a2d6e 4266
1e649dff
PP
4267end:
4268 bt_put(existing_stream_class);
e98a2d6e
PP
4269 return ret;
4270}
4271
4272static
4273int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
4274{
4275 int ret = 0;
4276 char *left = NULL;
4277 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4278
4279 switch (node->type) {
4280 case NODE_TYPEDEF:
4281 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
4282 &node->u._typedef.type_declarators);
4283 if (ret) {
28973adf
PP
4284 _BT_LOGE_NODE(node,
4285 "Cannot add type definition found in trace (`trace` block).");
e98a2d6e
PP
4286 goto error;
4287 }
4288 break;
4289 case NODE_TYPEALIAS:
4290 ret = visit_typealias(ctx, node->u.typealias.target,
4291 node->u.typealias.alias);
4292 if (ret) {
28973adf
PP
4293 _BT_LOGE_NODE(node,
4294 "Cannot add type alias found in trace (`trace` block).");
e98a2d6e
PP
4295 goto error;
4296 }
4297 break;
4298 case NODE_CTF_EXPRESSION:
4299 {
4300 left = concatenate_unary_strings(&node->u.ctf_expression.left);
4301 if (!left) {
28973adf 4302 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4303 ret = -EINVAL;
4304 goto error;
4305 }
4306
4307 if (!strcmp(left, "major")) {
4308 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
28973adf 4309 _BT_LOGE_DUP_ATTR(node, "major", "trace");
e98a2d6e
PP
4310 ret = -EPERM;
4311 goto error;
4312 }
4313
4314 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4315 &ctx->trace_major);
4316 if (ret) {
28973adf
PP
4317 _BT_LOGE_NODE(node,
4318 "Unexpected unary expression for trace's `major` attribute.");
e98a2d6e
PP
4319 ret = -EINVAL;
4320 goto error;
4321 }
4322
4323 _SET(set, _TRACE_MAJOR_SET);
4324 } else if (!strcmp(left, "minor")) {
4325 if (_IS_SET(set, _TRACE_MINOR_SET)) {
28973adf 4326 _BT_LOGE_DUP_ATTR(node, "minor", "trace");
e98a2d6e
PP
4327 ret = -EPERM;
4328 goto error;
4329 }
4330
4331 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4332 &ctx->trace_minor);
4333 if (ret) {
28973adf
PP
4334 _BT_LOGE_NODE(node,
4335 "Unexpected unary expression for trace's `minor` attribute.");
e98a2d6e
PP
4336 ret = -EINVAL;
4337 goto error;
4338 }
4339
4340 _SET(set, _TRACE_MINOR_SET);
4341 } else if (!strcmp(left, "uuid")) {
4342 if (_IS_SET(set, _TRACE_UUID_SET)) {
28973adf 4343 _BT_LOGE_DUP_ATTR(node, "uuid", "trace");
e98a2d6e
PP
4344 ret = -EPERM;
4345 goto error;
4346 }
4347
4348 ret = get_unary_uuid(&node->u.ctf_expression.right,
4349 ctx->trace_uuid);
4350 if (ret) {
28973adf
PP
4351 _BT_LOGE_NODE(node,
4352 "Invalid trace's `uuid` attribute.");
e98a2d6e
PP
4353 goto error;
4354 }
4355
892a5b6c
PP
4356 ret = bt_ctf_trace_set_uuid(ctx->trace, ctx->trace_uuid);
4357 if (ret) {
28973adf 4358 _BT_LOGE_NODE(node, "Cannot set trace's UUID.");
892a5b6c
PP
4359 goto error;
4360 }
4361
e98a2d6e
PP
4362 _SET(set, _TRACE_UUID_SET);
4363 } else if (!strcmp(left, "byte_order")) {
4364 /* Native byte order is already known at this stage */
4365 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4366 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4367 "trace");
e98a2d6e
PP
4368 ret = -EPERM;
4369 goto error;
4370 }
4371
4372 _SET(set, _TRACE_BYTE_ORDER_SET);
4373 } else if (!strcmp(left, "packet.header")) {
4374 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
28973adf
PP
4375 _BT_LOGE_NODE(node,
4376 "Duplicate `packet.header` entry in trace.");
e98a2d6e
PP
4377 ret = -EPERM;
4378 goto error;
4379 }
4380
4381 ret = visit_type_specifier_list(ctx,
4382 _BT_LIST_FIRST_ENTRY(
4383 &node->u.ctf_expression.right,
4384 struct ctf_node, siblings),
4385 &packet_header_decl);
4386 if (ret) {
28973adf
PP
4387 _BT_LOGE_NODE(node,
4388 "Cannot create trace's packet header field type.");
e98a2d6e
PP
4389 goto error;
4390 }
4391
4392 assert(packet_header_decl);
4393 ret = bt_ctf_trace_set_packet_header_type(ctx->trace,
4394 packet_header_decl);
4395 BT_PUT(packet_header_decl);
4396 if (ret) {
28973adf
PP
4397 _BT_LOGE_NODE(node,
4398 "Cannot set trace's packet header field type.");
e98a2d6e
PP
4399 goto error;
4400 }
4401
4402 _SET(set, _TRACE_PACKET_HEADER_SET);
4403 } else {
28973adf
PP
4404 _BT_LOGW_NODE(node,
4405 "Unknown attribute in stream class: "
08da4f77 4406 "attr-name=\"%s\"", left);
e98a2d6e
PP
4407 }
4408
4409 g_free(left);
4410 left = NULL;
4411 break;
4412 }
4413 default:
28973adf 4414 _BT_LOGE_NODE(node, "Unknown expression in trace.");
e98a2d6e
PP
4415 ret = -EINVAL;
4416 goto error;
4417 }
4418
4419 return 0;
4420
4421error:
4422 g_free(left);
4423 BT_PUT(packet_header_decl);
4424
4425 return ret;
4426}
4427
4428static
4429int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
4430{
4431 int ret = 0;
4432 int set = 0;
4433 struct ctf_node *iter;
4434 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
4435
4436 if (node->visited) {
4437 goto end;
4438 }
4439
4440 node->visited = TRUE;
4441
4442 if (ctx->is_trace_visited) {
28973adf 4443 _BT_LOGE_NODE(node, "Duplicate trace (`trace` block).");
e98a2d6e
PP
4444 ret = -EEXIST;
4445 goto error;
4446 }
4447
4448 ret = ctx_push_scope(ctx);
4449 if (ret) {
08da4f77 4450 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4451 goto error;
4452 }
4453
4454 bt_list_for_each_entry(iter, decl_list, siblings) {
4455 ret = visit_trace_decl_entry(ctx, iter, &set);
4456 if (ret) {
28973adf
PP
4457 _BT_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
4458 "ret=%d", ret);
e98a2d6e
PP
4459 ctx_pop_scope(ctx);
4460 goto error;
4461 }
4462 }
4463
4464 ctx_pop_scope(ctx);
4465
4466 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
28973adf
PP
4467 _BT_LOGE_NODE(node,
4468 "Missing `major` attribute in trace (`trace` block).");
e98a2d6e
PP
4469 ret = -EPERM;
4470 goto error;
4471 }
4472
4473 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
28973adf
PP
4474 _BT_LOGE_NODE(node,
4475 "Missing `minor` attribute in trace (`trace` block).");
e98a2d6e
PP
4476 ret = -EPERM;
4477 goto error;
4478 }
4479
4480 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4481 _BT_LOGE_NODE(node,
4482 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4483 ret = -EPERM;
4484 goto error;
4485 }
4486
4487 ctx->is_trace_visited = TRUE;
4488
4489end:
4490 return 0;
4491
4492error:
4493 return ret;
4494}
4495
4496static
4497int visit_env(struct ctx *ctx, struct ctf_node *node)
4498{
4499 int ret = 0;
4500 char *left = NULL;
4501 struct ctf_node *entry_node;
4502 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4503
4504 if (node->visited) {
4505 goto end;
4506 }
4507
4508 node->visited = TRUE;
4509
4510 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4511 struct bt_list_head *right_head =
4512 &entry_node->u.ctf_expression.right;
4513
4514 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4515 _BT_LOGE_NODE(entry_node,
4516 "Wrong expression in environment entry: "
08da4f77 4517 "node-type=%d", entry_node->type);
e98a2d6e
PP
4518 ret = -EPERM;
4519 goto error;
4520 }
4521
4522 left = concatenate_unary_strings(
4523 &entry_node->u.ctf_expression.left);
4524 if (!left) {
28973adf
PP
4525 _BT_LOGE_NODE(entry_node,
4526 "Cannot get environment entry's name.");
e98a2d6e
PP
4527 ret = -EINVAL;
4528 goto error;
4529 }
4530
4531 if (is_unary_string(right_head)) {
4532 char *right = concatenate_unary_strings(right_head);
4533
4534 if (!right) {
28973adf
PP
4535 _BT_LOGE_NODE(entry_node,
4536 "Unexpected unary expression for environment entry's value: "
08da4f77 4537 "name=\"%s\"", left);
e98a2d6e
PP
4538 ret = -EINVAL;
4539 goto error;
4540 }
4541
7bf5af54
PP
4542 if (strcmp(left, "tracer_name") == 0) {
4543 if (strncmp(right, "lttng", 5) == 0) {
4544 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4545 "tracer-name=\"%s\"",
4546 left, right);
4547 ctx->is_lttng = 1;
f4421ff3
PP
4548 }
4549 }
4550
e98a2d6e
PP
4551 ret = bt_ctf_trace_set_environment_field_string(
4552 ctx->trace, left, right);
4553 g_free(right);
4554
4555 if (ret) {
28973adf
PP
4556 _BT_LOGE_NODE(entry_node,
4557 "Cannot add string environment entry to trace: "
08da4f77 4558 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4559 goto error;
4560 }
4561 } else if (is_unary_unsigned(right_head) ||
4562 is_unary_signed(right_head)) {
4563 int64_t v;
4564
4565 if (is_unary_unsigned(right_head)) {
4566 ret = get_unary_unsigned(right_head,
4567 (uint64_t *) &v);
4568 } else {
4569 ret = get_unary_signed(right_head, &v);
4570 }
4571 if (ret) {
28973adf
PP
4572 _BT_LOGE_NODE(entry_node,
4573 "Unexpected unary expression for environment entry's value: "
08da4f77 4574 "name=\"%s\"", left);
e98a2d6e
PP
4575 ret = -EINVAL;
4576 goto error;
4577 }
4578
e98a2d6e
PP
4579 ret = bt_ctf_trace_set_environment_field_integer(
4580 ctx->trace, left, v);
4581 if (ret) {
28973adf
PP
4582 _BT_LOGE_NODE(entry_node,
4583 "Cannot add integer environment entry to trace: "
08da4f77 4584 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4585 goto error;
4586 }
4587 } else {
28973adf
PP
4588 _BT_LOGW_NODE(entry_node,
4589 "Environment entry has unknown type: "
08da4f77 4590 "name=\"%s\"", left);
e98a2d6e
PP
4591 }
4592
4593 g_free(left);
4594 left = NULL;
4595 }
4596
4597end:
4598 return 0;
4599
4600error:
4601 g_free(left);
4602
4603 return ret;
4604}
4605
4606static
4607int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4608{
4609 int ret = 0;
4610 int set = 0;
4611 char *left = NULL;
4612 struct ctf_node *node;
4613 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4614
4615 bt_list_for_each_entry(node, decl_list, siblings) {
4616 if (node->type == NODE_CTF_EXPRESSION) {
4617 struct ctf_node *right_node;
4618
4619 left = concatenate_unary_strings(
4620 &node->u.ctf_expression.left);
4621 if (!left) {
28973adf
PP
4622 _BT_LOGE_NODE(node,
4623 "Cannot concatenate unary strings.");
e98a2d6e
PP
4624 ret = -EINVAL;
4625 goto error;
4626 }
4627
4628 if (!strcmp(left, "byte_order")) {
4629 enum bt_ctf_byte_order bo;
4630
4631 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4632 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4633 "trace");
e98a2d6e
PP
4634 ret = -EPERM;
4635 goto error;
4636 }
4637
4638 _SET(&set, _TRACE_BYTE_ORDER_SET);
4639 right_node = _BT_LIST_FIRST_ENTRY(
4640 &node->u.ctf_expression.right,
4641 struct ctf_node, siblings);
55314f2a 4642 bo = byte_order_from_unary_expr(right_node);
e98a2d6e 4643 if (bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
28973adf
PP
4644 _BT_LOGE_NODE(node,
4645 "Invalid `byte_order` attribute in trace (`trace` block): "
4646 "expecting `le`, `be`, or `network`.");
e98a2d6e
PP
4647 ret = -EINVAL;
4648 goto error;
4649 } else if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
28973adf
PP
4650 _BT_LOGE_NODE(node,
4651 "Invalid `byte_order` attribute in trace (`trace` block): "
08da4f77 4652 "cannot be set to `native` here.");
e98a2d6e
PP
4653 ret = -EPERM;
4654 goto error;
4655 }
4656
1e649dff 4657 ctx->trace_bo = bo;
391c8f0d 4658 ret = bt_ctf_trace_set_native_byte_order(
e98a2d6e
PP
4659 ctx->trace, bo);
4660 if (ret) {
28973adf
PP
4661 _BT_LOGE_NODE(node,
4662 "Cannot set trace's byte order: "
08da4f77 4663 "ret=%d", ret);
e98a2d6e
PP
4664 goto error;
4665 }
4666 }
4667
4668 g_free(left);
4669 left = NULL;
4670 }
4671 }
4672
4673 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4674 _BT_LOGE_NODE(trace_node,
4675 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4676 ret = -EINVAL;
4677 goto error;
4678 }
4679
4680 return 0;
4681
4682error:
4683 g_free(left);
4684
4685 return ret;
4686}
4687
4688static
4689int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
ac0c6bdd 4690 struct bt_ctf_clock_class *clock, int *set)
e98a2d6e
PP
4691{
4692 int ret = 0;
4693 char *left = NULL;
4694
4695 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4696 _BT_LOGE_NODE(entry_node,
4697 "Unexpected node type: node-type=%d",
4698 entry_node->type);
e98a2d6e
PP
4699 ret = -EPERM;
4700 goto error;
4701 }
4702
4703 left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4704 if (!left) {
28973adf 4705 _BT_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4706 ret = -EINVAL;
4707 goto error;
4708 }
4709
4710 if (!strcmp(left, "name")) {
4711 char *right;
4712
4713 if (_IS_SET(set, _CLOCK_NAME_SET)) {
28973adf 4714 _BT_LOGE_DUP_ATTR(entry_node, "name", "clock class");
e98a2d6e
PP
4715 ret = -EPERM;
4716 goto error;
4717 }
4718
4719 right = concatenate_unary_strings(
4720 &entry_node->u.ctf_expression.right);
4721 if (!right) {
28973adf
PP
4722 _BT_LOGE_NODE(entry_node,
4723 "Unexpected unary expression for clock class's `name` attribute.");
e98a2d6e
PP
4724 ret = -EINVAL;
4725 goto error;
4726 }
4727
ac0c6bdd 4728 ret = bt_ctf_clock_class_set_name(clock, right);
e98a2d6e 4729 if (ret) {
28973adf
PP
4730 _BT_LOGE_NODE(entry_node,
4731 "cannot set clock class's name");
e98a2d6e
PP
4732 g_free(right);
4733 goto error;
4734 }
4735
4736 g_free(right);
4737 _SET(set, _CLOCK_NAME_SET);
4738 } else if (!strcmp(left, "uuid")) {
4739 unsigned char uuid[BABELTRACE_UUID_LEN];
4740
4741 if (_IS_SET(set, _CLOCK_UUID_SET)) {
28973adf 4742 _BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
e98a2d6e
PP
4743 ret = -EPERM;
4744 goto error;
4745 }
4746
4747 ret = get_unary_uuid(&entry_node->u.ctf_expression.right, uuid);
4748 if (ret) {
28973adf
PP
4749 _BT_LOGE_NODE(entry_node,
4750 "Invalid clock class's `uuid` attribute.");
e98a2d6e
PP
4751 goto error;
4752 }
4753
ac0c6bdd 4754 ret = bt_ctf_clock_class_set_uuid(clock, uuid);
e98a2d6e 4755 if (ret) {
28973adf
PP
4756 _BT_LOGE_NODE(entry_node,
4757 "Cannot set clock class's UUID.");
e98a2d6e
PP
4758 goto error;
4759 }
4760
4761 _SET(set, _CLOCK_UUID_SET);
4762 } else if (!strcmp(left, "description")) {
4763 char *right;
4764
4765 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
28973adf
PP
4766 _BT_LOGE_DUP_ATTR(entry_node, "description",
4767 "clock class");
e98a2d6e
PP
4768 ret = -EPERM;
4769 goto error;
4770 }
4771
4772 right = concatenate_unary_strings(
4773 &entry_node->u.ctf_expression.right);
4774 if (!right) {
28973adf
PP
4775 _BT_LOGE_NODE(entry_node,
4776 "Unexpected unary expression for clock class's `description` attribute.");
e98a2d6e
PP
4777 ret = -EINVAL;
4778 goto error;
4779 }
4780
ac0c6bdd 4781 ret = bt_ctf_clock_class_set_description(clock, right);
e98a2d6e 4782 if (ret) {
28973adf
PP
4783 _BT_LOGE_NODE(entry_node,
4784 "Cannot set clock class's description.");
e98a2d6e
PP
4785 g_free(right);
4786 goto error;
4787 }
4788
4789 g_free(right);
4790 _SET(set, _CLOCK_DESCRIPTION_SET);
4791 } else if (!strcmp(left, "freq")) {
4792 uint64_t freq;
4793
4794 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
28973adf 4795 _BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
e98a2d6e
PP
4796 ret = -EPERM;
4797 goto error;
4798 }
4799
4800 ret = get_unary_unsigned(
4801 &entry_node->u.ctf_expression.right, &freq);
4802 if (ret) {
28973adf
PP
4803 _BT_LOGE_NODE(entry_node,
4804 "Unexpected unary expression for clock class's `freq` attribute.");
e98a2d6e
PP
4805 ret = -EINVAL;
4806 goto error;
4807 }
4808
239744fc
PP
4809 if (freq == -1ULL || freq == 0) {
4810 _BT_LOGE_NODE(entry_node,
4811 "Invalid clock class frequency: freq=%" PRIu64,
4812 freq);
4813 ret = -EINVAL;
4814 goto error;
4815 }
4816
ac0c6bdd 4817 ret = bt_ctf_clock_class_set_frequency(clock, freq);
e98a2d6e 4818 if (ret) {
28973adf
PP
4819 _BT_LOGE_NODE(entry_node,
4820 "Cannot set clock class's frequency.");
e98a2d6e
PP
4821 goto error;
4822 }
4823
4824 _SET(set, _CLOCK_FREQ_SET);
4825 } else if (!strcmp(left, "precision")) {
4826 uint64_t precision;
4827
4828 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
28973adf
PP
4829 _BT_LOGE_DUP_ATTR(entry_node, "precision",
4830 "clock class");
e98a2d6e
PP
4831 ret = -EPERM;
4832 goto error;
4833 }
4834
4835 ret = get_unary_unsigned(
4836 &entry_node->u.ctf_expression.right, &precision);
4837 if (ret) {
28973adf
PP
4838 _BT_LOGE_NODE(entry_node,
4839 "Unexpected unary expression for clock class's `precision` attribute.");
e98a2d6e
PP
4840 ret = -EINVAL;
4841 goto error;
4842 }
4843
ac0c6bdd 4844 ret = bt_ctf_clock_class_set_precision(clock, precision);
e98a2d6e 4845 if (ret) {
28973adf
PP
4846 _BT_LOGE_NODE(entry_node,
4847 "Cannot set clock class's precision.");
e98a2d6e
PP
4848 goto error;
4849 }
4850
4851 _SET(set, _CLOCK_PRECISION_SET);
4852 } else if (!strcmp(left, "offset_s")) {
fb4ac437 4853 int64_t offset_s;
e98a2d6e
PP
4854
4855 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
28973adf
PP
4856 _BT_LOGE_DUP_ATTR(entry_node, "offset_s",
4857 "clock class");
e98a2d6e
PP
4858 ret = -EPERM;
4859 goto error;
4860 }
4861
fb4ac437 4862 ret = get_unary_signed(
e98a2d6e
PP
4863 &entry_node->u.ctf_expression.right, &offset_s);
4864 if (ret) {
28973adf
PP
4865 _BT_LOGE_NODE(entry_node,
4866 "Unexpected unary expression for clock class's `offset_s` attribute.");
e98a2d6e
PP
4867 ret = -EINVAL;
4868 goto error;
4869 }
4870
ac0c6bdd 4871 ret = bt_ctf_clock_class_set_offset_s(clock, offset_s);
e98a2d6e 4872 if (ret) {
28973adf
PP
4873 _BT_LOGE_NODE(entry_node,
4874 "Cannot set clock class's offset in seconds.");
e98a2d6e
PP
4875 goto error;
4876 }
4877
4878 _SET(set, _CLOCK_OFFSET_S_SET);
4879 } else if (!strcmp(left, "offset")) {
fb4ac437 4880 int64_t offset;
e98a2d6e
PP
4881
4882 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
28973adf 4883 _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
e98a2d6e
PP
4884 ret = -EPERM;
4885 goto error;
4886 }
4887
fb4ac437 4888 ret = get_unary_signed(
e98a2d6e
PP
4889 &entry_node->u.ctf_expression.right, &offset);
4890 if (ret) {
28973adf
PP
4891 _BT_LOGE_NODE(entry_node,
4892 "Unexpected unary expression for clock class's `offset` attribute.");
e98a2d6e
PP
4893 ret = -EINVAL;
4894 goto error;
4895 }
4896
ac0c6bdd 4897 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset);
e98a2d6e 4898 if (ret) {
28973adf
PP
4899 _BT_LOGE_NODE(entry_node,
4900 "Cannot set clock class's offset in cycles.");
e98a2d6e
PP
4901 goto error;
4902 }
4903
4904 _SET(set, _CLOCK_OFFSET_SET);
4905 } else if (!strcmp(left, "absolute")) {
4906 struct ctf_node *right;
4907
4908 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
28973adf
PP
4909 _BT_LOGE_DUP_ATTR(entry_node, "absolute",
4910 "clock class");
e98a2d6e
PP
4911 ret = -EPERM;
4912 goto error;
4913 }
4914
4915 right = _BT_LIST_FIRST_ENTRY(
4916 &entry_node->u.ctf_expression.right,
4917 struct ctf_node, siblings);
55314f2a 4918 ret = get_boolean(right);
e98a2d6e 4919 if (ret < 0) {
28973adf
PP
4920 _BT_LOGE_NODE(entry_node,
4921 "Unexpected unary expression for clock class's `absolute` attribute.");
e98a2d6e
PP
4922 ret = -EINVAL;
4923 goto error;
4924 }
4925
ac0c6bdd 4926 ret = bt_ctf_clock_class_set_is_absolute(clock, ret);
e98a2d6e 4927 if (ret) {
28973adf
PP
4928 _BT_LOGE_NODE(entry_node,
4929 "Cannot set clock class's absolute flag.");
e98a2d6e
PP
4930 goto error;
4931 }
4932
4933 _SET(set, _CLOCK_ABSOLUTE_SET);
4934 } else {
28973adf
PP
4935 _BT_LOGW_NODE(entry_node,
4936 "Unknown attribute in clock class: attr-name=\"%s\"",
e98a2d6e
PP
4937 left);
4938 }
4939
4940 g_free(left);
4941 left = NULL;
4942
4943 return 0;
4944
4945error:
4946 g_free(left);
4947
4948 return ret;
4949}
4950
4951static
55314f2a 4952int64_t cycles_from_ns(uint64_t frequency, int64_t ns)
92540773 4953{
55314f2a 4954 int64_t cycles;
92540773
JD
4955
4956 /* 1GHz */
4957 if (frequency == 1000000000ULL) {
4958 cycles = ns;
4959 } else {
4960 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
4961 }
4962
4963 return cycles;
4964}
4965
4966static
1e649dff 4967int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
92540773
JD
4968{
4969 int ret;
4970 uint64_t freq;
4971 int64_t offset_cycles;
a2a54545 4972 int64_t offset_to_apply;
92540773
JD
4973
4974 freq = bt_ctf_clock_class_get_frequency(clock);
4975 if (freq == -1ULL) {
08da4f77 4976 BT_LOGE_STR("Cannot get clock class's frequency.");
92540773
JD
4977 ret = -1;
4978 goto end;
4979 }
4980
4981 ret = bt_ctf_clock_class_get_offset_cycles(clock, &offset_cycles);
4982 if (ret) {
08da4f77 4983 BT_LOGE_STR("Cannot get clock class's offset in cycles.");
92540773
JD
4984 ret = -1;
4985 goto end;
4986 }
4987
a2a54545
PP
4988 offset_to_apply =
4989 ctx->decoder_config.clock_class_offset_s * 1000000000LL +
4990 ctx->decoder_config.clock_class_offset_ns;
4991 offset_cycles += cycles_from_ns(freq, offset_to_apply);
92540773
JD
4992 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
4993
4994end:
4995 return ret;
4996}
4997
4998static
1e649dff 4999int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
e98a2d6e
PP
5000{
5001 int ret = 0;
5002 int set = 0;
ac0c6bdd 5003 struct bt_ctf_clock_class *clock;
e98a2d6e
PP
5004 struct ctf_node *entry_node;
5005 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
f4421ff3 5006 const char *clock_class_name;
e98a2d6e
PP
5007
5008 if (clock_node->visited) {
5009 return 0;
5010 }
5011
5012 clock_node->visited = TRUE;
f3534905
PP
5013
5014 /* CTF 1.8's default frequency for a clock class is 1 GHz */
5015 clock = bt_ctf_clock_class_create(NULL, 1000000000);
e98a2d6e 5016 if (!clock) {
28973adf
PP
5017 _BT_LOGE_NODE(clock_node,
5018 "Cannot create default clock class.");
e98a2d6e
PP
5019 ret = -ENOMEM;
5020 goto error;
5021 }
5022
5023 bt_list_for_each_entry(entry_node, decl_list, siblings) {
5024 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set);
5025 if (ret) {
28973adf
PP
5026 _BT_LOGE_NODE(entry_node,
5027 "Cannot visit clock class's entry: ret=%d",
5028 ret);
e98a2d6e
PP
5029 goto error;
5030 }
5031 }
5032
5033 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
28973adf
PP
5034 _BT_LOGE_NODE(clock_node,
5035 "Missing `name` attribute in clock class.");
e98a2d6e
PP
5036 ret = -EPERM;
5037 goto error;
5038 }
5039
f4421ff3
PP
5040 clock_class_name = bt_ctf_clock_class_get_name(clock);
5041 assert(clock_class_name);
5042 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
5043 /*
5044 * Old versions of LTTng forgot to set its clock class
5045 * as absolute, even if it is. This is important because
5046 * it's a condition to be able to sort notifications
5047 * from different sources.
5048 */
5049 ret = bt_ctf_clock_class_set_is_absolute(clock, 1);
5050 if (ret) {
28973adf
PP
5051 _BT_LOGE_NODE(clock_node,
5052 "Cannot set clock class's absolute flag.");
f4421ff3
PP
5053 goto error;
5054 }
e98a2d6e
PP
5055 }
5056
1e649dff 5057 ret = apply_clock_class_offset(ctx, clock);
92540773 5058 if (ret) {
28973adf
PP
5059 _BT_LOGE_NODE(clock_node,
5060 "Cannot apply clock class's custom offset.");
92540773
JD
5061 goto error;
5062 }
5063
ac0c6bdd 5064 ret = bt_ctf_trace_add_clock_class(ctx->trace, clock);
e98a2d6e 5065 if (ret) {
28973adf
PP
5066 _BT_LOGE_NODE(clock_node,
5067 "Cannot add clock class to trace.");
e98a2d6e
PP
5068 goto error;
5069 }
5070
5071error:
5072 BT_PUT(clock);
5073
5074 return ret;
5075}
5076
5077static
5078int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
5079{
5080 int ret = 0;
5081
5082 if (root_decl_node->visited) {
5083 goto end;
5084 }
5085
5086 root_decl_node->visited = TRUE;
5087
5088 switch (root_decl_node->type) {
5089 case NODE_TYPEDEF:
5090 ret = visit_typedef(ctx,
5091 root_decl_node->u._typedef.type_specifier_list,
5092 &root_decl_node->u._typedef.type_declarators);
5093 if (ret) {
28973adf
PP
5094 _BT_LOGE_NODE(root_decl_node,
5095 "Cannot add type definition found in root scope.");
e98a2d6e
PP
5096 goto end;
5097 }
5098 break;
5099 case NODE_TYPEALIAS:
5100 ret = visit_typealias(ctx, root_decl_node->u.typealias.target,
5101 root_decl_node->u.typealias.alias);
5102 if (ret) {
28973adf
PP
5103 _BT_LOGE_NODE(root_decl_node,
5104 "Cannot add type alias found in root scope.");
e98a2d6e
PP
5105 goto end;
5106 }
5107 break;
5108 case NODE_TYPE_SPECIFIER_LIST:
5109 {
5110 _BT_CTF_FIELD_TYPE_INIT(decl);
5111
5112 /*
5113 * Just add the type specifier to the root
5114 * declaration scope. Put local reference.
5115 */
5116 ret = visit_type_specifier_list(ctx, root_decl_node, &decl);
5117 if (ret) {
28973adf
PP
5118 _BT_LOGE_NODE(root_decl_node,
5119 "Cannot visit root scope's field type: "
5120 "ret=%d", ret);
e98a2d6e
PP
5121 assert(!decl);
5122 goto end;
5123 }
5124
5125 BT_PUT(decl);
5126 break;
5127 }
5128 default:
28973adf
PP
5129 _BT_LOGE_NODE(root_decl_node,
5130 "Unexpected node type: node-type=%d",
5131 root_decl_node->type);
e98a2d6e
PP
5132 ret = -EPERM;
5133 goto end;
5134 }
5135
5136end:
5137 return ret;
5138}
5139
91fd6f6a
PP
5140static
5141int set_trace_name(struct ctx *ctx)
5142{
5143 GString *name;
5144 int ret = 0;
5145 struct bt_value *value = NULL;
5146
5147 assert(bt_ctf_trace_get_stream_class_count(ctx->trace) == 0);
5148 name = g_string_new(NULL);
5149 if (!name) {
28973adf 5150 BT_LOGE_STR("Failed to allocate a GString.");
91fd6f6a
PP
5151 ret = -1;
5152 goto end;
5153 }
5154
5155 /*
5156 * Check if we have a trace environment string value named `hostname`.
5157 * If so, use it as the trace name's prefix.
5158 */
5159 value = bt_ctf_trace_get_environment_field_value_by_name(ctx->trace,
5160 "hostname");
5161 if (bt_value_is_string(value)) {
5162 const char *hostname;
5163
5164 ret = bt_value_string_get(value, &hostname);
5165 assert(ret == 0);
5166 g_string_append(name, hostname);
5167
5168 if (ctx->trace_name_suffix) {
5169 g_string_append_c(name, G_DIR_SEPARATOR);
5170 }
5171 }
5172
5173 if (ctx->trace_name_suffix) {
5174 g_string_append(name, ctx->trace_name_suffix);
5175 }
5176
5177 ret = bt_ctf_trace_set_name(ctx->trace, name->str);
5178 if (ret) {
28973adf 5179 BT_LOGE("Cannot set trace's name: name=\"%s\"", name->str);
91fd6f6a
PP
5180 goto error;
5181 }
5182
5183 goto end;
5184
5185error:
5186 ret = -1;
5187
5188end:
5189 bt_put(value);
5190
5191 if (name) {
5192 g_string_free(name, TRUE);
5193 }
5194
5195 return ret;
5196}
5197
e98a2d6e 5198static
1e649dff 5199int move_ctx_stream_classes_to_trace(struct ctx *ctx)
e98a2d6e 5200{
fde61d26 5201 int ret = 0;
e98a2d6e
PP
5202 GHashTableIter iter;
5203 gpointer key, stream_class;
5204
91fd6f6a
PP
5205 if (g_hash_table_size(ctx->stream_classes) > 0 &&
5206 bt_ctf_trace_get_stream_class_count(ctx->trace) == 0) {
5207 /*
5208 * We're about to add the first stream class to the
5209 * trace. This will freeze the trace, and after this
5210 * we cannot set the name anymore. At this point,
5211 * set the trace name.
5212 */
5213 ret = set_trace_name(ctx);
5214 if (ret) {
28973adf 5215 BT_LOGE_STR("Cannot set trace's name.");
91fd6f6a
PP
5216 goto end;
5217 }
5218 }
5219
e98a2d6e
PP
5220 g_hash_table_iter_init(&iter, ctx->stream_classes);
5221
5222 while (g_hash_table_iter_next(&iter, &key, &stream_class)) {
5223 ret = bt_ctf_trace_add_stream_class(ctx->trace,
5224 stream_class);
5225 if (ret) {
5226 int64_t id = bt_ctf_stream_class_get_id(stream_class);
08da4f77 5227 BT_LOGE("Cannot add stream class to trace: id=%" PRId64,
e98a2d6e
PP
5228 id);
5229 goto end;
5230 }
5231 }
5232
1e649dff
PP
5233 g_hash_table_remove_all(ctx->stream_classes);
5234
e98a2d6e
PP
5235end:
5236 return ret;
5237}
5238
1e649dff 5239BT_HIDDEN
55314f2a 5240struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
a2a54545
PP
5241 const struct ctf_metadata_decoder_config *decoder_config,
5242 const char *name)
e98a2d6e 5243{
1e649dff 5244 int ret;
e98a2d6e 5245 struct ctx *ctx = NULL;
1e649dff 5246 struct bt_ctf_trace *trace;
e98a2d6e 5247
1e649dff
PP
5248 trace = bt_ctf_trace_create();
5249 if (!trace) {
08da4f77 5250 BT_LOGE_STR("Cannot create empty trace.");
e98a2d6e
PP
5251 goto error;
5252 }
5253
835b2d10 5254 /* Set packet header to NULL to override the default one */
1e649dff 5255 ret = bt_ctf_trace_set_packet_header_type(trace, NULL);
e98a2d6e 5256 if (ret) {
08da4f77 5257 BT_LOGE_STR("Cannot reset initial trace's packet header field type.");
e98a2d6e
PP
5258 goto error;
5259 }
5260
1e649dff 5261 /* Create visitor's context */
a2a54545 5262 ctx = ctx_create(trace, decoder_config, name);
e98a2d6e 5263 if (!ctx) {
08da4f77 5264 BT_LOGE_STR("Cannot create visitor's context.");
e98a2d6e
PP
5265 goto error;
5266 }
5267
1e649dff
PP
5268 trace = NULL;
5269 goto end;
5270
5271error:
5272 ctx_destroy(ctx);
5273 ctx = NULL;
5274
5275end:
5276 bt_put(trace);
5277 return (void *) ctx;
5278}
5279
5280BT_HIDDEN
5281void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
5282{
5283 ctx_destroy((void *) visitor);
5284}
5285
5286BT_HIDDEN
5287struct bt_ctf_trace *ctf_visitor_generate_ir_get_trace(
5288 struct ctf_visitor_generate_ir *visitor)
5289{
5290 struct ctx *ctx = (void *) visitor;
5291
5292 assert(ctx);
5293 assert(ctx->trace);
5294 return bt_get(ctx->trace);
5295}
5296
5297BT_HIDDEN
5298int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
5299 struct ctf_node *node)
5300{
5301 int ret = 0;
5302 struct ctx *ctx = (void *) visitor;
5303
08da4f77 5304 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
1e649dff 5305
e98a2d6e
PP
5306 switch (node->type) {
5307 case NODE_ROOT:
5308 {
5309 struct ctf_node *iter;
5310 int got_trace_decl = FALSE;
e98a2d6e
PP
5311
5312 /*
1e649dff
PP
5313 * The first thing we need is the native byte order of
5314 * the trace block, because early type aliases can have
5315 * a `byte_order` attribute set to `native`. If we don't
5316 * have the native byte order yet, and we don't have any
5317 * trace block yet, then fail with EINCOMPLETE.
e98a2d6e 5318 */
1e649dff
PP
5319 if (ctx->trace_bo == BT_CTF_BYTE_ORDER_NATIVE) {
5320 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5321 if (got_trace_decl) {
28973adf
PP
5322 _BT_LOGE_NODE(node,
5323 "Duplicate trace (`trace` block).");
1e649dff
PP
5324 ret = -1;
5325 goto end;
5326 }
e98a2d6e 5327
1e649dff
PP
5328 ret = set_trace_byte_order(ctx, iter);
5329 if (ret) {
28973adf
PP
5330 _BT_LOGE_NODE(node,
5331 "Cannot set trace's native byte order: "
08da4f77 5332 "ret=%d", ret);
1e649dff
PP
5333 goto end;
5334 }
5335
5336 got_trace_decl = TRUE;
e98a2d6e
PP
5337 }
5338
1e649dff 5339 if (!got_trace_decl) {
28973adf 5340 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
1e649dff
PP
5341 ret = -EINCOMPLETE;
5342 goto end;
5343 }
e98a2d6e
PP
5344 }
5345
1e649dff
PP
5346 assert(ctx->trace_bo == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
5347 ctx->trace_bo == BT_CTF_BYTE_ORDER_BIG_ENDIAN);
5348 assert(ctx->current_scope &&
5349 ctx->current_scope->parent_scope == NULL);
e98a2d6e 5350
f4421ff3
PP
5351 /* Environment */
5352 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
5353 ret = visit_env(ctx, iter);
5354 if (ret) {
28973adf
PP
5355 _BT_LOGE_NODE(iter,
5356 "Cannot visit trace's environment (`env` block) entry: "
08da4f77 5357 "ret=%d", ret);
f4421ff3
PP
5358 goto end;
5359 }
5360 }
5361
5362 assert(ctx->current_scope &&
5363 ctx->current_scope->parent_scope == NULL);
5364
e98a2d6e 5365 /*
f4421ff3 5366 * Visit clock blocks.
e98a2d6e
PP
5367 */
5368 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
1e649dff 5369 ret = visit_clock_decl(ctx, iter);
e98a2d6e 5370 if (ret) {
28973adf
PP
5371 _BT_LOGE_NODE(iter,
5372 "Cannot visit clock class: ret=%d",
e98a2d6e 5373 ret);
1e649dff 5374 goto end;
e98a2d6e
PP
5375 }
5376 }
5377
1e649dff
PP
5378 assert(ctx->current_scope &&
5379 ctx->current_scope->parent_scope == NULL);
5380
e98a2d6e
PP
5381 /*
5382 * Visit root declarations next, as they can be used by any
5383 * following entity.
5384 */
5385 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
5386 siblings) {
5387 ret = visit_root_decl(ctx, iter);
5388 if (ret) {
28973adf
PP
5389 _BT_LOGE_NODE(iter,
5390 "Cannot visit root entry: ret=%d",
e98a2d6e 5391 ret);
1e649dff 5392 goto end;
e98a2d6e
PP
5393 }
5394 }
5395
1e649dff
PP
5396 assert(ctx->current_scope &&
5397 ctx->current_scope->parent_scope == NULL);
5398
5399 /* Callsite blocks are not supported */
e98a2d6e 5400 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
28973adf
PP
5401 _BT_LOGW_NODE(iter,
5402 "\"callsite\" blocks are not supported as of this version.");
e98a2d6e
PP
5403 }
5404
1e649dff
PP
5405 assert(ctx->current_scope &&
5406 ctx->current_scope->parent_scope == NULL);
5407
e98a2d6e
PP
5408 /* Trace */
5409 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5410 ret = visit_trace_decl(ctx, iter);
5411 if (ret) {
28973adf
PP
5412 _BT_LOGE_NODE(iter,
5413 "Cannot visit trace (`trace` block): "
08da4f77 5414 "ret=%d", ret);
1e649dff 5415 goto end;
e98a2d6e
PP
5416 }
5417 }
5418
1e649dff
PP
5419 assert(ctx->current_scope &&
5420 ctx->current_scope->parent_scope == NULL);
5421
e98a2d6e
PP
5422 /* Streams */
5423 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
5424 ret = visit_stream_decl(ctx, iter);
5425 if (ret) {
28973adf
PP
5426 _BT_LOGE_NODE(iter,
5427 "Cannot visit stream class: ret=%d",
08da4f77 5428 ret);
1e649dff 5429 goto end;
e98a2d6e
PP
5430 }
5431 }
5432
1e649dff
PP
5433 assert(ctx->current_scope &&
5434 ctx->current_scope->parent_scope == NULL);
5435
e98a2d6e
PP
5436 /* Events */
5437 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
5438 ret = visit_event_decl(ctx, iter);
5439 if (ret) {
28973adf
PP
5440 _BT_LOGE_NODE(iter,
5441 "Cannot visit event class: ret=%d",
08da4f77 5442 ret);
1e649dff 5443 goto end;
e98a2d6e
PP
5444 }
5445 }
1e649dff
PP
5446
5447 assert(ctx->current_scope &&
5448 ctx->current_scope->parent_scope == NULL);
e98a2d6e
PP
5449 break;
5450 }
e98a2d6e 5451 default:
28973adf
PP
5452 _BT_LOGE_NODE(node,
5453 "Unexpected node type: node-type=%d",
08da4f77 5454 node->type);
e98a2d6e 5455 ret = -EINVAL;
1e649dff 5456 goto end;
e98a2d6e
PP
5457 }
5458
1e649dff
PP
5459 /* Move decoded stream classes to trace, if any */
5460 ret = move_ctx_stream_classes_to_trace(ctx);
e98a2d6e 5461 if (ret) {
08da4f77 5462 BT_LOGE("Cannot move stream classes to trace: ret=%d", ret);
e98a2d6e
PP
5463 }
5464
1e649dff 5465end:
e98a2d6e
PP
5466 return ret;
5467}
This page took 0.394582 seconds and 4 git commands to generate.