2 * ctf-visitor-generate-ir.c
4 * Common Trace Format metadata visitor (generates CTF IR objects).
6 * Based on older ctf-visitor-generate-io-struct.c.
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2018 - Philippe Proulx <philippe.proulx@efficios.com>
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
30 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-IR-VISITOR"
39 #include <babeltrace/assert-internal.h>
43 #include <babeltrace/common-internal.h>
44 #include <babeltrace/compat/uuid-internal.h>
45 #include <babeltrace/endian-internal.h>
46 #include <babeltrace/babeltrace.h>
53 #include "ctf-meta-visitors.h"
55 /* Bit value (left shift) */
56 #define _BV(_val) (1 << (_val))
58 /* Bit is set in a set of bits */
59 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
61 /* Set bit in a set of bits */
62 #define _SET(_set, _mask) (*(_set) |= (_mask))
64 /* Try to push scope, or go to the `error` label */
65 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
67 ret = ctx_push_scope(ctx); \
69 BT_LOGE_STR("Cannot push scope."); \
74 /* Bits for verifying existing attributes in various declarations */
76 _CLOCK_NAME_SET
= _BV(0),
77 _CLOCK_UUID_SET
= _BV(1),
78 _CLOCK_FREQ_SET
= _BV(2),
79 _CLOCK_PRECISION_SET
= _BV(3),
80 _CLOCK_OFFSET_S_SET
= _BV(4),
81 _CLOCK_OFFSET_SET
= _BV(5),
82 _CLOCK_ABSOLUTE_SET
= _BV(6),
83 _CLOCK_DESCRIPTION_SET
= _BV(7),
87 _INTEGER_ALIGN_SET
= _BV(0),
88 _INTEGER_SIZE_SET
= _BV(1),
89 _INTEGER_BASE_SET
= _BV(2),
90 _INTEGER_ENCODING_SET
= _BV(3),
91 _INTEGER_BYTE_ORDER_SET
= _BV(4),
92 _INTEGER_SIGNED_SET
= _BV(5),
93 _INTEGER_MAP_SET
= _BV(6),
97 _FLOAT_ALIGN_SET
= _BV(0),
98 _FLOAT_MANT_DIG_SET
= _BV(1),
99 _FLOAT_EXP_DIG_SET
= _BV(2),
100 _FLOAT_BYTE_ORDER_SET
= _BV(3),
104 _STRING_ENCODING_SET
= _BV(0),
108 _TRACE_MINOR_SET
= _BV(0),
109 _TRACE_MAJOR_SET
= _BV(1),
110 _TRACE_BYTE_ORDER_SET
= _BV(2),
111 _TRACE_UUID_SET
= _BV(3),
112 _TRACE_PACKET_HEADER_SET
= _BV(4),
116 _STREAM_ID_SET
= _BV(0),
117 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
118 _STREAM_EVENT_HEADER_SET
= _BV(2),
119 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
123 _EVENT_NAME_SET
= _BV(0),
124 _EVENT_ID_SET
= _BV(1),
125 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
126 _EVENT_STREAM_ID_SET
= _BV(3),
127 _EVENT_LOG_LEVEL_SET
= _BV(4),
128 _EVENT_CONTEXT_SET
= _BV(5),
129 _EVENT_FIELDS_SET
= _BV(6),
137 LOG_LEVEL_WARNING
= 4,
138 LOG_LEVEL_NOTICE
= 5,
140 LOG_LEVEL_DEBUG_SYSTEM
= 7,
141 LOG_LEVEL_DEBUG_PROGRAM
= 8,
142 LOG_LEVEL_DEBUG_PROCESS
= 9,
143 LOG_LEVEL_DEBUG_MODULE
= 10,
144 LOG_LEVEL_DEBUG_UNIT
= 11,
145 LOG_LEVEL_DEBUG_FUNCTION
= 12,
146 LOG_LEVEL_DEBUG_LINE
= 13,
147 LOG_LEVEL_DEBUG
= 14,
151 /* Prefixes of class aliases */
152 #define _PREFIX_ALIAS 'a'
153 #define _PREFIX_ENUM 'e'
154 #define _PREFIX_STRUCT 's'
155 #define _PREFIX_VARIANT 'v'
157 /* First entry in a BT list */
158 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
159 bt_list_entry((_ptr)->next, _class, _member)
161 #define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
162 _BT_LOGE_LINENO((_node)->lineno, \
163 "Duplicate attribute in %s: attr-name=\"%s\"", \
166 #define _BT_LOGE_NODE(_node, _msg, args...) \
167 _BT_LOGE_LINENO((_node)->lineno, _msg, ## args)
169 #define _BT_LOGW_NODE(_node, _msg, args...) \
170 _BT_LOGW_LINENO((_node)->lineno, _msg, ## args)
172 #define _BT_LOGV_NODE(_node, _msg, args...) \
173 _BT_LOGV_LINENO((_node)->lineno, _msg, ## args)
176 * Declaration scope of a visitor context. This represents a TSDL
177 * lexical scope, so that aliases and named structures, variants,
178 * and enumerations may be registered and looked up hierarchically.
180 struct ctx_decl_scope
{
182 * Alias name to field class.
184 * GQuark -> struct ctf_field_class * (owned by this)
186 GHashTable
*decl_map
;
188 /* Parent scope; NULL if this is the root declaration scope */
189 struct ctx_decl_scope
*parent_scope
;
193 * Visitor context (private).
196 /* Trace IR trace class being filled (owned by this) */
197 bt_trace_class
*trace_class
;
199 /* CTF meta trace being filled (owned by this) */
200 struct ctf_trace_class
*ctf_tc
;
202 /* Current declaration scope (top of the stack) (owned by this) */
203 struct ctx_decl_scope
*current_scope
;
205 /* True if trace declaration is visited */
206 bool is_trace_visited
;
208 /* True if this is an LTTng trace */
211 /* Config passed by the user */
212 struct ctf_metadata_decoder_config decoder_config
;
218 struct ctf_visitor_generate_ir
;
221 * Creates a new declaration scope.
223 * @param par_scope Parent scope (NULL if creating a root scope)
224 * @returns New declaration scope, or NULL on error
227 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx_decl_scope
*par_scope
)
229 struct ctx_decl_scope
*scope
;
231 scope
= g_new(struct ctx_decl_scope
, 1);
233 BT_LOGE_STR("Failed to allocate one declaration scope.");
237 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
238 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
239 scope
->parent_scope
= par_scope
;
246 * Destroys a declaration scope.
248 * This function does not destroy the parent scope.
250 * @param scope Scope to destroy
253 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
259 g_hash_table_destroy(scope
->decl_map
);
267 * Returns the GQuark of a prefixed alias.
269 * @param prefix Prefix character
271 * @returns Associated GQuark, or 0 on error
274 GQuark
get_prefixed_named_quark(char prefix
, const char *name
)
280 /* Prefix character + original string + '\0' */
281 char *prname
= g_new(char, strlen(name
) + 2);
283 BT_LOGE_STR("Failed to allocate a string.");
287 sprintf(prname
, "%c%s", prefix
, name
);
288 qname
= g_quark_from_string(prname
);
296 * Looks up a prefixed class alias within a declaration scope.
298 * @param scope Declaration scope
299 * @param prefix Prefix character
300 * @param name Alias name
301 * @param levels Number of levels to dig into (-1 means infinite)
302 * @param copy True to return a copy
303 * @returns Declaration (owned by caller if \p copy is true),
304 * or NULL if not found
307 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
308 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
309 int levels
, bool copy
)
313 struct ctf_field_class
*decl
= NULL
;
314 struct ctx_decl_scope
*cur_scope
= scope
;
318 qname
= get_prefixed_named_quark(prefix
, name
);
327 while (cur_scope
&& cur_levels
< levels
) {
328 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
329 (gconstpointer
) GUINT_TO_POINTER(qname
));
331 /* Caller's reference */
333 decl
= ctf_field_class_copy(decl
);
340 cur_scope
= cur_scope
->parent_scope
;
349 * Looks up a class alias within a declaration scope.
351 * @param scope Declaration scope
352 * @param name Alias name
353 * @param levels Number of levels to dig into (-1 means infinite)
354 * @param copy True to return a copy
355 * @returns Declaration (owned by caller if \p copy is true),
356 * or NULL if not found
359 struct ctf_field_class
*ctx_decl_scope_lookup_alias(
360 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
363 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ALIAS
,
368 * Looks up an enumeration within a declaration scope.
370 * @param scope Declaration scope
371 * @param name Enumeration name
372 * @param levels Number of levels to dig into (-1 means infinite)
373 * @param copy True to return a copy
374 * @returns Declaration (owned by caller if \p copy is true),
375 * or NULL if not found
378 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(
379 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
382 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ENUM
,
387 * Looks up a structure within a declaration scope.
389 * @param scope Declaration scope
390 * @param name Structure name
391 * @param levels Number of levels to dig into (-1 means infinite)
392 * @param copy True to return a copy
393 * @returns Declaration (owned by caller if \p copy is true),
394 * or NULL if not found
397 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(
398 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
401 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
402 _PREFIX_STRUCT
, name
, levels
, copy
);
406 * Looks up a variant within a declaration scope.
408 * @param scope Declaration scope
409 * @param name Variant name
410 * @param levels Number of levels to dig into (-1 means infinite)
411 * @param copy True to return a copy
412 * @returns Declaration (owned by caller if \p copy is true),
413 * or NULL if not found
416 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(
417 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
420 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
421 _PREFIX_VARIANT
, name
, levels
, copy
);
425 * Registers a prefixed class alias within a declaration scope.
427 * @param scope Declaration scope
428 * @param prefix Prefix character
429 * @param name Alias name (non-NULL)
430 * @param decl Field class to register (copied)
431 * @returns 0 if registration went okay, negative value otherwise
434 int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope
*scope
,
435 char prefix
, const char *name
, struct ctf_field_class
*decl
)
443 qname
= get_prefixed_named_quark(prefix
, name
);
449 /* Make sure alias does not exist in local scope */
450 if (ctx_decl_scope_lookup_prefix_alias(scope
, prefix
, name
, 1,
456 decl
= ctf_field_class_copy(decl
);
458 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
465 * Registers a class alias within a declaration scope.
467 * @param scope Declaration scope
468 * @param name Alias name (non-NULL)
469 * @param decl Field class to register (copied)
470 * @returns 0 if registration went okay, negative value otherwise
473 int ctx_decl_scope_register_alias(struct ctx_decl_scope
*scope
,
474 const char *name
, struct ctf_field_class
*decl
)
476 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ALIAS
,
477 name
, (void *) decl
);
481 * Registers an enumeration declaration within a declaration scope.
483 * @param scope Declaration scope
484 * @param name Enumeration name (non-NULL)
485 * @param decl Enumeration field class to register (copied)
486 * @returns 0 if registration went okay, negative value otherwise
489 int ctx_decl_scope_register_enum(struct ctx_decl_scope
*scope
,
490 const char *name
, struct ctf_field_class_enum
*decl
)
492 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ENUM
,
493 name
, (void *) decl
);
497 * Registers a structure declaration within a declaration scope.
499 * @param scope Declaration scope
500 * @param name Structure name (non-NULL)
501 * @param decl Structure field class to register (copied)
502 * @returns 0 if registration went okay, negative value otherwise
505 int ctx_decl_scope_register_struct(struct ctx_decl_scope
*scope
,
506 const char *name
, struct ctf_field_class_struct
*decl
)
508 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_STRUCT
,
509 name
, (void *) decl
);
513 * Registers a variant declaration within a declaration scope.
515 * @param scope Declaration scope
516 * @param name Variant name (non-NULL)
517 * @param decl Variant field class to register
518 * @returns 0 if registration went okay, negative value otherwise
521 int ctx_decl_scope_register_variant(struct ctx_decl_scope
*scope
,
522 const char *name
, struct ctf_field_class_variant
*decl
)
524 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_VARIANT
,
525 name
, (void *) decl
);
529 * Destroys a visitor context.
531 * @param ctx Visitor context to destroy
534 void ctx_destroy(struct ctx
*ctx
)
536 struct ctx_decl_scope
*scope
;
542 scope
= ctx
->current_scope
;
545 * Destroy all scopes, from current one to the root scope.
548 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
550 ctx_decl_scope_destroy(scope
);
551 scope
= parent_scope
;
554 bt_trace_class_put_ref(ctx
->trace_class
);
557 ctf_trace_class_destroy(ctx
->ctf_tc
);
567 * Creates a new visitor context.
569 * @param trace Associated trace
570 * @returns New visitor context, or NULL on error
573 struct ctx
*ctx_create(
574 const struct ctf_metadata_decoder_config
*decoder_config
)
576 struct ctx
*ctx
= NULL
;
578 BT_ASSERT(decoder_config
);
580 ctx
= g_new0(struct ctx
, 1);
582 BT_LOGE_STR("Failed to allocate one visitor context.");
586 ctx
->trace_class
= bt_trace_class_create();
587 if (!ctx
->trace_class
) {
588 BT_LOGE_STR("Cannot create empty trace class.");
592 ctx
->ctf_tc
= ctf_trace_class_create();
594 BT_LOGE_STR("Cannot create CTF trace class.");
598 /* Root declaration scope */
599 ctx
->current_scope
= ctx_decl_scope_create(NULL
);
600 if (!ctx
->current_scope
) {
601 BT_LOGE_STR("Cannot create declaration scope.");
605 ctx
->decoder_config
= *decoder_config
;
617 * Pushes a new declaration scope on top of a visitor context's
618 * declaration scope stack.
620 * @param ctx Visitor context
621 * @returns 0 on success, or a negative value on error
624 int ctx_push_scope(struct ctx
*ctx
)
627 struct ctx_decl_scope
*new_scope
;
630 new_scope
= ctx_decl_scope_create(ctx
->current_scope
);
632 BT_LOGE_STR("Cannot create declaration scope.");
637 ctx
->current_scope
= new_scope
;
644 void ctx_pop_scope(struct ctx
*ctx
)
646 struct ctx_decl_scope
*parent_scope
= NULL
;
650 if (!ctx
->current_scope
) {
654 parent_scope
= ctx
->current_scope
->parent_scope
;
655 ctx_decl_scope_destroy(ctx
->current_scope
);
656 ctx
->current_scope
= parent_scope
;
663 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
664 struct ctf_field_class
**decl
);
667 char *remove_underscores_from_field_ref(const char *field_ref
)
673 UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
,
674 UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
,
675 } state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
677 BT_ASSERT(field_ref
);
678 ret
= calloc(strlen(field_ref
) + 1, 1);
680 BT_LOGE("Failed to allocate a string: size=%zu",
681 strlen(field_ref
) + 1);
688 while (*in_ch
!= '\0') {
692 /* Remove whitespace */
696 if (state
== UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
) {
698 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
704 state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
707 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
722 int is_unary_string(struct bt_list_head
*head
)
725 struct ctf_node
*node
;
727 bt_list_for_each_entry(node
, head
, siblings
) {
728 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
732 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
741 char *concatenate_unary_strings(struct bt_list_head
*head
)
745 struct ctf_node
*node
;
747 str
= g_string_new(NULL
);
750 bt_list_for_each_entry(node
, head
, siblings
) {
754 node
->type
!= NODE_UNARY_EXPRESSION
||
755 node
->u
.unary_expression
.type
!= UNARY_STRING
||
758 node
->u
.unary_expression
.link
!=
766 switch (node
->u
.unary_expression
.link
) {
768 g_string_append(str
, ".");
770 case UNARY_ARROWLINK
:
771 g_string_append(str
, "->");
773 case UNARY_DOTDOTDOT
:
774 g_string_append(str
, "...");
780 src_string
= node
->u
.unary_expression
.u
.string
;
781 g_string_append(str
, src_string
);
785 /* Destroys the container, returns the underlying string */
786 return g_string_free(str
, FALSE
);
789 /* This always returns NULL */
790 return g_string_free(str
, TRUE
);
794 const char *get_map_clock_name_value(struct bt_list_head
*head
)
797 struct ctf_node
*node
;
798 const char *name
= NULL
;
800 bt_list_for_each_entry(node
, head
, siblings
) {
802 int uexpr_type
= node
->u
.unary_expression
.type
;
803 int uexpr_link
= node
->u
.unary_expression
.link
;
804 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
805 uexpr_type
!= UNARY_STRING
||
806 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
811 /* Needs to be chained with . */
812 switch (node
->u
.unary_expression
.link
) {
815 case UNARY_ARROWLINK
:
816 case UNARY_DOTDOTDOT
:
822 src_string
= node
->u
.unary_expression
.u
.string
;
826 if (strcmp("clock", src_string
)) {
834 if (strcmp("value", src_string
)) {
839 /* Extra identifier, unknown */
853 int is_unary_unsigned(struct bt_list_head
*head
)
856 struct ctf_node
*node
;
858 bt_list_for_each_entry(node
, head
, siblings
) {
859 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
863 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
872 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
876 struct ctf_node
*node
;
880 if (bt_list_empty(head
)) {
885 bt_list_for_each_entry(node
, head
, siblings
) {
886 int uexpr_type
= node
->u
.unary_expression
.type
;
887 int uexpr_link
= node
->u
.unary_expression
.link
;
888 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
889 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
890 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
892 _BT_LOGE_NODE(node
, "Invalid constant unsigned integer.");
897 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
906 int is_unary_signed(struct bt_list_head
*head
)
909 struct ctf_node
*node
;
911 bt_list_for_each_entry(node
, head
, siblings
) {
912 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
916 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
925 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
929 struct ctf_node
*node
;
931 bt_list_for_each_entry(node
, head
, siblings
) {
932 int uexpr_type
= node
->u
.unary_expression
.type
;
933 int uexpr_link
= node
->u
.unary_expression
.link
;
934 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
935 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
936 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
937 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
943 switch (uexpr_type
) {
944 case UNARY_UNSIGNED_CONSTANT
:
946 node
->u
.unary_expression
.u
.unsigned_constant
;
948 case UNARY_SIGNED_CONSTANT
:
949 *value
= node
->u
.unary_expression
.u
.signed_constant
;
964 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
968 struct ctf_node
*node
;
970 bt_list_for_each_entry(node
, head
, siblings
) {
971 int uexpr_type
= node
->u
.unary_expression
.type
;
972 int uexpr_link
= node
->u
.unary_expression
.link
;
973 const char *src_string
;
975 if (node
->type
!= NODE_UNARY_EXPRESSION
||
976 uexpr_type
!= UNARY_STRING
||
977 uexpr_link
!= UNARY_LINK_UNKNOWN
||
983 src_string
= node
->u
.unary_expression
.u
.string
;
984 ret
= bt_uuid_parse(src_string
, uuid
);
987 "Cannot parse UUID: uuid=\"%s\"", src_string
);
997 int get_boolean(struct ctf_node
*unary_expr
)
1001 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
1002 _BT_LOGE_NODE(unary_expr
,
1003 "Expecting unary expression: node-type=%d",
1009 switch (unary_expr
->u
.unary_expression
.type
) {
1010 case UNARY_UNSIGNED_CONSTANT
:
1011 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
1013 case UNARY_SIGNED_CONSTANT
:
1014 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
1018 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
1020 if (!strcmp(str
, "true") || !strcmp(str
, "TRUE")) {
1022 } else if (!strcmp(str
, "false") || !strcmp(str
, "FALSE")) {
1025 _BT_LOGE_NODE(unary_expr
,
1026 "Unexpected boolean value: value=\"%s\"", str
);
1033 _BT_LOGE_NODE(unary_expr
,
1034 "Unexpected unary expression type: node-type=%d",
1035 unary_expr
->u
.unary_expression
.type
);
1045 enum ctf_byte_order
byte_order_from_unary_expr(struct ctf_node
*unary_expr
)
1048 enum ctf_byte_order bo
= -1;
1050 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1051 _BT_LOGE_NODE(unary_expr
,
1052 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1056 str
= unary_expr
->u
.unary_expression
.u
.string
;
1058 if (!strcmp(str
, "be") || !strcmp(str
, "network")) {
1059 bo
= CTF_BYTE_ORDER_BIG
;
1060 } else if (!strcmp(str
, "le")) {
1061 bo
= CTF_BYTE_ORDER_LITTLE
;
1062 } else if (!strcmp(str
, "native")) {
1063 bo
= CTF_BYTE_ORDER_DEFAULT
;
1065 _BT_LOGE_NODE(unary_expr
,
1066 "Unexpected \"byte_order\" attribute value: "
1067 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1077 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1078 struct ctf_node
*uexpr
)
1080 enum ctf_byte_order bo
= byte_order_from_unary_expr(uexpr
);
1082 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
1083 bo
= ctx
->ctf_tc
->default_byte_order
;
1090 int is_align_valid(uint64_t align
)
1092 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
1096 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
1101 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1102 _BT_LOGE_NODE(cls_specifier
,
1103 "Unexpected node type: node-type=%d",
1104 cls_specifier
->type
);
1109 switch (cls_specifier
->u
.field_class_specifier
.type
) {
1111 g_string_append(str
, "void");
1114 g_string_append(str
, "char");
1116 case TYPESPEC_SHORT
:
1117 g_string_append(str
, "short");
1120 g_string_append(str
, "int");
1123 g_string_append(str
, "long");
1125 case TYPESPEC_FLOAT
:
1126 g_string_append(str
, "float");
1128 case TYPESPEC_DOUBLE
:
1129 g_string_append(str
, "double");
1131 case TYPESPEC_SIGNED
:
1132 g_string_append(str
, "signed");
1134 case TYPESPEC_UNSIGNED
:
1135 g_string_append(str
, "unsigned");
1138 g_string_append(str
, "bool");
1140 case TYPESPEC_COMPLEX
:
1141 g_string_append(str
, "_Complex");
1143 case TYPESPEC_IMAGINARY
:
1144 g_string_append(str
, "_Imaginary");
1146 case TYPESPEC_CONST
:
1147 g_string_append(str
, "const");
1149 case TYPESPEC_ID_TYPE
:
1150 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1151 g_string_append(str
,
1152 cls_specifier
->u
.field_class_specifier
.id_type
);
1155 case TYPESPEC_STRUCT
:
1157 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1159 if (!node
->u
._struct
.name
) {
1160 _BT_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1165 g_string_append(str
, "struct ");
1166 g_string_append(str
, node
->u
._struct
.name
);
1169 case TYPESPEC_VARIANT
:
1171 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1173 if (!node
->u
.variant
.name
) {
1174 _BT_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1179 g_string_append(str
, "variant ");
1180 g_string_append(str
, node
->u
.variant
.name
);
1185 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1187 if (!node
->u
._enum
.enum_id
) {
1189 "Unexpected empty enumeration field class (`enum`) name.");
1194 g_string_append(str
, "enum ");
1195 g_string_append(str
, node
->u
._enum
.enum_id
);
1198 case TYPESPEC_FLOATING_POINT
:
1199 case TYPESPEC_INTEGER
:
1200 case TYPESPEC_STRING
:
1202 _BT_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1203 "Unexpected field class specifier type: %d",
1204 cls_specifier
->u
.field_class_specifier
.type
);
1214 int get_class_specifier_list_name(struct ctx
*ctx
,
1215 struct ctf_node
*cls_specifier_list
, GString
*str
)
1218 struct ctf_node
*iter
;
1219 int alias_item_nr
= 0;
1220 struct bt_list_head
*head
=
1221 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1223 bt_list_for_each_entry(iter
, head
, siblings
) {
1224 if (alias_item_nr
!= 0) {
1225 g_string_append(str
, " ");
1229 ret
= get_class_specifier_name(ctx
, iter
, str
);
1240 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1241 struct ctf_node
*cls_specifier_list
,
1242 struct ctf_node
*node_field_class_declarator
)
1248 struct ctf_node
*iter
;
1249 struct bt_list_head
*pointers
=
1250 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1252 str
= g_string_new("");
1253 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1255 g_string_free(str
, TRUE
);
1259 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1260 g_string_append(str
, " *");
1262 if (iter
->u
.pointer
.const_qualifier
) {
1263 g_string_append(str
, " const");
1267 str_c
= g_string_free(str
, FALSE
);
1268 qalias
= g_quark_from_string(str_c
);
1276 int visit_field_class_declarator(struct ctx
*ctx
,
1277 struct ctf_node
*cls_specifier_list
,
1278 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1279 struct ctf_field_class
**field_decl
,
1280 struct ctf_field_class
*nested_decl
)
1283 * During this whole function, nested_decl is always OURS,
1284 * whereas field_decl is an output which we create, but
1285 * belongs to the caller (it is moved).
1290 /* Validate field class declarator node */
1291 if (node_field_class_declarator
) {
1292 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1294 _BT_LOGE_NODE(node_field_class_declarator
,
1295 "Unexpected field class declarator type: type=%d",
1296 node_field_class_declarator
->u
.field_class_declarator
.type
);
1301 /* TODO: GCC bitfields not supported yet */
1302 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1304 _BT_LOGE_NODE(node_field_class_declarator
,
1305 "GCC bitfields are not supported as of this version.");
1311 /* Find the right nested declaration if not provided */
1313 struct bt_list_head
*pointers
=
1314 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1316 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1320 * If we have a pointer declarator, it HAS to
1321 * be present in the field class aliases (else
1324 qalias
= create_class_alias_identifier(ctx
,
1325 cls_specifier_list
, node_field_class_declarator
);
1327 ctx_decl_scope_lookup_alias(ctx
->current_scope
,
1328 g_quark_to_string(qalias
), -1, true);
1330 _BT_LOGE_NODE(node_field_class_declarator
,
1331 "Cannot find class alias: name=\"%s\"",
1332 g_quark_to_string(qalias
));
1337 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1338 /* Pointer: force integer's base to 16 */
1339 struct ctf_field_class_int
*int_fc
=
1340 (void *) nested_decl
;
1343 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1346 ret
= visit_field_class_specifier_list(ctx
,
1347 cls_specifier_list
, &nested_decl
);
1349 BT_ASSERT(!nested_decl
);
1355 BT_ASSERT(nested_decl
);
1357 if (!node_field_class_declarator
) {
1358 *field_decl
= nested_decl
;
1363 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1364 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1366 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1372 *field_name
= g_quark_from_string(id
);
1377 *field_decl
= nested_decl
;
1381 struct ctf_node
*first
;
1382 struct ctf_field_class
*decl
= NULL
;
1383 struct ctf_field_class
*outer_field_decl
= NULL
;
1384 struct bt_list_head
*length
=
1385 &node_field_class_declarator
->
1386 u
.field_class_declarator
.u
.nested
.length
;
1388 /* Create array/sequence, pass nested_decl as child */
1389 if (bt_list_empty(length
)) {
1390 _BT_LOGE_NODE(node_field_class_declarator
,
1391 "Expecting length field reference or value.");
1396 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1397 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1398 _BT_LOGE_NODE(first
,
1399 "Unexpected node type: node-type=%d",
1405 switch (first
->u
.unary_expression
.type
) {
1406 case UNARY_UNSIGNED_CONSTANT
:
1408 struct ctf_field_class_array
*array_decl
= NULL
;
1410 array_decl
= ctf_field_class_array_create();
1411 BT_ASSERT(array_decl
);
1412 array_decl
->length
=
1413 first
->u
.unary_expression
.u
.unsigned_constant
;
1414 array_decl
->base
.elem_fc
= nested_decl
;
1416 decl
= (void *) array_decl
;
1421 /* Lookup unsigned integer definition, create seq. */
1422 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1423 char *length_name
= concatenate_unary_strings(length
);
1426 _BT_LOGE_NODE(node_field_class_declarator
,
1427 "Cannot concatenate unary strings.");
1432 if (strncmp(length_name
, "env.", 4) == 0) {
1433 /* This is, in fact, an array */
1434 const char *env_entry_name
= &length_name
[4];
1435 struct ctf_trace_class_env_entry
*env_entry
=
1436 ctf_trace_class_borrow_env_entry_by_name(
1437 ctx
->ctf_tc
, env_entry_name
);
1438 struct ctf_field_class_array
*array_decl
;
1441 _BT_LOGE_NODE(node_field_class_declarator
,
1442 "Cannot find environment entry: "
1443 "name=\"%s\"", env_entry_name
);
1448 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1449 _BT_LOGE_NODE(node_field_class_declarator
,
1450 "Wrong environment entry type "
1451 "(expecting integer): "
1452 "name=\"%s\"", env_entry_name
);
1457 if (env_entry
->value
.i
< 0) {
1458 _BT_LOGE_NODE(node_field_class_declarator
,
1459 "Invalid, negative array length: "
1460 "env-entry-name=\"%s\", "
1463 env_entry
->value
.i
);
1468 array_decl
= ctf_field_class_array_create();
1469 BT_ASSERT(array_decl
);
1470 array_decl
->length
=
1471 (uint64_t) env_entry
->value
.i
;
1472 array_decl
->base
.elem_fc
= nested_decl
;
1474 decl
= (void *) array_decl
;
1476 char *length_name_no_underscore
=
1477 remove_underscores_from_field_ref(
1479 if (!length_name_no_underscore
) {
1481 * remove_underscores_from_field_ref()
1487 seq_decl
= ctf_field_class_sequence_create();
1488 BT_ASSERT(seq_decl
);
1489 seq_decl
->base
.elem_fc
= nested_decl
;
1491 g_string_assign(seq_decl
->length_ref
,
1492 length_name_no_underscore
);
1493 free(length_name_no_underscore
);
1494 decl
= (void *) seq_decl
;
1497 g_free(length_name
);
1505 BT_ASSERT(!nested_decl
);
1507 BT_ASSERT(!*field_decl
);
1510 * At this point, we found the next nested declaration.
1511 * We currently own this (and lost the ownership of
1512 * nested_decl in the meantime). Pass this next
1513 * nested declaration as the content of the outer
1514 * container, MOVING its ownership.
1516 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1518 node_field_class_declarator
->
1519 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1520 &outer_field_decl
, decl
);
1523 BT_ASSERT(!outer_field_decl
);
1528 BT_ASSERT(outer_field_decl
);
1529 *field_decl
= outer_field_decl
;
1530 outer_field_decl
= NULL
;
1533 BT_ASSERT(*field_decl
);
1537 ctf_field_class_destroy(*field_decl
);
1545 ctf_field_class_destroy(nested_decl
);
1551 int visit_struct_decl_field(struct ctx
*ctx
,
1552 struct ctf_field_class_struct
*struct_decl
,
1553 struct ctf_node
*cls_specifier_list
,
1554 struct bt_list_head
*field_class_declarators
)
1557 struct ctf_node
*iter
;
1558 struct ctf_field_class
*field_decl
= NULL
;
1560 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1563 const char *field_name
;
1565 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1566 &qfield_name
, iter
, &field_decl
, NULL
);
1568 BT_ASSERT(!field_decl
);
1569 _BT_LOGE_NODE(cls_specifier_list
,
1570 "Cannot visit field class declarator: ret=%d", ret
);
1574 BT_ASSERT(field_decl
);
1575 field_name
= g_quark_to_string(qfield_name
);
1577 /* Check if field with same name already exists */
1578 if (ctf_field_class_struct_borrow_member_by_name(
1579 struct_decl
, field_name
)) {
1580 _BT_LOGE_NODE(cls_specifier_list
,
1581 "Duplicate field in structure field class: "
1582 "field-name=\"%s\"", field_name
);
1587 /* Add field to structure */
1588 ctf_field_class_struct_append_member(struct_decl
,
1589 field_name
, field_decl
);
1596 ctf_field_class_destroy(field_decl
);
1602 int visit_variant_decl_field(struct ctx
*ctx
,
1603 struct ctf_field_class_variant
*variant_decl
,
1604 struct ctf_node
*cls_specifier_list
,
1605 struct bt_list_head
*field_class_declarators
)
1608 struct ctf_node
*iter
;
1609 struct ctf_field_class
*field_decl
= NULL
;
1611 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1614 const char *field_name
;
1616 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1617 &qfield_name
, iter
, &field_decl
, NULL
);
1619 BT_ASSERT(!field_decl
);
1620 _BT_LOGE_NODE(cls_specifier_list
,
1621 "Cannot visit field class declarator: ret=%d", ret
);
1625 BT_ASSERT(field_decl
);
1626 field_name
= g_quark_to_string(qfield_name
);
1628 /* Check if field with same name already exists */
1629 if (ctf_field_class_variant_borrow_option_by_name(
1630 variant_decl
, field_name
)) {
1631 _BT_LOGE_NODE(cls_specifier_list
,
1632 "Duplicate field in variant field class: "
1633 "field-name=\"%s\"", field_name
);
1638 /* Add field to structure */
1639 ctf_field_class_variant_append_option(variant_decl
,
1640 field_name
, field_decl
);
1647 ctf_field_class_destroy(field_decl
);
1653 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1654 struct bt_list_head
*field_class_declarators
)
1658 struct ctf_node
*iter
;
1659 struct ctf_field_class
*class_decl
= NULL
;
1661 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1662 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1663 &qidentifier
, iter
, &class_decl
, NULL
);
1666 "Cannot visit field class declarator: ret=%d", ret
);
1671 /* Do not allow field class def and alias of untagged variants */
1672 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1673 struct ctf_field_class_variant
*var_fc
=
1674 (void *) class_decl
;
1676 if (var_fc
->tag_path
.path
->len
== 0) {
1678 "Type definition of untagged variant field class is not allowed.");
1684 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1685 g_quark_to_string(qidentifier
), class_decl
);
1688 "Cannot register field class alias: name=\"%s\"",
1689 g_quark_to_string(qidentifier
));
1695 ctf_field_class_destroy(class_decl
);
1701 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1702 struct ctf_node
*alias
)
1706 struct ctf_node
*node
;
1707 GQuark qdummy_field_name
;
1708 struct ctf_field_class
*class_decl
= NULL
;
1710 /* Create target field class */
1711 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1714 node
= _BT_LIST_FIRST_ENTRY(
1715 &target
->u
.field_class_alias_target
.field_class_declarators
,
1716 struct ctf_node
, siblings
);
1719 ret
= visit_field_class_declarator(ctx
,
1720 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1721 &qdummy_field_name
, node
, &class_decl
, NULL
);
1723 BT_ASSERT(!class_decl
);
1725 "Cannot visit field class declarator: ret=%d", ret
);
1729 /* Do not allow field class def and alias of untagged variants */
1730 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1731 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1733 if (var_fc
->tag_path
.path
->len
== 0) {
1734 _BT_LOGE_NODE(target
,
1735 "Type definition of untagged variant field class is not allowed.");
1742 * The semantic validator does not check whether the target is
1743 * abstract or not (if it has an identifier). Check it here.
1745 if (qdummy_field_name
!= 0) {
1746 _BT_LOGE_NODE(target
,
1747 "Expecting empty identifier: id=\"%s\"",
1748 g_quark_to_string(qdummy_field_name
));
1753 /* Create alias identifier */
1754 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1755 struct ctf_node
, siblings
);
1756 qalias
= create_class_alias_identifier(ctx
,
1757 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1758 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1759 g_quark_to_string(qalias
), class_decl
);
1762 "Cannot register class alias: name=\"%s\"",
1763 g_quark_to_string(qalias
));
1768 ctf_field_class_destroy(class_decl
);
1774 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1775 struct ctf_field_class_struct
*struct_decl
)
1779 switch (entry_node
->type
) {
1781 ret
= visit_field_class_def(ctx
,
1782 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1783 &entry_node
->u
.field_class_def
.field_class_declarators
);
1785 _BT_LOGE_NODE(entry_node
,
1786 "Cannot add field class found in structure field class: ret=%d",
1791 case NODE_TYPEALIAS
:
1792 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1793 entry_node
->u
.field_class_alias
.alias
);
1795 _BT_LOGE_NODE(entry_node
,
1796 "Cannot add field class alias found in structure field class: ret=%d",
1801 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1803 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1804 entry_node
->u
.struct_or_variant_declaration
.
1805 field_class_specifier_list
,
1806 &entry_node
->u
.struct_or_variant_declaration
.
1807 field_class_declarators
);
1813 _BT_LOGE_NODE(entry_node
,
1814 "Unexpected node type: node-type=%d", entry_node
->type
);
1824 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1825 struct ctf_field_class_variant
*variant_decl
)
1829 switch (entry_node
->type
) {
1831 ret
= visit_field_class_def(ctx
,
1832 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1833 &entry_node
->u
.field_class_def
.field_class_declarators
);
1835 _BT_LOGE_NODE(entry_node
,
1836 "Cannot add field class found in variant field class: ret=%d",
1841 case NODE_TYPEALIAS
:
1842 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1843 entry_node
->u
.field_class_alias
.alias
);
1845 _BT_LOGE_NODE(entry_node
,
1846 "Cannot add field class alias found in variant field class: ret=%d",
1851 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1853 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1854 entry_node
->u
.struct_or_variant_declaration
.
1855 field_class_specifier_list
,
1856 &entry_node
->u
.struct_or_variant_declaration
.
1857 field_class_declarators
);
1863 _BT_LOGE_NODE(entry_node
,
1864 "Unexpected node type: node-type=%d",
1875 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1876 struct bt_list_head
*decl_list
, int has_body
,
1877 struct bt_list_head
*min_align
,
1878 struct ctf_field_class_struct
**struct_decl
)
1882 BT_ASSERT(struct_decl
);
1883 *struct_decl
= NULL
;
1885 /* For named struct (without body), lookup in declaration scope */
1888 BT_LOGE_STR("Bodyless structure field class: missing name.");
1893 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1895 if (!*struct_decl
) {
1896 BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
1902 struct ctf_node
*entry_node
;
1903 uint64_t min_align_value
= 0;
1906 if (ctx_decl_scope_lookup_struct(
1907 ctx
->current_scope
, name
, 1, false)) {
1908 BT_LOGE("Structure field class already declared in local scope: "
1909 "name=\"struct %s\"", name
);
1915 if (!bt_list_empty(min_align
)) {
1916 ret
= get_unary_unsigned(min_align
, &min_align_value
);
1918 BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1924 *struct_decl
= ctf_field_class_struct_create();
1925 BT_ASSERT(*struct_decl
);
1927 if (min_align_value
!= 0) {
1928 (*struct_decl
)->base
.alignment
= min_align_value
;
1931 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1933 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1934 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1937 _BT_LOGE_NODE(entry_node
,
1938 "Cannot visit structure field class entry: "
1948 ret
= ctx_decl_scope_register_struct(ctx
->current_scope
,
1949 name
, *struct_decl
);
1951 BT_LOGE("Cannot register structure field class in declaration scope: "
1952 "name=\"struct %s\", ret=%d", name
, ret
);
1961 ctf_field_class_destroy((void *) *struct_decl
);
1962 *struct_decl
= NULL
;
1967 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1968 const char *tag
, struct bt_list_head
*decl_list
,
1969 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1972 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1974 BT_ASSERT(variant_decl
);
1975 *variant_decl
= NULL
;
1977 /* For named variant (without body), lookup in declaration scope */
1980 BT_LOGE_STR("Bodyless variant field class: missing name.");
1985 untagged_variant_decl
=
1986 ctx_decl_scope_lookup_variant(ctx
->current_scope
,
1988 if (!untagged_variant_decl
) {
1989 BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
1995 struct ctf_node
*entry_node
;
1998 if (ctx_decl_scope_lookup_variant(ctx
->current_scope
,
2000 BT_LOGE("Variant field class already declared in local scope: "
2001 "name=\"variant %s\"", name
);
2007 untagged_variant_decl
= ctf_field_class_variant_create();
2008 BT_ASSERT(untagged_variant_decl
);
2009 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
2011 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
2012 ret
= visit_variant_decl_entry(ctx
, entry_node
,
2013 untagged_variant_decl
);
2015 _BT_LOGE_NODE(entry_node
,
2016 "Cannot visit variant field class entry: "
2026 ret
= ctx_decl_scope_register_variant(
2027 ctx
->current_scope
, name
,
2028 untagged_variant_decl
);
2030 BT_LOGE("Cannot register variant field class in declaration scope: "
2031 "name=\"variant %s\", ret=%d", name
, ret
);
2038 * If tagged, create tagged variant and return; otherwise
2039 * return untagged variant.
2042 *variant_decl
= untagged_variant_decl
;
2043 untagged_variant_decl
= NULL
;
2046 * At this point, we have a fresh untagged variant; nobody
2047 * else owns it. Set its tag now.
2049 char *tag_no_underscore
=
2050 remove_underscores_from_field_ref(tag
);
2052 if (!tag_no_underscore
) {
2053 /* remove_underscores_from_field_ref() logs errors */
2057 g_string_assign(untagged_variant_decl
->tag_ref
,
2059 free(tag_no_underscore
);
2060 *variant_decl
= untagged_variant_decl
;
2061 untagged_variant_decl
= NULL
;
2064 BT_ASSERT(!untagged_variant_decl
);
2065 BT_ASSERT(*variant_decl
);
2069 ctf_field_class_destroy((void *) untagged_variant_decl
);
2070 untagged_variant_decl
= NULL
;
2071 ctf_field_class_destroy((void *) *variant_decl
);
2072 *variant_decl
= NULL
;
2085 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
2086 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
2090 struct ctf_node
*iter
;
2091 struct uori start
= {
2099 const char *label
= enumerator
->u
.enumerator
.id
;
2100 const char *effective_label
= label
;
2101 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2103 bt_list_for_each_entry(iter
, values
, siblings
) {
2104 struct uori
*target
;
2106 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2108 "Wrong expression for enumeration field class label: "
2109 "node-type=%d, label=\"%s\"", iter
->type
,
2121 switch (iter
->u
.unary_expression
.type
) {
2122 case UNARY_SIGNED_CONSTANT
:
2123 target
->is_signed
= true;
2125 iter
->u
.unary_expression
.u
.signed_constant
;
2127 case UNARY_UNSIGNED_CONSTANT
:
2128 target
->is_signed
= false;
2130 iter
->u
.unary_expression
.u
.unsigned_constant
;
2134 "Invalid enumeration field class entry: "
2135 "expecting constant signed or unsigned integer: "
2136 "node-type=%d, label=\"%s\"",
2137 iter
->u
.unary_expression
.type
, label
);
2144 "Invalid enumeration field class entry: label=\"%s\"",
2161 if (end
.is_signed
) {
2162 last
->value
.i
= end
.value
.i
+ 1;
2164 last
->value
.u
= end
.value
.u
+ 1;
2167 if (label
[0] == '_') {
2169 * Strip the first underscore of any enumeration field
2170 * class's label in case this enumeration FC is used as
2171 * a variant FC tag later. The variant FC choice names
2172 * could also start with `_`, in which case the prefix
2173 * is removed, and it the resulting choice name needs to
2176 effective_label
= &label
[1];
2179 ctf_field_class_enum_append_mapping(enum_decl
, effective_label
,
2180 start
.value
.u
, end
.value
.u
);
2188 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2189 struct ctf_node
*container_cls
,
2190 struct bt_list_head
*enumerator_list
,
2191 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2195 struct ctf_field_class_int
*integer_decl
= NULL
;
2197 BT_ASSERT(enum_decl
);
2200 /* For named enum (without body), lookup in declaration scope */
2203 BT_LOGE_STR("Bodyless enumeration field class: missing name.");
2208 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2211 BT_LOGE("Cannot find enumeration field class: "
2212 "name=\"enum %s\"", name
);
2217 struct ctf_node
*iter
;
2218 struct uori last_value
= {
2224 if (ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2226 BT_LOGE("Enumeration field class already declared in local scope: "
2227 "name=\"enum %s\"", name
);
2233 if (!container_cls
) {
2234 integer_decl
= (void *) ctx_decl_scope_lookup_alias(
2235 ctx
->current_scope
, "int", -1, true);
2236 if (!integer_decl
) {
2237 BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2242 ret
= visit_field_class_declarator(ctx
, container_cls
,
2243 &qdummy_id
, NULL
, (void *) &integer_decl
,
2246 BT_ASSERT(!integer_decl
);
2252 BT_ASSERT(integer_decl
);
2254 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2255 BT_LOGE("Container field class for enumeration field class is not an integer field class: "
2256 "fc-type=%d", integer_decl
->base
.base
.type
);
2261 *enum_decl
= ctf_field_class_enum_create();
2262 BT_ASSERT(*enum_decl
);
2263 (*enum_decl
)->base
.base
.base
.alignment
=
2264 integer_decl
->base
.base
.alignment
;
2265 ctf_field_class_int_copy_content((void *) *enum_decl
,
2266 (void *) integer_decl
);
2267 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2269 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2270 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2274 "Cannot visit enumeration field class entry: "
2281 ret
= ctx_decl_scope_register_enum(ctx
->current_scope
,
2284 BT_LOGE("Cannot register enumeration field class in declaration scope: "
2294 ctf_field_class_destroy((void *) *enum_decl
);
2298 ctf_field_class_destroy((void *) integer_decl
);
2299 integer_decl
= NULL
;
2304 int visit_field_class_specifier(struct ctx
*ctx
,
2305 struct ctf_node
*cls_specifier_list
,
2306 struct ctf_field_class
**decl
)
2309 GString
*str
= NULL
;
2312 str
= g_string_new("");
2313 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2315 _BT_LOGE_NODE(cls_specifier_list
,
2316 "Cannot get field class specifier list's name: ret=%d", ret
);
2320 *decl
= ctx_decl_scope_lookup_alias(ctx
->current_scope
, str
->str
, -1,
2323 _BT_LOGE_NODE(cls_specifier_list
,
2324 "Cannot find field class alias: name=\"%s\"", str
->str
);
2332 ctf_field_class_destroy(*decl
);
2337 g_string_free(str
, TRUE
);
2344 int visit_integer_decl(struct ctx
*ctx
,
2345 struct bt_list_head
*expressions
,
2346 struct ctf_field_class_int
**integer_decl
)
2351 struct ctf_node
*expression
;
2352 uint64_t alignment
= 0, size
= 0;
2353 bt_clock_class
*mapped_clock_class
= NULL
;
2354 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2355 enum bt_field_class_integer_preferred_display_base base
=
2356 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2357 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2359 *integer_decl
= NULL
;
2361 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2362 struct ctf_node
*left
, *right
;
2364 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2365 struct ctf_node
, siblings
);
2366 right
= _BT_LIST_FIRST_ENTRY(
2367 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2370 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2372 "Unexpected unary expression type: type=%d",
2373 left
->u
.unary_expression
.type
);
2378 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
2379 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2380 _BT_LOGE_DUP_ATTR(left
, "signed",
2381 "integer field class");
2386 signedness
= get_boolean(right
);
2387 if (signedness
< 0) {
2388 _BT_LOGE_NODE(right
,
2389 "Invalid boolean value for integer field class's `signed` attribute: "
2395 _SET(&set
, _INTEGER_SIGNED_SET
);
2396 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2398 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2399 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2400 "integer field class");
2405 byte_order
= get_real_byte_order(ctx
, right
);
2406 if (byte_order
== -1) {
2407 _BT_LOGE_NODE(right
,
2408 "Invalid `byte_order` attribute in integer field class: "
2414 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2415 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
2416 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2417 _BT_LOGE_DUP_ATTR(left
, "size",
2418 "integer field class");
2423 if (right
->u
.unary_expression
.type
!=
2424 UNARY_UNSIGNED_CONSTANT
) {
2425 _BT_LOGE_NODE(right
,
2426 "Invalid `size` attribute in integer field class: "
2427 "expecting unsigned constant integer: "
2429 right
->u
.unary_expression
.type
);
2434 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2436 _BT_LOGE_NODE(right
,
2437 "Invalid `size` attribute in integer field class: "
2438 "expecting positive constant integer: "
2439 "size=%" PRIu64
, size
);
2442 } else if (size
> 64) {
2443 _BT_LOGE_NODE(right
,
2444 "Invalid `size` attribute in integer field class: "
2445 "integer fields over 64 bits are not supported as of this version: "
2446 "size=%" PRIu64
, size
);
2451 _SET(&set
, _INTEGER_SIZE_SET
);
2452 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2454 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2455 _BT_LOGE_DUP_ATTR(left
, "align",
2456 "integer field class");
2461 if (right
->u
.unary_expression
.type
!=
2462 UNARY_UNSIGNED_CONSTANT
) {
2463 _BT_LOGE_NODE(right
,
2464 "Invalid `align` attribute in integer field class: "
2465 "expecting unsigned constant integer: "
2467 right
->u
.unary_expression
.type
);
2473 right
->u
.unary_expression
.u
.unsigned_constant
;
2474 if (!is_align_valid(alignment
)) {
2475 _BT_LOGE_NODE(right
,
2476 "Invalid `align` attribute in integer field class: "
2477 "expecting power of two: "
2478 "align=%" PRIu64
, alignment
);
2483 _SET(&set
, _INTEGER_ALIGN_SET
);
2484 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
2485 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2486 _BT_LOGE_DUP_ATTR(left
, "base",
2487 "integer field class");
2492 switch (right
->u
.unary_expression
.type
) {
2493 case UNARY_UNSIGNED_CONSTANT
:
2495 uint64_t constant
= right
->u
.unary_expression
.
2496 u
.unsigned_constant
;
2500 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2503 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2506 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2509 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2512 _BT_LOGE_NODE(right
,
2513 "Invalid `base` attribute in integer field class: "
2515 right
->u
.unary_expression
.u
.unsigned_constant
);
2523 char *s_right
= concatenate_unary_strings(
2524 &expression
->u
.ctf_expression
.right
);
2526 _BT_LOGE_NODE(right
,
2527 "Unexpected unary expression for integer field class's `base` attribute.");
2532 if (!strcmp(s_right
, "decimal") ||
2533 !strcmp(s_right
, "dec") ||
2534 !strcmp(s_right
, "d") ||
2535 !strcmp(s_right
, "i") ||
2536 !strcmp(s_right
, "u")) {
2537 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2538 } else if (!strcmp(s_right
, "hexadecimal") ||
2539 !strcmp(s_right
, "hex") ||
2540 !strcmp(s_right
, "x") ||
2541 !strcmp(s_right
, "X") ||
2542 !strcmp(s_right
, "p")) {
2543 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2544 } else if (!strcmp(s_right
, "octal") ||
2545 !strcmp(s_right
, "oct") ||
2546 !strcmp(s_right
, "o")) {
2547 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2548 } else if (!strcmp(s_right
, "binary") ||
2549 !strcmp(s_right
, "b")) {
2550 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2552 _BT_LOGE_NODE(right
,
2553 "Unexpected unary expression for integer field class's `base` attribute: "
2554 "base=\"%s\"", s_right
);
2564 _BT_LOGE_NODE(right
,
2565 "Invalid `base` attribute in integer field class: "
2566 "expecting unsigned constant integer or unary string.");
2571 _SET(&set
, _INTEGER_BASE_SET
);
2572 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2576 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2577 _BT_LOGE_DUP_ATTR(left
, "encoding",
2578 "integer field class");
2583 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2584 _BT_LOGE_NODE(right
,
2585 "Invalid `encoding` attribute in integer field class: "
2586 "expecting unary string.");
2591 s_right
= concatenate_unary_strings(
2592 &expression
->u
.ctf_expression
.right
);
2594 _BT_LOGE_NODE(right
,
2595 "Unexpected unary expression for integer field class's `encoding` attribute.");
2600 if (!strcmp(s_right
, "UTF8") ||
2601 !strcmp(s_right
, "utf8") ||
2602 !strcmp(s_right
, "utf-8") ||
2603 !strcmp(s_right
, "UTF-8") ||
2604 !strcmp(s_right
, "ASCII") ||
2605 !strcmp(s_right
, "ascii")) {
2606 encoding
= CTF_ENCODING_UTF8
;
2607 } else if (!strcmp(s_right
, "none")) {
2608 encoding
= CTF_ENCODING_NONE
;
2610 _BT_LOGE_NODE(right
,
2611 "Invalid `encoding` attribute in integer field class: "
2612 "unknown encoding: encoding=\"%s\"",
2620 _SET(&set
, _INTEGER_ENCODING_SET
);
2621 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
2622 const char *clock_name
;
2624 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2625 _BT_LOGE_DUP_ATTR(left
, "map",
2626 "integer field class");
2631 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2632 _BT_LOGE_NODE(right
,
2633 "Invalid `map` attribute in integer field class: "
2634 "expecting unary string.");
2640 get_map_clock_name_value(
2641 &expression
->u
.ctf_expression
.right
);
2643 char *s_right
= concatenate_unary_strings(
2644 &expression
->u
.ctf_expression
.right
);
2647 _BT_LOGE_NODE(right
,
2648 "Unexpected unary expression for integer field class's `map` attribute.");
2653 _BT_LOGE_NODE(right
,
2654 "Invalid `map` attribute in integer field class: "
2655 "cannot find clock class at this point: name=\"%s\"",
2657 _SET(&set
, _INTEGER_MAP_SET
);
2662 mapped_clock_class
=
2663 ctf_trace_class_borrow_clock_class_by_name(
2664 ctx
->ctf_tc
, clock_name
);
2665 if (!mapped_clock_class
) {
2666 _BT_LOGE_NODE(right
,
2667 "Invalid `map` attribute in integer field class: "
2668 "cannot find clock class at this point: name=\"%s\"",
2674 _SET(&set
, _INTEGER_MAP_SET
);
2677 "Unknown attribute in integer field class: "
2679 left
->u
.unary_expression
.u
.string
);
2683 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2684 BT_LOGE_STR("Missing `size` attribute in integer field class.");
2689 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2690 if (size
% CHAR_BIT
) {
2691 /* Bit-packed alignment */
2694 /* Byte-packed alignment */
2695 alignment
= CHAR_BIT
;
2699 *integer_decl
= ctf_field_class_int_create();
2700 BT_ASSERT(*integer_decl
);
2701 (*integer_decl
)->base
.base
.alignment
= alignment
;
2702 (*integer_decl
)->base
.byte_order
= byte_order
;
2703 (*integer_decl
)->base
.size
= size
;
2704 (*integer_decl
)->is_signed
= (signedness
> 0);
2705 (*integer_decl
)->disp_base
= base
;
2706 (*integer_decl
)->encoding
= encoding
;
2707 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2708 bt_clock_class_get_ref((*integer_decl
)->mapped_clock_class
);
2712 ctf_field_class_destroy((void *) *integer_decl
);
2713 *integer_decl
= NULL
;
2718 int visit_floating_point_number_decl(struct ctx
*ctx
,
2719 struct bt_list_head
*expressions
,
2720 struct ctf_field_class_float
**float_decl
)
2724 struct ctf_node
*expression
;
2725 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2726 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2730 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2731 struct ctf_node
*left
, *right
;
2733 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2734 struct ctf_node
, siblings
);
2735 right
= _BT_LIST_FIRST_ENTRY(
2736 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2739 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2741 "Unexpected unary expression type: type=%d",
2742 left
->u
.unary_expression
.type
);
2747 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
2748 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2749 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2750 "floating point number field class");
2755 byte_order
= get_real_byte_order(ctx
, right
);
2756 if (byte_order
== -1) {
2757 _BT_LOGE_NODE(right
,
2758 "Invalid `byte_order` attribute in floating point number field class: "
2764 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2765 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2767 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2768 _BT_LOGE_DUP_ATTR(left
, "exp_dig",
2769 "floating point number field class");
2774 if (right
->u
.unary_expression
.type
!=
2775 UNARY_UNSIGNED_CONSTANT
) {
2776 _BT_LOGE_NODE(right
,
2777 "Invalid `exp_dig` attribute in floating point number field class: "
2778 "expecting unsigned constant integer: "
2780 right
->u
.unary_expression
.type
);
2785 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2786 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2787 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2789 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2790 _BT_LOGE_DUP_ATTR(left
, "mant_dig",
2791 "floating point number field class");
2796 if (right
->u
.unary_expression
.type
!=
2797 UNARY_UNSIGNED_CONSTANT
) {
2798 _BT_LOGE_NODE(right
,
2799 "Invalid `mant_dig` attribute in floating point number field class: "
2800 "expecting unsigned constant integer: "
2802 right
->u
.unary_expression
.type
);
2807 mant_dig
= right
->u
.unary_expression
.u
.
2809 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2810 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2812 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2813 _BT_LOGE_DUP_ATTR(left
, "align",
2814 "floating point number field class");
2819 if (right
->u
.unary_expression
.type
!=
2820 UNARY_UNSIGNED_CONSTANT
) {
2821 _BT_LOGE_NODE(right
,
2822 "Invalid `align` attribute in floating point number field class: "
2823 "expecting unsigned constant integer: "
2825 right
->u
.unary_expression
.type
);
2830 alignment
= right
->u
.unary_expression
.u
.
2833 if (!is_align_valid(alignment
)) {
2834 _BT_LOGE_NODE(right
,
2835 "Invalid `align` attribute in floating point number field class: "
2836 "expecting power of two: "
2837 "align=%" PRIu64
, alignment
);
2842 _SET(&set
, _FLOAT_ALIGN_SET
);
2845 "Unknown attribute in floating point number field class: "
2847 left
->u
.unary_expression
.u
.string
);
2851 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2852 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2857 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2858 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2863 if (mant_dig
!= 24 && mant_dig
!= 53) {
2864 BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2869 if (mant_dig
== 24 && exp_dig
!= 8) {
2870 BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2875 if (mant_dig
== 53 && exp_dig
!= 11) {
2876 BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2881 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2882 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2883 /* Bit-packed alignment */
2886 /* Byte-packed alignment */
2887 alignment
= CHAR_BIT
;
2891 *float_decl
= ctf_field_class_float_create();
2892 BT_ASSERT(*float_decl
);
2893 (*float_decl
)->base
.base
.alignment
= alignment
;
2894 (*float_decl
)->base
.byte_order
= byte_order
;
2895 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2899 ctf_field_class_destroy((void *) *float_decl
);
2905 int visit_string_decl(struct ctx
*ctx
,
2906 struct bt_list_head
*expressions
,
2907 struct ctf_field_class_string
**string_decl
)
2911 struct ctf_node
*expression
;
2912 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2914 *string_decl
= NULL
;
2916 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2917 struct ctf_node
*left
, *right
;
2919 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2920 struct ctf_node
, siblings
);
2921 right
= _BT_LIST_FIRST_ENTRY(
2922 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2925 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2927 "Unexpected unary expression type: type=%d",
2928 left
->u
.unary_expression
.type
);
2933 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
2936 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2937 _BT_LOGE_DUP_ATTR(left
, "encoding",
2938 "string field class");
2943 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2944 _BT_LOGE_NODE(right
,
2945 "Invalid `encoding` attribute in string field class: "
2946 "expecting unary string.");
2951 s_right
= concatenate_unary_strings(
2952 &expression
->u
.ctf_expression
.right
);
2954 _BT_LOGE_NODE(right
,
2955 "Unexpected unary expression for string field class's `encoding` attribute.");
2960 if (!strcmp(s_right
, "UTF8") ||
2961 !strcmp(s_right
, "utf8") ||
2962 !strcmp(s_right
, "utf-8") ||
2963 !strcmp(s_right
, "UTF-8") ||
2964 !strcmp(s_right
, "ASCII") ||
2965 !strcmp(s_right
, "ascii")) {
2966 encoding
= CTF_ENCODING_UTF8
;
2967 } else if (!strcmp(s_right
, "none")) {
2968 encoding
= CTF_ENCODING_NONE
;
2970 _BT_LOGE_NODE(right
,
2971 "Invalid `encoding` attribute in string field class: "
2972 "unknown encoding: encoding=\"%s\"",
2980 _SET(&set
, _STRING_ENCODING_SET
);
2983 "Unknown attribute in string field class: "
2985 left
->u
.unary_expression
.u
.string
);
2989 *string_decl
= ctf_field_class_string_create();
2990 BT_ASSERT(*string_decl
);
2991 (*string_decl
)->encoding
= encoding
;
2995 ctf_field_class_destroy((void *) *string_decl
);
2996 *string_decl
= NULL
;
3001 int visit_field_class_specifier_list(struct ctx
*ctx
,
3002 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
3005 struct ctf_node
*first
, *node
;
3009 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
3010 _BT_LOGE_NODE(ts_list
,
3011 "Unexpected node type: node-type=%d", ts_list
->type
);
3016 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
3017 struct ctf_node
, siblings
);
3018 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
3019 _BT_LOGE_NODE(first
,
3020 "Unexpected node type: node-type=%d", first
->type
);
3025 node
= first
->u
.field_class_specifier
.node
;
3027 switch (first
->u
.field_class_specifier
.type
) {
3028 case TYPESPEC_INTEGER
:
3029 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
3036 case TYPESPEC_FLOATING_POINT
:
3037 ret
= visit_floating_point_number_decl(ctx
,
3038 &node
->u
.floating_point
.expressions
, (void *) decl
);
3044 case TYPESPEC_STRING
:
3045 ret
= visit_string_decl(ctx
,
3046 &node
->u
.string
.expressions
, (void *) decl
);
3052 case TYPESPEC_STRUCT
:
3053 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
3054 &node
->u
._struct
.declaration_list
,
3055 node
->u
._struct
.has_body
,
3056 &node
->u
._struct
.min_align
, (void *) decl
);
3062 case TYPESPEC_VARIANT
:
3063 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
3064 node
->u
.variant
.choice
,
3065 &node
->u
.variant
.declaration_list
,
3066 node
->u
.variant
.has_body
, (void *) decl
);
3073 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
3074 node
->u
._enum
.container_field_class
,
3075 &node
->u
._enum
.enumerator_list
,
3076 node
->u
._enum
.has_body
, (void *) decl
);
3084 case TYPESPEC_SHORT
:
3087 case TYPESPEC_FLOAT
:
3088 case TYPESPEC_DOUBLE
:
3089 case TYPESPEC_SIGNED
:
3090 case TYPESPEC_UNSIGNED
:
3092 case TYPESPEC_COMPLEX
:
3093 case TYPESPEC_IMAGINARY
:
3094 case TYPESPEC_CONST
:
3095 case TYPESPEC_ID_TYPE
:
3096 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
3098 _BT_LOGE_NODE(first
,
3099 "Cannot visit field class specifier: ret=%d",
3106 _BT_LOGE_NODE(first
,
3107 "Unexpected field class specifier type: node-type=%d",
3108 first
->u
.field_class_specifier
.type
);
3117 ctf_field_class_destroy((void *) *decl
);
3123 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3124 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
3130 switch (node
->type
) {
3132 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3133 &node
->u
.field_class_def
.field_class_declarators
);
3136 "Cannot add field class found in event class.");
3140 case NODE_TYPEALIAS
:
3141 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3142 node
->u
.field_class_alias
.alias
);
3145 "Cannot add field class alias found in event class.");
3149 case NODE_CTF_EXPRESSION
:
3151 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3153 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3158 if (!strcmp(left
, "name")) {
3159 /* This is already known at this stage */
3160 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3161 _BT_LOGE_DUP_ATTR(node
, "name", "event class");
3166 _SET(set
, _EVENT_NAME_SET
);
3167 } else if (!strcmp(left
, "id")) {
3170 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3171 _BT_LOGE_DUP_ATTR(node
, "id", "event class");
3176 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3178 /* Only read "id" if get_unary_unsigned() succeeded. */
3179 if (ret
|| (!ret
&& id
< 0)) {
3181 "Unexpected unary expression for event class's `id` attribute.");
3186 event_class
->id
= id
;
3187 _SET(set
, _EVENT_ID_SET
);
3188 } else if (!strcmp(left
, "stream_id")) {
3189 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3190 _BT_LOGE_DUP_ATTR(node
, "stream_id",
3196 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3200 * Only read "stream_id" if get_unary_unsigned()
3203 if (ret
|| (!ret
&& *stream_id
< 0)) {
3205 "Unexpected unary expression for event class's `stream_id` attribute.");
3210 _SET(set
, _EVENT_STREAM_ID_SET
);
3211 } else if (!strcmp(left
, "context")) {
3212 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3214 "Duplicate `context` entry in event class.");
3219 ret
= visit_field_class_specifier_list(ctx
,
3220 _BT_LIST_FIRST_ENTRY(
3221 &node
->u
.ctf_expression
.right
,
3222 struct ctf_node
, siblings
),
3223 &event_class
->spec_context_fc
);
3226 "Cannot create event class's context field class.");
3230 BT_ASSERT(event_class
->spec_context_fc
);
3231 _SET(set
, _EVENT_CONTEXT_SET
);
3232 } else if (!strcmp(left
, "fields")) {
3233 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3235 "Duplicate `fields` entry in event class.");
3240 ret
= visit_field_class_specifier_list(ctx
,
3241 _BT_LIST_FIRST_ENTRY(
3242 &node
->u
.ctf_expression
.right
,
3243 struct ctf_node
, siblings
),
3244 &event_class
->payload_fc
);
3247 "Cannot create event class's payload field class.");
3251 BT_ASSERT(event_class
->payload_fc
);
3252 _SET(set
, _EVENT_FIELDS_SET
);
3253 } else if (!strcmp(left
, "loglevel")) {
3254 uint64_t loglevel_value
;
3255 enum bt_event_class_log_level log_level
= -1;
3257 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3258 _BT_LOGE_DUP_ATTR(node
, "loglevel",
3264 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3268 "Unexpected unary expression for event class's `loglevel` attribute.");
3273 switch (loglevel_value
) {
3275 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3278 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3281 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3284 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3287 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3290 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3293 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3296 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3299 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3302 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3305 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3308 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3311 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3314 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3317 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3320 _BT_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3321 "log-level=%" PRIu64
, loglevel_value
);
3324 if (log_level
!= -1) {
3325 event_class
->log_level
= log_level
;
3328 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3329 } else if (!strcmp(left
, "model.emf.uri")) {
3332 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3333 _BT_LOGE_DUP_ATTR(node
, "model.emf.uri",
3339 right
= concatenate_unary_strings(
3340 &node
->u
.ctf_expression
.right
);
3343 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3348 if (strlen(right
) == 0) {
3350 "Not setting event class's EMF URI because it's empty.");
3352 g_string_assign(event_class
->emf_uri
,
3357 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3360 "Unknown attribute in event class: "
3361 "attr-name=\"%s\"", left
);
3385 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3389 struct ctf_node
*iter
;
3390 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3392 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3393 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3397 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3400 "Cannot concatenate unary strings.");
3404 if (!strcmp(left
, "name")) {
3405 name
= concatenate_unary_strings(
3406 &iter
->u
.ctf_expression
.right
);
3409 "Unexpected unary expression for event class's `name` attribute.");
3430 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3434 struct ctf_node
*iter
;
3435 uint64_t stream_id
= 0;
3436 char *event_name
= NULL
;
3437 struct ctf_event_class
*event_class
= NULL
;
3438 struct ctf_stream_class
*stream_class
= NULL
;
3439 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3440 bool pop_scope
= false;
3442 if (node
->visited
) {
3446 node
->visited
= TRUE
;
3447 event_name
= get_event_decl_name(ctx
, node
);
3450 "Missing `name` attribute in event class.");
3455 event_class
= ctf_event_class_create();
3456 BT_ASSERT(event_class
);
3457 g_string_assign(event_class
->name
, event_name
);
3458 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3461 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3462 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3465 _BT_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3471 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3473 * Allow missing stream_id if there is only a single
3476 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3478 /* Create implicit stream class if there's none */
3480 stream_class
= ctf_stream_class_create();
3481 BT_ASSERT(stream_class
);
3482 stream_class
->id
= stream_id
;
3483 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3485 stream_class
= stream_class
;
3488 /* Single stream class: get its ID */
3489 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3490 stream_id
= stream_class
->id
;
3494 "Missing `stream_id` attribute in event class.");
3500 /* We have the stream ID now; get the stream class if found */
3501 if (!stream_class
) {
3502 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3503 ctx
->ctf_tc
, stream_id
);
3504 if (!stream_class
) {
3506 "Cannot find stream class at this point: "
3507 "id=%" PRId64
, stream_id
);
3513 BT_ASSERT(stream_class
);
3515 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3516 /* Allow only one event without ID per stream */
3517 if (stream_class
->event_classes
->len
!= 0) {
3519 "Missing `id` attribute in event class.");
3525 event_class
->id
= 0;
3528 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3531 "Duplicate event class (same ID) in the same stream class: "
3532 "id=%" PRId64
, event_class
->id
);
3537 ctf_stream_class_append_event_class(stream_class
, event_class
);
3542 ctf_event_class_destroy(event_class
);
3562 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3563 struct ctf_field_class
*fc
)
3565 bt_clock_class
*clock_class_to_map_to
= NULL
;
3566 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3568 uint64_t clock_class_count
;
3574 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3575 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3579 if (int_fc
->mapped_clock_class
) {
3580 /* Already mapped */
3584 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3586 switch (clock_class_count
) {
3589 * No clock class exists in the trace at this point. Create an
3590 * implicit one at 1 GHz, named `default`, and use this clock
3593 clock_class_to_map_to
= bt_clock_class_create();
3594 BT_ASSERT(clock_class_to_map_to
);
3595 bt_clock_class_set_frequency(clock_class_to_map_to
,
3596 UINT64_C(1000000000));
3597 ret
= bt_clock_class_set_name(clock_class_to_map_to
,
3599 BT_ASSERT(ret
== 0);
3600 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3601 clock_class_to_map_to
);
3602 bt_clock_class_get_ref(clock_class_to_map_to
);
3606 * Only one clock class exists in the trace at this point: use
3609 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3610 bt_clock_class_get_ref(clock_class_to_map_to
);
3614 * Timestamp field not mapped to a clock class and there's more
3615 * than one clock class in the trace: this is an error.
3617 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3618 "but there's more than one clock class in the trace at this point.");
3623 BT_ASSERT(clock_class_to_map_to
);
3624 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3625 bt_clock_class_get_ref(int_fc
->mapped_clock_class
);
3628 bt_clock_class_put_ref(clock_class_to_map_to
);
3633 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3634 struct ctf_field_class
*root_fc
, const char *field_name
)
3638 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3639 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3645 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3646 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3650 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3651 count
= struct_fc
->members
->len
;
3653 count
= var_fc
->options
->len
;
3656 for (i
= 0; i
< count
; i
++) {
3657 struct ctf_named_field_class
*named_fc
= NULL
;
3659 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3660 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3662 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3663 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3667 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3668 ret
= auto_map_field_to_trace_clock_class(ctx
,
3671 BT_LOGE("Cannot automatically map field to trace's clock class: "
3672 "field-name=\"%s\"", field_name
);
3677 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3680 BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3681 "field-name=\"%s\", root-field-name=\"%s\"",
3682 field_name
, named_fc
->name
->str
);
3692 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3693 struct ctf_stream_class
*stream_class
, int *set
)
3698 switch (node
->type
) {
3700 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3701 &node
->u
.field_class_def
.field_class_declarators
);
3704 "Cannot add field class found in stream class.");
3708 case NODE_TYPEALIAS
:
3709 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3710 node
->u
.field_class_alias
.alias
);
3713 "Cannot add field class alias found in stream class.");
3717 case NODE_CTF_EXPRESSION
:
3719 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3721 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3726 if (!strcmp(left
, "id")) {
3729 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3730 _BT_LOGE_DUP_ATTR(node
, "id",
3731 "stream declaration");
3736 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3739 /* Only read "id" if get_unary_unsigned() succeeded. */
3740 if (ret
|| (!ret
&& id
< 0)) {
3742 "Unexpected unary expression for stream class's `id` attribute.");
3747 if (ctf_trace_class_borrow_stream_class_by_id(
3750 "Duplicate stream class (same ID): id=%" PRId64
,
3756 stream_class
->id
= id
;
3757 _SET(set
, _STREAM_ID_SET
);
3758 } else if (!strcmp(left
, "event.header")) {
3759 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3761 "Duplicate `event.header` entry in stream class.");
3766 ret
= visit_field_class_specifier_list(ctx
,
3767 _BT_LIST_FIRST_ENTRY(
3768 &node
->u
.ctf_expression
.right
,
3769 struct ctf_node
, siblings
),
3770 &stream_class
->event_header_fc
);
3773 "Cannot create stream class's event header field class.");
3777 BT_ASSERT(stream_class
->event_header_fc
);
3778 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3779 stream_class
->event_header_fc
, "timestamp");
3782 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3786 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3787 } else if (!strcmp(left
, "event.context")) {
3788 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3790 "Duplicate `event.context` entry in stream class.");
3795 ret
= visit_field_class_specifier_list(ctx
,
3796 _BT_LIST_FIRST_ENTRY(
3797 &node
->u
.ctf_expression
.right
,
3798 struct ctf_node
, siblings
),
3799 &stream_class
->event_common_context_fc
);
3802 "Cannot create stream class's event context field class.");
3806 BT_ASSERT(stream_class
->event_common_context_fc
);
3807 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3808 } else if (!strcmp(left
, "packet.context")) {
3809 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3811 "Duplicate `packet.context` entry in stream class.");
3816 ret
= visit_field_class_specifier_list(ctx
,
3817 _BT_LIST_FIRST_ENTRY(
3818 &node
->u
.ctf_expression
.right
,
3819 struct ctf_node
, siblings
),
3820 &stream_class
->packet_context_fc
);
3823 "Cannot create stream class's packet context field class.");
3827 BT_ASSERT(stream_class
->packet_context_fc
);
3828 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3829 stream_class
->packet_context_fc
,
3833 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3837 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3838 stream_class
->packet_context_fc
,
3842 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3846 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3849 "Unknown attribute in stream class: "
3850 "attr-name=\"%s\"", left
);
3871 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3875 struct ctf_node
*iter
;
3876 struct ctf_stream_class
*stream_class
= NULL
;
3877 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3879 if (node
->visited
) {
3883 node
->visited
= TRUE
;
3884 stream_class
= ctf_stream_class_create();
3885 BT_ASSERT(stream_class
);
3886 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3888 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3889 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3892 "Cannot visit stream class's entry: "
3901 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3902 /* Check that packet header has `stream_id` field */
3903 struct ctf_named_field_class
*named_fc
= NULL
;
3905 if (!ctx
->ctf_tc
->packet_header_fc
) {
3907 "Stream class has a `id` attribute, "
3908 "but trace has no packet header field class.");
3912 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3913 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3916 "Stream class has a `id` attribute, "
3917 "but trace's packet header field class has no `stream_id` field.");
3921 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3922 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3924 "Stream class has a `id` attribute, "
3925 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3929 /* Allow only _one_ ID-less stream */
3930 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3932 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3937 /* Automatic ID: 0 */
3938 stream_class
->id
= 0;
3942 * Make sure that this stream class's ID is currently unique in
3945 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3946 stream_class
->id
)) {
3948 "Duplicate stream class (same ID): id=%" PRId64
,
3954 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3955 stream_class
= NULL
;
3959 ctf_stream_class_destroy(stream_class
);
3960 stream_class
= NULL
;
3967 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3973 switch (node
->type
) {
3975 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3976 &node
->u
.field_class_def
.field_class_declarators
);
3979 "Cannot add field class found in trace (`trace` block).");
3983 case NODE_TYPEALIAS
:
3984 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3985 node
->u
.field_class_alias
.alias
);
3988 "Cannot add field class alias found in trace (`trace` block).");
3992 case NODE_CTF_EXPRESSION
:
3994 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3996 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
4001 if (!strcmp(left
, "major")) {
4002 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
4003 _BT_LOGE_DUP_ATTR(node
, "major", "trace");
4008 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4012 "Unexpected unary expression for trace's `major` attribute.");
4019 "Invalid trace's `minor` attribute: expecting 1.");
4023 ctx
->ctf_tc
->major
= val
;
4024 _SET(set
, _TRACE_MAJOR_SET
);
4025 } else if (!strcmp(left
, "minor")) {
4026 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
4027 _BT_LOGE_DUP_ATTR(node
, "minor", "trace");
4032 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4036 "Unexpected unary expression for trace's `minor` attribute.");
4043 "Invalid trace's `minor` attribute: expecting 8.");
4047 ctx
->ctf_tc
->minor
= val
;
4048 _SET(set
, _TRACE_MINOR_SET
);
4049 } else if (!strcmp(left
, "uuid")) {
4050 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
4051 _BT_LOGE_DUP_ATTR(node
, "uuid", "trace");
4056 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
,
4060 "Invalid trace's `uuid` attribute.");
4064 ctx
->ctf_tc
->is_uuid_set
= true;
4065 _SET(set
, _TRACE_UUID_SET
);
4066 } else if (!strcmp(left
, "byte_order")) {
4067 /* Default byte order is already known at this stage */
4068 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
4069 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4075 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= -1);
4076 _SET(set
, _TRACE_BYTE_ORDER_SET
);
4077 } else if (!strcmp(left
, "packet.header")) {
4078 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
4080 "Duplicate `packet.header` entry in trace.");
4085 ret
= visit_field_class_specifier_list(ctx
,
4086 _BT_LIST_FIRST_ENTRY(
4087 &node
->u
.ctf_expression
.right
,
4088 struct ctf_node
, siblings
),
4089 &ctx
->ctf_tc
->packet_header_fc
);
4092 "Cannot create trace's packet header field class.");
4096 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
4097 _SET(set
, _TRACE_PACKET_HEADER_SET
);
4100 "Unknown attribute in stream class: "
4101 "attr-name=\"%s\"", left
);
4109 _BT_LOGE_NODE(node
, "Unknown expression in trace.");
4122 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
4126 struct ctf_node
*iter
;
4127 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
4129 if (node
->visited
) {
4133 node
->visited
= TRUE
;
4135 if (ctx
->is_trace_visited
) {
4136 _BT_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
4141 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4143 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
4144 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
4146 _BT_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
4155 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
4157 "Missing `major` attribute in trace (`trace` block).");
4162 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
4164 "Missing `minor` attribute in trace (`trace` block).");
4169 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4171 "Missing `byte_order` attribute in trace (`trace` block).");
4176 ctx
->is_trace_visited
= true;
4186 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4190 struct ctf_node
*entry_node
;
4191 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4193 if (node
->visited
) {
4197 node
->visited
= TRUE
;
4199 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4200 struct bt_list_head
*right_head
=
4201 &entry_node
->u
.ctf_expression
.right
;
4203 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4204 _BT_LOGE_NODE(entry_node
,
4205 "Wrong expression in environment entry: "
4206 "node-type=%d", entry_node
->type
);
4211 left
= concatenate_unary_strings(
4212 &entry_node
->u
.ctf_expression
.left
);
4214 _BT_LOGE_NODE(entry_node
,
4215 "Cannot get environment entry's name.");
4220 if (is_unary_string(right_head
)) {
4221 char *right
= concatenate_unary_strings(right_head
);
4224 _BT_LOGE_NODE(entry_node
,
4225 "Unexpected unary expression for environment entry's value: "
4226 "name=\"%s\"", left
);
4231 if (strcmp(left
, "tracer_name") == 0) {
4232 if (strncmp(right
, "lttng", 5) == 0) {
4233 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4234 "tracer-name=\"%s\"",
4236 ctx
->is_lttng
= true;
4240 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4241 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4244 } else if (is_unary_unsigned(right_head
) ||
4245 is_unary_signed(right_head
)) {
4248 if (is_unary_unsigned(right_head
)) {
4249 ret
= get_unary_unsigned(right_head
,
4252 ret
= get_unary_signed(right_head
, &v
);
4255 _BT_LOGE_NODE(entry_node
,
4256 "Unexpected unary expression for environment entry's value: "
4257 "name=\"%s\"", left
);
4262 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4263 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4266 _BT_LOGW_NODE(entry_node
,
4267 "Environment entry has unknown type: "
4268 "name=\"%s\"", left
);
4284 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4289 struct ctf_node
*node
;
4290 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4292 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4293 if (node
->type
== NODE_CTF_EXPRESSION
) {
4294 struct ctf_node
*right_node
;
4296 left
= concatenate_unary_strings(
4297 &node
->u
.ctf_expression
.left
);
4300 "Cannot concatenate unary strings.");
4305 if (!strcmp(left
, "byte_order")) {
4306 enum ctf_byte_order bo
;
4308 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4309 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4315 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4316 right_node
= _BT_LIST_FIRST_ENTRY(
4317 &node
->u
.ctf_expression
.right
,
4318 struct ctf_node
, siblings
);
4319 bo
= byte_order_from_unary_expr(right_node
);
4322 "Invalid `byte_order` attribute in trace (`trace` block): "
4323 "expecting `le`, `be`, or `network`.");
4326 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4328 "Invalid `byte_order` attribute in trace (`trace` block): "
4329 "cannot be set to `native` here.");
4334 ctx
->ctf_tc
->default_byte_order
= bo
;
4342 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4343 _BT_LOGE_NODE(trace_node
,
4344 "Missing `byte_order` attribute in trace (`trace` block).");
4357 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4358 bt_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4359 uint64_t *offset_cycles
)
4364 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4365 _BT_LOGE_NODE(entry_node
,
4366 "Unexpected node type: node-type=%d",
4372 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4374 _BT_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4379 if (!strcmp(left
, "name")) {
4382 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4383 _BT_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4388 right
= concatenate_unary_strings(
4389 &entry_node
->u
.ctf_expression
.right
);
4391 _BT_LOGE_NODE(entry_node
,
4392 "Unexpected unary expression for clock class's `name` attribute.");
4397 ret
= bt_clock_class_set_name(clock
, right
);
4399 _BT_LOGE_NODE(entry_node
,
4400 "cannot set clock class's name");
4406 _SET(set
, _CLOCK_NAME_SET
);
4407 } else if (!strcmp(left
, "uuid")) {
4408 uint8_t uuid
[BABELTRACE_UUID_LEN
];
4410 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4411 _BT_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4416 ret
= get_unary_uuid(&entry_node
->u
.ctf_expression
.right
, uuid
);
4418 _BT_LOGE_NODE(entry_node
,
4419 "Invalid clock class's `uuid` attribute.");
4423 bt_clock_class_set_uuid(clock
, uuid
);
4424 _SET(set
, _CLOCK_UUID_SET
);
4425 } else if (!strcmp(left
, "description")) {
4428 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4429 _BT_LOGE_DUP_ATTR(entry_node
, "description",
4435 right
= concatenate_unary_strings(
4436 &entry_node
->u
.ctf_expression
.right
);
4438 _BT_LOGE_NODE(entry_node
,
4439 "Unexpected unary expression for clock class's `description` attribute.");
4444 ret
= bt_clock_class_set_description(clock
, right
);
4446 _BT_LOGE_NODE(entry_node
,
4447 "Cannot set clock class's description.");
4453 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4454 } else if (!strcmp(left
, "freq")) {
4455 uint64_t freq
= UINT64_C(-1);
4457 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4458 _BT_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4463 ret
= get_unary_unsigned(
4464 &entry_node
->u
.ctf_expression
.right
, &freq
);
4466 _BT_LOGE_NODE(entry_node
,
4467 "Unexpected unary expression for clock class's `freq` attribute.");
4472 if (freq
== UINT64_C(-1) || freq
== 0) {
4473 _BT_LOGE_NODE(entry_node
,
4474 "Invalid clock class frequency: freq=%" PRIu64
,
4480 bt_clock_class_set_frequency(clock
, freq
);
4481 _SET(set
, _CLOCK_FREQ_SET
);
4482 } else if (!strcmp(left
, "precision")) {
4485 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4486 _BT_LOGE_DUP_ATTR(entry_node
, "precision",
4492 ret
= get_unary_unsigned(
4493 &entry_node
->u
.ctf_expression
.right
, &precision
);
4495 _BT_LOGE_NODE(entry_node
,
4496 "Unexpected unary expression for clock class's `precision` attribute.");
4501 bt_clock_class_set_precision(clock
, precision
);
4502 _SET(set
, _CLOCK_PRECISION_SET
);
4503 } else if (!strcmp(left
, "offset_s")) {
4504 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4505 _BT_LOGE_DUP_ATTR(entry_node
, "offset_s",
4511 ret
= get_unary_signed(
4512 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4514 _BT_LOGE_NODE(entry_node
,
4515 "Unexpected unary expression for clock class's `offset_s` attribute.");
4520 _SET(set
, _CLOCK_OFFSET_S_SET
);
4521 } else if (!strcmp(left
, "offset")) {
4522 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4523 _BT_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4528 ret
= get_unary_unsigned(
4529 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4531 _BT_LOGE_NODE(entry_node
,
4532 "Unexpected unary expression for clock class's `offset` attribute.");
4537 _SET(set
, _CLOCK_OFFSET_SET
);
4538 } else if (!strcmp(left
, "absolute")) {
4539 struct ctf_node
*right
;
4541 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4542 _BT_LOGE_DUP_ATTR(entry_node
, "absolute",
4548 right
= _BT_LIST_FIRST_ENTRY(
4549 &entry_node
->u
.ctf_expression
.right
,
4550 struct ctf_node
, siblings
);
4551 ret
= get_boolean(right
);
4553 _BT_LOGE_NODE(entry_node
,
4554 "Unexpected unary expression for clock class's `absolute` attribute.");
4559 bt_clock_class_set_is_absolute(clock
, ret
);
4560 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4562 _BT_LOGW_NODE(entry_node
,
4563 "Unknown attribute in clock class: attr-name=\"%s\"",
4577 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4582 if (frequency
== UINT64_C(1000000000)) {
4585 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4592 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4593 uint64_t *offset_cycles
, uint64_t freq
)
4595 if (*offset_cycles
>= freq
) {
4596 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4598 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4599 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4604 void apply_clock_class_offset(struct ctx
*ctx
,
4605 bt_clock_class
*clock
)
4608 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4609 uint64_t offset_ns_to_apply
;
4610 int64_t cur_offset_s
;
4611 uint64_t cur_offset_cycles
;
4613 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4614 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4618 /* Transfer nanoseconds to seconds as much as possible */
4619 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4620 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4621 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4622 const int64_t extra_s
= -abs_extra_s
;
4623 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4624 (extra_s
* INT64_C(1000000000));
4626 BT_ASSERT(offset_ns
> 0);
4627 offset_ns_to_apply
= (uint64_t) offset_ns
;
4628 offset_s_to_apply
+= extra_s
;
4630 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4631 INT64_C(1000000000);
4632 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4633 (extra_s
* INT64_C(1000000000));
4635 BT_ASSERT(offset_ns
>= 0);
4636 offset_ns_to_apply
= (uint64_t) offset_ns
;
4637 offset_s_to_apply
+= extra_s
;
4640 freq
= bt_clock_class_get_frequency(clock
);
4641 bt_clock_class_get_offset(clock
,
4642 &cur_offset_s
, &cur_offset_cycles
);
4645 cur_offset_s
+= offset_s_to_apply
;
4646 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4649 * Recalibrate offsets because the part in cycles can be greater
4650 * than the frequency at this point.
4652 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4654 /* Set final offsets */
4655 bt_clock_class_set_offset(clock
, cur_offset_s
, cur_offset_cycles
);
4662 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4666 bt_clock_class
*clock
;
4667 struct ctf_node
*entry_node
;
4668 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4669 const char *clock_class_name
;
4670 int64_t offset_seconds
= 0;
4671 uint64_t offset_cycles
= 0;
4674 if (clock_node
->visited
) {
4678 clock_node
->visited
= TRUE
;
4680 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4681 clock
= bt_clock_class_create();
4683 _BT_LOGE_NODE(clock_node
,
4684 "Cannot create default clock class.");
4689 /* CTF: not absolute by default */
4690 bt_clock_class_set_is_absolute(clock
, BT_FALSE
);
4692 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4693 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4694 &offset_seconds
, &offset_cycles
);
4696 _BT_LOGE_NODE(entry_node
,
4697 "Cannot visit clock class's entry: ret=%d",
4703 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4704 _BT_LOGE_NODE(clock_node
,
4705 "Missing `name` attribute in clock class.");
4710 clock_class_name
= bt_clock_class_get_name(clock
);
4711 BT_ASSERT(clock_class_name
);
4712 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4714 * Old versions of LTTng forgot to set its clock class
4715 * as absolute, even if it is. This is important because
4716 * it's a condition to be able to sort notifications
4717 * from different sources.
4719 bt_clock_class_set_is_absolute(clock
, BT_TRUE
);
4723 * Adjust offsets so that the part in cycles is less than the
4724 * frequency (move to the part in seconds).
4726 freq
= bt_clock_class_get_frequency(clock
);
4727 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4728 BT_ASSERT(offset_cycles
< bt_clock_class_get_frequency(clock
));
4729 bt_clock_class_set_offset(clock
, offset_seconds
, offset_cycles
);
4730 apply_clock_class_offset(ctx
, clock
);
4731 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4732 bt_clock_class_get_ref(clock
);
4735 BT_CLOCK_CLASS_PUT_REF_AND_RESET(clock
);
4740 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4744 if (root_decl_node
->visited
) {
4748 root_decl_node
->visited
= TRUE
;
4750 switch (root_decl_node
->type
) {
4752 ret
= visit_field_class_def(ctx
,
4753 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4754 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4756 _BT_LOGE_NODE(root_decl_node
,
4757 "Cannot add field class found in root scope.");
4761 case NODE_TYPEALIAS
:
4762 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4763 root_decl_node
->u
.field_class_alias
.alias
);
4765 _BT_LOGE_NODE(root_decl_node
,
4766 "Cannot add field class alias found in root scope.");
4770 case NODE_TYPE_SPECIFIER_LIST
:
4772 struct ctf_field_class
*decl
= NULL
;
4775 * Just add the field class specifier to the root
4776 * declaration scope. Put local reference.
4778 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4780 _BT_LOGE_NODE(root_decl_node
,
4781 "Cannot visit root scope's field class: "
4787 ctf_field_class_destroy(decl
);
4792 _BT_LOGE_NODE(root_decl_node
,
4793 "Unexpected node type: node-type=%d",
4794 root_decl_node
->type
);
4804 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4805 const struct ctf_metadata_decoder_config
*decoder_config
)
4807 struct ctx
*ctx
= NULL
;
4809 /* Create visitor's context */
4810 ctx
= ctx_create(decoder_config
);
4812 BT_LOGE_STR("Cannot create visitor's context.");
4823 return (void *) ctx
;
4827 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4829 ctx_destroy((void *) visitor
);
4833 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4834 struct ctf_visitor_generate_ir
*visitor
)
4836 struct ctx
*ctx
= (void *) visitor
;
4839 BT_ASSERT(ctx
->trace_class
);
4840 bt_trace_class_get_ref(ctx
->trace_class
);
4841 return ctx
->trace_class
;
4845 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4846 struct ctf_visitor_generate_ir
*visitor
)
4848 struct ctx
*ctx
= (void *) visitor
;
4851 BT_ASSERT(ctx
->ctf_tc
);
4856 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4857 struct ctf_node
*node
)
4860 struct ctx
*ctx
= (void *) visitor
;
4862 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4864 switch (node
->type
) {
4867 struct ctf_node
*iter
;
4868 bool got_trace_decl
= false;
4871 * The first thing we need is the native byte order of
4872 * the trace block, because early class aliases can have
4873 * a `byte_order` attribute set to `native`. If we don't
4874 * have the native byte order yet, and we don't have any
4875 * trace block yet, then fail with EINCOMPLETE.
4877 if (ctx
->ctf_tc
->default_byte_order
== -1) {
4878 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4879 if (got_trace_decl
) {
4881 "Duplicate trace (`trace` block).");
4886 ret
= set_trace_byte_order(ctx
, iter
);
4889 "Cannot set trace's native byte order: "
4894 got_trace_decl
= true;
4897 if (!got_trace_decl
) {
4898 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4904 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4905 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4906 BT_ASSERT(ctx
->current_scope
&&
4907 ctx
->current_scope
->parent_scope
== NULL
);
4910 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4911 ret
= visit_env(ctx
, iter
);
4914 "Cannot visit trace's environment (`env` block) entry: "
4920 BT_ASSERT(ctx
->current_scope
&&
4921 ctx
->current_scope
->parent_scope
== NULL
);
4924 * Visit clock blocks.
4926 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4927 ret
= visit_clock_decl(ctx
, iter
);
4930 "Cannot visit clock class: ret=%d",
4936 BT_ASSERT(ctx
->current_scope
&&
4937 ctx
->current_scope
->parent_scope
== NULL
);
4940 * Visit root declarations next, as they can be used by any
4943 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4945 ret
= visit_root_decl(ctx
, iter
);
4948 "Cannot visit root entry: ret=%d",
4954 BT_ASSERT(ctx
->current_scope
&&
4955 ctx
->current_scope
->parent_scope
== NULL
);
4957 /* Callsite blocks are not supported */
4958 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4960 "\"callsite\" blocks are not supported as of this version.");
4963 BT_ASSERT(ctx
->current_scope
&&
4964 ctx
->current_scope
->parent_scope
== NULL
);
4967 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4968 ret
= visit_trace_decl(ctx
, iter
);
4971 "Cannot visit trace (`trace` block): "
4977 BT_ASSERT(ctx
->current_scope
&&
4978 ctx
->current_scope
->parent_scope
== NULL
);
4981 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4982 ret
= visit_stream_decl(ctx
, iter
);
4985 "Cannot visit stream class: ret=%d",
4991 BT_ASSERT(ctx
->current_scope
&&
4992 ctx
->current_scope
->parent_scope
== NULL
);
4995 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4996 ret
= visit_event_decl(ctx
, iter
);
4999 "Cannot visit event class: ret=%d",
5005 BT_ASSERT(ctx
->current_scope
&&
5006 ctx
->current_scope
->parent_scope
== NULL
);
5011 "Unexpected node type: node-type=%d",
5017 /* Update default clock classes */
5018 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
);
5024 /* Update trace class meanings */
5025 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
5031 /* Update text arrays and sequences */
5032 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
5038 /* Resolve sequence lengths and variant tags */
5039 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
);
5045 /* Update "in IR" for field classes */
5046 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
5052 /* Update saved value indexes */
5053 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
5059 /* Validate what we have so far */
5060 ret
= ctf_trace_class_validate(ctx
->ctf_tc
);
5066 /* Copy new CTF metadata -> new IR metadata */
5067 ret
= ctf_trace_class_translate(ctx
->trace_class
, ctx
->ctf_tc
);