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(bt_self_component_source
*self_comp
,
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.");
587 ctx
->trace_class
= bt_trace_class_create(
588 bt_self_component_source_as_self_component(self_comp
));
589 if (!ctx
->trace_class
) {
590 BT_LOGE_STR("Cannot create empty trace class.");
595 ctx
->ctf_tc
= ctf_trace_class_create();
597 BT_LOGE_STR("Cannot create CTF trace class.");
601 /* Root declaration scope */
602 ctx
->current_scope
= ctx_decl_scope_create(NULL
);
603 if (!ctx
->current_scope
) {
604 BT_LOGE_STR("Cannot create declaration scope.");
608 ctx
->decoder_config
= *decoder_config
;
620 * Pushes a new declaration scope on top of a visitor context's
621 * declaration scope stack.
623 * @param ctx Visitor context
624 * @returns 0 on success, or a negative value on error
627 int ctx_push_scope(struct ctx
*ctx
)
630 struct ctx_decl_scope
*new_scope
;
633 new_scope
= ctx_decl_scope_create(ctx
->current_scope
);
635 BT_LOGE_STR("Cannot create declaration scope.");
640 ctx
->current_scope
= new_scope
;
647 void ctx_pop_scope(struct ctx
*ctx
)
649 struct ctx_decl_scope
*parent_scope
= NULL
;
653 if (!ctx
->current_scope
) {
657 parent_scope
= ctx
->current_scope
->parent_scope
;
658 ctx_decl_scope_destroy(ctx
->current_scope
);
659 ctx
->current_scope
= parent_scope
;
666 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
667 struct ctf_field_class
**decl
);
670 char *remove_underscores_from_field_ref(const char *field_ref
)
676 UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
,
677 UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
,
678 } state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
680 BT_ASSERT(field_ref
);
681 ret
= calloc(strlen(field_ref
) + 1, 1);
683 BT_LOGE("Failed to allocate a string: size=%zu",
684 strlen(field_ref
) + 1);
691 while (*in_ch
!= '\0') {
695 /* Remove whitespace */
699 if (state
== UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
) {
701 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
707 state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
710 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
725 int is_unary_string(struct bt_list_head
*head
)
728 struct ctf_node
*node
;
730 bt_list_for_each_entry(node
, head
, siblings
) {
731 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
735 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
744 char *concatenate_unary_strings(struct bt_list_head
*head
)
748 struct ctf_node
*node
;
750 str
= g_string_new(NULL
);
753 bt_list_for_each_entry(node
, head
, siblings
) {
757 node
->type
!= NODE_UNARY_EXPRESSION
||
758 node
->u
.unary_expression
.type
!= UNARY_STRING
||
761 node
->u
.unary_expression
.link
!=
769 switch (node
->u
.unary_expression
.link
) {
771 g_string_append(str
, ".");
773 case UNARY_ARROWLINK
:
774 g_string_append(str
, "->");
776 case UNARY_DOTDOTDOT
:
777 g_string_append(str
, "...");
783 src_string
= node
->u
.unary_expression
.u
.string
;
784 g_string_append(str
, src_string
);
788 /* Destroys the container, returns the underlying string */
789 return g_string_free(str
, FALSE
);
792 /* This always returns NULL */
793 return g_string_free(str
, TRUE
);
797 const char *get_map_clock_name_value(struct bt_list_head
*head
)
800 struct ctf_node
*node
;
801 const char *name
= NULL
;
803 bt_list_for_each_entry(node
, head
, siblings
) {
805 int uexpr_type
= node
->u
.unary_expression
.type
;
806 int uexpr_link
= node
->u
.unary_expression
.link
;
807 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
808 uexpr_type
!= UNARY_STRING
||
809 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
814 /* Needs to be chained with . */
815 switch (node
->u
.unary_expression
.link
) {
818 case UNARY_ARROWLINK
:
819 case UNARY_DOTDOTDOT
:
825 src_string
= node
->u
.unary_expression
.u
.string
;
829 if (strcmp("clock", src_string
)) {
837 if (strcmp("value", src_string
)) {
842 /* Extra identifier, unknown */
856 int is_unary_unsigned(struct bt_list_head
*head
)
859 struct ctf_node
*node
;
861 bt_list_for_each_entry(node
, head
, siblings
) {
862 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
866 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
875 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
879 struct ctf_node
*node
;
883 if (bt_list_empty(head
)) {
888 bt_list_for_each_entry(node
, head
, siblings
) {
889 int uexpr_type
= node
->u
.unary_expression
.type
;
890 int uexpr_link
= node
->u
.unary_expression
.link
;
891 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
892 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
893 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
895 _BT_LOGE_NODE(node
, "Invalid constant unsigned integer.");
900 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
909 int is_unary_signed(struct bt_list_head
*head
)
912 struct ctf_node
*node
;
914 bt_list_for_each_entry(node
, head
, siblings
) {
915 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
919 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
928 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
932 struct ctf_node
*node
;
934 bt_list_for_each_entry(node
, head
, siblings
) {
935 int uexpr_type
= node
->u
.unary_expression
.type
;
936 int uexpr_link
= node
->u
.unary_expression
.link
;
937 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
938 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
939 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
940 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
946 switch (uexpr_type
) {
947 case UNARY_UNSIGNED_CONSTANT
:
949 node
->u
.unary_expression
.u
.unsigned_constant
;
951 case UNARY_SIGNED_CONSTANT
:
952 *value
= node
->u
.unary_expression
.u
.signed_constant
;
967 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
971 struct ctf_node
*node
;
973 bt_list_for_each_entry(node
, head
, siblings
) {
974 int uexpr_type
= node
->u
.unary_expression
.type
;
975 int uexpr_link
= node
->u
.unary_expression
.link
;
976 const char *src_string
;
978 if (node
->type
!= NODE_UNARY_EXPRESSION
||
979 uexpr_type
!= UNARY_STRING
||
980 uexpr_link
!= UNARY_LINK_UNKNOWN
||
986 src_string
= node
->u
.unary_expression
.u
.string
;
987 ret
= bt_uuid_parse(src_string
, uuid
);
990 "Cannot parse UUID: uuid=\"%s\"", src_string
);
1000 int get_boolean(struct ctf_node
*unary_expr
)
1004 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
1005 _BT_LOGE_NODE(unary_expr
,
1006 "Expecting unary expression: node-type=%d",
1012 switch (unary_expr
->u
.unary_expression
.type
) {
1013 case UNARY_UNSIGNED_CONSTANT
:
1014 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
1016 case UNARY_SIGNED_CONSTANT
:
1017 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
1021 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
1023 if (!strcmp(str
, "true") || !strcmp(str
, "TRUE")) {
1025 } else if (!strcmp(str
, "false") || !strcmp(str
, "FALSE")) {
1028 _BT_LOGE_NODE(unary_expr
,
1029 "Unexpected boolean value: value=\"%s\"", str
);
1036 _BT_LOGE_NODE(unary_expr
,
1037 "Unexpected unary expression type: node-type=%d",
1038 unary_expr
->u
.unary_expression
.type
);
1048 enum ctf_byte_order
byte_order_from_unary_expr(struct ctf_node
*unary_expr
)
1051 enum ctf_byte_order bo
= -1;
1053 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1054 _BT_LOGE_NODE(unary_expr
,
1055 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1059 str
= unary_expr
->u
.unary_expression
.u
.string
;
1061 if (!strcmp(str
, "be") || !strcmp(str
, "network")) {
1062 bo
= CTF_BYTE_ORDER_BIG
;
1063 } else if (!strcmp(str
, "le")) {
1064 bo
= CTF_BYTE_ORDER_LITTLE
;
1065 } else if (!strcmp(str
, "native")) {
1066 bo
= CTF_BYTE_ORDER_DEFAULT
;
1068 _BT_LOGE_NODE(unary_expr
,
1069 "Unexpected \"byte_order\" attribute value: "
1070 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1080 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1081 struct ctf_node
*uexpr
)
1083 enum ctf_byte_order bo
= byte_order_from_unary_expr(uexpr
);
1085 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
1086 bo
= ctx
->ctf_tc
->default_byte_order
;
1093 int is_align_valid(uint64_t align
)
1095 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
1099 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
1104 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1105 _BT_LOGE_NODE(cls_specifier
,
1106 "Unexpected node type: node-type=%d",
1107 cls_specifier
->type
);
1112 switch (cls_specifier
->u
.field_class_specifier
.type
) {
1114 g_string_append(str
, "void");
1117 g_string_append(str
, "char");
1119 case TYPESPEC_SHORT
:
1120 g_string_append(str
, "short");
1123 g_string_append(str
, "int");
1126 g_string_append(str
, "long");
1128 case TYPESPEC_FLOAT
:
1129 g_string_append(str
, "float");
1131 case TYPESPEC_DOUBLE
:
1132 g_string_append(str
, "double");
1134 case TYPESPEC_SIGNED
:
1135 g_string_append(str
, "signed");
1137 case TYPESPEC_UNSIGNED
:
1138 g_string_append(str
, "unsigned");
1141 g_string_append(str
, "bool");
1143 case TYPESPEC_COMPLEX
:
1144 g_string_append(str
, "_Complex");
1146 case TYPESPEC_IMAGINARY
:
1147 g_string_append(str
, "_Imaginary");
1149 case TYPESPEC_CONST
:
1150 g_string_append(str
, "const");
1152 case TYPESPEC_ID_TYPE
:
1153 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1154 g_string_append(str
,
1155 cls_specifier
->u
.field_class_specifier
.id_type
);
1158 case TYPESPEC_STRUCT
:
1160 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1162 if (!node
->u
._struct
.name
) {
1163 _BT_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1168 g_string_append(str
, "struct ");
1169 g_string_append(str
, node
->u
._struct
.name
);
1172 case TYPESPEC_VARIANT
:
1174 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1176 if (!node
->u
.variant
.name
) {
1177 _BT_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1182 g_string_append(str
, "variant ");
1183 g_string_append(str
, node
->u
.variant
.name
);
1188 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1190 if (!node
->u
._enum
.enum_id
) {
1192 "Unexpected empty enumeration field class (`enum`) name.");
1197 g_string_append(str
, "enum ");
1198 g_string_append(str
, node
->u
._enum
.enum_id
);
1201 case TYPESPEC_FLOATING_POINT
:
1202 case TYPESPEC_INTEGER
:
1203 case TYPESPEC_STRING
:
1205 _BT_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1206 "Unexpected field class specifier type: %d",
1207 cls_specifier
->u
.field_class_specifier
.type
);
1217 int get_class_specifier_list_name(struct ctx
*ctx
,
1218 struct ctf_node
*cls_specifier_list
, GString
*str
)
1221 struct ctf_node
*iter
;
1222 int alias_item_nr
= 0;
1223 struct bt_list_head
*head
=
1224 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1226 bt_list_for_each_entry(iter
, head
, siblings
) {
1227 if (alias_item_nr
!= 0) {
1228 g_string_append(str
, " ");
1232 ret
= get_class_specifier_name(ctx
, iter
, str
);
1243 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1244 struct ctf_node
*cls_specifier_list
,
1245 struct ctf_node
*node_field_class_declarator
)
1251 struct ctf_node
*iter
;
1252 struct bt_list_head
*pointers
=
1253 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1255 str
= g_string_new("");
1256 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1258 g_string_free(str
, TRUE
);
1262 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1263 g_string_append(str
, " *");
1265 if (iter
->u
.pointer
.const_qualifier
) {
1266 g_string_append(str
, " const");
1270 str_c
= g_string_free(str
, FALSE
);
1271 qalias
= g_quark_from_string(str_c
);
1279 int visit_field_class_declarator(struct ctx
*ctx
,
1280 struct ctf_node
*cls_specifier_list
,
1281 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1282 struct ctf_field_class
**field_decl
,
1283 struct ctf_field_class
*nested_decl
)
1286 * During this whole function, nested_decl is always OURS,
1287 * whereas field_decl is an output which we create, but
1288 * belongs to the caller (it is moved).
1293 /* Validate field class declarator node */
1294 if (node_field_class_declarator
) {
1295 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1297 _BT_LOGE_NODE(node_field_class_declarator
,
1298 "Unexpected field class declarator type: type=%d",
1299 node_field_class_declarator
->u
.field_class_declarator
.type
);
1304 /* TODO: GCC bitfields not supported yet */
1305 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1307 _BT_LOGE_NODE(node_field_class_declarator
,
1308 "GCC bitfields are not supported as of this version.");
1314 /* Find the right nested declaration if not provided */
1316 struct bt_list_head
*pointers
=
1317 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1319 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1323 * If we have a pointer declarator, it HAS to
1324 * be present in the field class aliases (else
1327 qalias
= create_class_alias_identifier(ctx
,
1328 cls_specifier_list
, node_field_class_declarator
);
1330 ctx_decl_scope_lookup_alias(ctx
->current_scope
,
1331 g_quark_to_string(qalias
), -1, true);
1333 _BT_LOGE_NODE(node_field_class_declarator
,
1334 "Cannot find class alias: name=\"%s\"",
1335 g_quark_to_string(qalias
));
1340 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1341 /* Pointer: force integer's base to 16 */
1342 struct ctf_field_class_int
*int_fc
=
1343 (void *) nested_decl
;
1346 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1349 ret
= visit_field_class_specifier_list(ctx
,
1350 cls_specifier_list
, &nested_decl
);
1352 BT_ASSERT(!nested_decl
);
1358 BT_ASSERT(nested_decl
);
1360 if (!node_field_class_declarator
) {
1361 *field_decl
= nested_decl
;
1366 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1367 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1369 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1375 *field_name
= g_quark_from_string(id
);
1380 *field_decl
= nested_decl
;
1384 struct ctf_node
*first
;
1385 struct ctf_field_class
*decl
= NULL
;
1386 struct ctf_field_class
*outer_field_decl
= NULL
;
1387 struct bt_list_head
*length
=
1388 &node_field_class_declarator
->
1389 u
.field_class_declarator
.u
.nested
.length
;
1391 /* Create array/sequence, pass nested_decl as child */
1392 if (bt_list_empty(length
)) {
1393 _BT_LOGE_NODE(node_field_class_declarator
,
1394 "Expecting length field reference or value.");
1399 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1400 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1401 _BT_LOGE_NODE(first
,
1402 "Unexpected node type: node-type=%d",
1408 switch (first
->u
.unary_expression
.type
) {
1409 case UNARY_UNSIGNED_CONSTANT
:
1411 struct ctf_field_class_array
*array_decl
= NULL
;
1413 array_decl
= ctf_field_class_array_create();
1414 BT_ASSERT(array_decl
);
1415 array_decl
->length
=
1416 first
->u
.unary_expression
.u
.unsigned_constant
;
1417 array_decl
->base
.elem_fc
= nested_decl
;
1419 decl
= (void *) array_decl
;
1424 /* Lookup unsigned integer definition, create seq. */
1425 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1426 char *length_name
= concatenate_unary_strings(length
);
1429 _BT_LOGE_NODE(node_field_class_declarator
,
1430 "Cannot concatenate unary strings.");
1435 if (strncmp(length_name
, "env.", 4) == 0) {
1436 /* This is, in fact, an array */
1437 const char *env_entry_name
= &length_name
[4];
1438 struct ctf_trace_class_env_entry
*env_entry
=
1439 ctf_trace_class_borrow_env_entry_by_name(
1440 ctx
->ctf_tc
, env_entry_name
);
1441 struct ctf_field_class_array
*array_decl
;
1444 _BT_LOGE_NODE(node_field_class_declarator
,
1445 "Cannot find environment entry: "
1446 "name=\"%s\"", env_entry_name
);
1451 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1452 _BT_LOGE_NODE(node_field_class_declarator
,
1453 "Wrong environment entry type "
1454 "(expecting integer): "
1455 "name=\"%s\"", env_entry_name
);
1460 if (env_entry
->value
.i
< 0) {
1461 _BT_LOGE_NODE(node_field_class_declarator
,
1462 "Invalid, negative array length: "
1463 "env-entry-name=\"%s\", "
1466 env_entry
->value
.i
);
1471 array_decl
= ctf_field_class_array_create();
1472 BT_ASSERT(array_decl
);
1473 array_decl
->length
=
1474 (uint64_t) env_entry
->value
.i
;
1475 array_decl
->base
.elem_fc
= nested_decl
;
1477 decl
= (void *) array_decl
;
1479 char *length_name_no_underscore
=
1480 remove_underscores_from_field_ref(
1482 if (!length_name_no_underscore
) {
1484 * remove_underscores_from_field_ref()
1490 seq_decl
= ctf_field_class_sequence_create();
1491 BT_ASSERT(seq_decl
);
1492 seq_decl
->base
.elem_fc
= nested_decl
;
1494 g_string_assign(seq_decl
->length_ref
,
1495 length_name_no_underscore
);
1496 free(length_name_no_underscore
);
1497 decl
= (void *) seq_decl
;
1500 g_free(length_name
);
1508 BT_ASSERT(!nested_decl
);
1510 BT_ASSERT(!*field_decl
);
1513 * At this point, we found the next nested declaration.
1514 * We currently own this (and lost the ownership of
1515 * nested_decl in the meantime). Pass this next
1516 * nested declaration as the content of the outer
1517 * container, MOVING its ownership.
1519 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1521 node_field_class_declarator
->
1522 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1523 &outer_field_decl
, decl
);
1526 BT_ASSERT(!outer_field_decl
);
1531 BT_ASSERT(outer_field_decl
);
1532 *field_decl
= outer_field_decl
;
1533 outer_field_decl
= NULL
;
1536 BT_ASSERT(*field_decl
);
1540 ctf_field_class_destroy(*field_decl
);
1548 ctf_field_class_destroy(nested_decl
);
1554 int visit_struct_decl_field(struct ctx
*ctx
,
1555 struct ctf_field_class_struct
*struct_decl
,
1556 struct ctf_node
*cls_specifier_list
,
1557 struct bt_list_head
*field_class_declarators
)
1560 struct ctf_node
*iter
;
1561 struct ctf_field_class
*field_decl
= NULL
;
1563 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1566 const char *field_name
;
1568 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1569 &qfield_name
, iter
, &field_decl
, NULL
);
1571 BT_ASSERT(!field_decl
);
1572 _BT_LOGE_NODE(cls_specifier_list
,
1573 "Cannot visit field class declarator: ret=%d", ret
);
1577 BT_ASSERT(field_decl
);
1578 field_name
= g_quark_to_string(qfield_name
);
1580 /* Check if field with same name already exists */
1581 if (ctf_field_class_struct_borrow_member_by_name(
1582 struct_decl
, field_name
)) {
1583 _BT_LOGE_NODE(cls_specifier_list
,
1584 "Duplicate field in structure field class: "
1585 "field-name=\"%s\"", field_name
);
1590 /* Add field to structure */
1591 ctf_field_class_struct_append_member(struct_decl
,
1592 field_name
, field_decl
);
1599 ctf_field_class_destroy(field_decl
);
1605 int visit_variant_decl_field(struct ctx
*ctx
,
1606 struct ctf_field_class_variant
*variant_decl
,
1607 struct ctf_node
*cls_specifier_list
,
1608 struct bt_list_head
*field_class_declarators
)
1611 struct ctf_node
*iter
;
1612 struct ctf_field_class
*field_decl
= NULL
;
1614 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1617 const char *field_name
;
1619 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1620 &qfield_name
, iter
, &field_decl
, NULL
);
1622 BT_ASSERT(!field_decl
);
1623 _BT_LOGE_NODE(cls_specifier_list
,
1624 "Cannot visit field class declarator: ret=%d", ret
);
1628 BT_ASSERT(field_decl
);
1629 field_name
= g_quark_to_string(qfield_name
);
1631 /* Check if field with same name already exists */
1632 if (ctf_field_class_variant_borrow_option_by_name(
1633 variant_decl
, field_name
)) {
1634 _BT_LOGE_NODE(cls_specifier_list
,
1635 "Duplicate field in variant field class: "
1636 "field-name=\"%s\"", field_name
);
1641 /* Add field to structure */
1642 ctf_field_class_variant_append_option(variant_decl
,
1643 field_name
, field_decl
);
1650 ctf_field_class_destroy(field_decl
);
1656 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1657 struct bt_list_head
*field_class_declarators
)
1661 struct ctf_node
*iter
;
1662 struct ctf_field_class
*class_decl
= NULL
;
1664 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1665 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1666 &qidentifier
, iter
, &class_decl
, NULL
);
1669 "Cannot visit field class declarator: ret=%d", ret
);
1674 /* Do not allow field class def and alias of untagged variants */
1675 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1676 struct ctf_field_class_variant
*var_fc
=
1677 (void *) class_decl
;
1679 if (var_fc
->tag_path
.path
->len
== 0) {
1681 "Type definition of untagged variant field class is not allowed.");
1687 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1688 g_quark_to_string(qidentifier
), class_decl
);
1691 "Cannot register field class alias: name=\"%s\"",
1692 g_quark_to_string(qidentifier
));
1698 ctf_field_class_destroy(class_decl
);
1704 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1705 struct ctf_node
*alias
)
1709 struct ctf_node
*node
;
1710 GQuark qdummy_field_name
;
1711 struct ctf_field_class
*class_decl
= NULL
;
1713 /* Create target field class */
1714 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1717 node
= _BT_LIST_FIRST_ENTRY(
1718 &target
->u
.field_class_alias_target
.field_class_declarators
,
1719 struct ctf_node
, siblings
);
1722 ret
= visit_field_class_declarator(ctx
,
1723 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1724 &qdummy_field_name
, node
, &class_decl
, NULL
);
1726 BT_ASSERT(!class_decl
);
1728 "Cannot visit field class declarator: ret=%d", ret
);
1732 /* Do not allow field class def and alias of untagged variants */
1733 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1734 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1736 if (var_fc
->tag_path
.path
->len
== 0) {
1737 _BT_LOGE_NODE(target
,
1738 "Type definition of untagged variant field class is not allowed.");
1745 * The semantic validator does not check whether the target is
1746 * abstract or not (if it has an identifier). Check it here.
1748 if (qdummy_field_name
!= 0) {
1749 _BT_LOGE_NODE(target
,
1750 "Expecting empty identifier: id=\"%s\"",
1751 g_quark_to_string(qdummy_field_name
));
1756 /* Create alias identifier */
1757 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1758 struct ctf_node
, siblings
);
1759 qalias
= create_class_alias_identifier(ctx
,
1760 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1761 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1762 g_quark_to_string(qalias
), class_decl
);
1765 "Cannot register class alias: name=\"%s\"",
1766 g_quark_to_string(qalias
));
1771 ctf_field_class_destroy(class_decl
);
1777 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1778 struct ctf_field_class_struct
*struct_decl
)
1782 switch (entry_node
->type
) {
1784 ret
= visit_field_class_def(ctx
,
1785 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1786 &entry_node
->u
.field_class_def
.field_class_declarators
);
1788 _BT_LOGE_NODE(entry_node
,
1789 "Cannot add field class found in structure field class: ret=%d",
1794 case NODE_TYPEALIAS
:
1795 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1796 entry_node
->u
.field_class_alias
.alias
);
1798 _BT_LOGE_NODE(entry_node
,
1799 "Cannot add field class alias found in structure field class: ret=%d",
1804 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1806 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1807 entry_node
->u
.struct_or_variant_declaration
.
1808 field_class_specifier_list
,
1809 &entry_node
->u
.struct_or_variant_declaration
.
1810 field_class_declarators
);
1816 _BT_LOGE_NODE(entry_node
,
1817 "Unexpected node type: node-type=%d", entry_node
->type
);
1827 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1828 struct ctf_field_class_variant
*variant_decl
)
1832 switch (entry_node
->type
) {
1834 ret
= visit_field_class_def(ctx
,
1835 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1836 &entry_node
->u
.field_class_def
.field_class_declarators
);
1838 _BT_LOGE_NODE(entry_node
,
1839 "Cannot add field class found in variant field class: ret=%d",
1844 case NODE_TYPEALIAS
:
1845 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1846 entry_node
->u
.field_class_alias
.alias
);
1848 _BT_LOGE_NODE(entry_node
,
1849 "Cannot add field class alias found in variant field class: ret=%d",
1854 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1856 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1857 entry_node
->u
.struct_or_variant_declaration
.
1858 field_class_specifier_list
,
1859 &entry_node
->u
.struct_or_variant_declaration
.
1860 field_class_declarators
);
1866 _BT_LOGE_NODE(entry_node
,
1867 "Unexpected node type: node-type=%d",
1878 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1879 struct bt_list_head
*decl_list
, int has_body
,
1880 struct bt_list_head
*min_align
,
1881 struct ctf_field_class_struct
**struct_decl
)
1885 BT_ASSERT(struct_decl
);
1886 *struct_decl
= NULL
;
1888 /* For named struct (without body), lookup in declaration scope */
1891 BT_LOGE_STR("Bodyless structure field class: missing name.");
1896 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1898 if (!*struct_decl
) {
1899 BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
1905 struct ctf_node
*entry_node
;
1906 uint64_t min_align_value
= 0;
1909 if (ctx_decl_scope_lookup_struct(
1910 ctx
->current_scope
, name
, 1, false)) {
1911 BT_LOGE("Structure field class already declared in local scope: "
1912 "name=\"struct %s\"", name
);
1918 if (!bt_list_empty(min_align
)) {
1919 ret
= get_unary_unsigned(min_align
, &min_align_value
);
1921 BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1927 *struct_decl
= ctf_field_class_struct_create();
1928 BT_ASSERT(*struct_decl
);
1930 if (min_align_value
!= 0) {
1931 (*struct_decl
)->base
.alignment
= min_align_value
;
1934 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1936 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1937 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1940 _BT_LOGE_NODE(entry_node
,
1941 "Cannot visit structure field class entry: "
1951 ret
= ctx_decl_scope_register_struct(ctx
->current_scope
,
1952 name
, *struct_decl
);
1954 BT_LOGE("Cannot register structure field class in declaration scope: "
1955 "name=\"struct %s\", ret=%d", name
, ret
);
1964 ctf_field_class_destroy((void *) *struct_decl
);
1965 *struct_decl
= NULL
;
1970 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1971 const char *tag
, struct bt_list_head
*decl_list
,
1972 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1975 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1977 BT_ASSERT(variant_decl
);
1978 *variant_decl
= NULL
;
1980 /* For named variant (without body), lookup in declaration scope */
1983 BT_LOGE_STR("Bodyless variant field class: missing name.");
1988 untagged_variant_decl
=
1989 ctx_decl_scope_lookup_variant(ctx
->current_scope
,
1991 if (!untagged_variant_decl
) {
1992 BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
1998 struct ctf_node
*entry_node
;
2001 if (ctx_decl_scope_lookup_variant(ctx
->current_scope
,
2003 BT_LOGE("Variant field class already declared in local scope: "
2004 "name=\"variant %s\"", name
);
2010 untagged_variant_decl
= ctf_field_class_variant_create();
2011 BT_ASSERT(untagged_variant_decl
);
2012 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
2014 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
2015 ret
= visit_variant_decl_entry(ctx
, entry_node
,
2016 untagged_variant_decl
);
2018 _BT_LOGE_NODE(entry_node
,
2019 "Cannot visit variant field class entry: "
2029 ret
= ctx_decl_scope_register_variant(
2030 ctx
->current_scope
, name
,
2031 untagged_variant_decl
);
2033 BT_LOGE("Cannot register variant field class in declaration scope: "
2034 "name=\"variant %s\", ret=%d", name
, ret
);
2041 * If tagged, create tagged variant and return; otherwise
2042 * return untagged variant.
2045 *variant_decl
= untagged_variant_decl
;
2046 untagged_variant_decl
= NULL
;
2049 * At this point, we have a fresh untagged variant; nobody
2050 * else owns it. Set its tag now.
2052 char *tag_no_underscore
=
2053 remove_underscores_from_field_ref(tag
);
2055 if (!tag_no_underscore
) {
2056 /* remove_underscores_from_field_ref() logs errors */
2060 g_string_assign(untagged_variant_decl
->tag_ref
,
2062 free(tag_no_underscore
);
2063 *variant_decl
= untagged_variant_decl
;
2064 untagged_variant_decl
= NULL
;
2067 BT_ASSERT(!untagged_variant_decl
);
2068 BT_ASSERT(*variant_decl
);
2072 ctf_field_class_destroy((void *) untagged_variant_decl
);
2073 untagged_variant_decl
= NULL
;
2074 ctf_field_class_destroy((void *) *variant_decl
);
2075 *variant_decl
= NULL
;
2088 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
2089 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
2093 struct ctf_node
*iter
;
2094 struct uori start
= {
2102 const char *label
= enumerator
->u
.enumerator
.id
;
2103 const char *effective_label
= label
;
2104 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2106 bt_list_for_each_entry(iter
, values
, siblings
) {
2107 struct uori
*target
;
2109 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2111 "Wrong expression for enumeration field class label: "
2112 "node-type=%d, label=\"%s\"", iter
->type
,
2124 switch (iter
->u
.unary_expression
.type
) {
2125 case UNARY_SIGNED_CONSTANT
:
2126 target
->is_signed
= true;
2128 iter
->u
.unary_expression
.u
.signed_constant
;
2130 case UNARY_UNSIGNED_CONSTANT
:
2131 target
->is_signed
= false;
2133 iter
->u
.unary_expression
.u
.unsigned_constant
;
2137 "Invalid enumeration field class entry: "
2138 "expecting constant signed or unsigned integer: "
2139 "node-type=%d, label=\"%s\"",
2140 iter
->u
.unary_expression
.type
, label
);
2147 "Invalid enumeration field class entry: label=\"%s\"",
2164 if (end
.is_signed
) {
2165 last
->value
.i
= end
.value
.i
+ 1;
2167 last
->value
.u
= end
.value
.u
+ 1;
2170 if (label
[0] == '_') {
2172 * Strip the first underscore of any enumeration field
2173 * class's label in case this enumeration FC is used as
2174 * a variant FC tag later. The variant FC choice names
2175 * could also start with `_`, in which case the prefix
2176 * is removed, and it the resulting choice name needs to
2179 effective_label
= &label
[1];
2182 ctf_field_class_enum_append_mapping(enum_decl
, effective_label
,
2183 start
.value
.u
, end
.value
.u
);
2191 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2192 struct ctf_node
*container_cls
,
2193 struct bt_list_head
*enumerator_list
,
2194 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2198 struct ctf_field_class_int
*integer_decl
= NULL
;
2200 BT_ASSERT(enum_decl
);
2203 /* For named enum (without body), lookup in declaration scope */
2206 BT_LOGE_STR("Bodyless enumeration field class: missing name.");
2211 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2214 BT_LOGE("Cannot find enumeration field class: "
2215 "name=\"enum %s\"", name
);
2220 struct ctf_node
*iter
;
2221 struct uori last_value
= {
2227 if (ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2229 BT_LOGE("Enumeration field class already declared in local scope: "
2230 "name=\"enum %s\"", name
);
2236 if (!container_cls
) {
2237 integer_decl
= (void *) ctx_decl_scope_lookup_alias(
2238 ctx
->current_scope
, "int", -1, true);
2239 if (!integer_decl
) {
2240 BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2245 ret
= visit_field_class_declarator(ctx
, container_cls
,
2246 &qdummy_id
, NULL
, (void *) &integer_decl
,
2249 BT_ASSERT(!integer_decl
);
2255 BT_ASSERT(integer_decl
);
2257 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2258 BT_LOGE("Container field class for enumeration field class is not an integer field class: "
2259 "fc-type=%d", integer_decl
->base
.base
.type
);
2264 *enum_decl
= ctf_field_class_enum_create();
2265 BT_ASSERT(*enum_decl
);
2266 (*enum_decl
)->base
.base
.base
.alignment
=
2267 integer_decl
->base
.base
.alignment
;
2268 ctf_field_class_int_copy_content((void *) *enum_decl
,
2269 (void *) integer_decl
);
2270 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2272 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2273 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2277 "Cannot visit enumeration field class entry: "
2284 ret
= ctx_decl_scope_register_enum(ctx
->current_scope
,
2287 BT_LOGE("Cannot register enumeration field class in declaration scope: "
2297 ctf_field_class_destroy((void *) *enum_decl
);
2301 ctf_field_class_destroy((void *) integer_decl
);
2302 integer_decl
= NULL
;
2307 int visit_field_class_specifier(struct ctx
*ctx
,
2308 struct ctf_node
*cls_specifier_list
,
2309 struct ctf_field_class
**decl
)
2312 GString
*str
= NULL
;
2315 str
= g_string_new("");
2316 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2318 _BT_LOGE_NODE(cls_specifier_list
,
2319 "Cannot get field class specifier list's name: ret=%d", ret
);
2323 *decl
= ctx_decl_scope_lookup_alias(ctx
->current_scope
, str
->str
, -1,
2326 _BT_LOGE_NODE(cls_specifier_list
,
2327 "Cannot find field class alias: name=\"%s\"", str
->str
);
2335 ctf_field_class_destroy(*decl
);
2340 g_string_free(str
, TRUE
);
2347 int visit_integer_decl(struct ctx
*ctx
,
2348 struct bt_list_head
*expressions
,
2349 struct ctf_field_class_int
**integer_decl
)
2354 struct ctf_node
*expression
;
2355 uint64_t alignment
= 0, size
= 0;
2356 bt_clock_class
*mapped_clock_class
= NULL
;
2357 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2358 bt_field_class_integer_preferred_display_base base
=
2359 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2360 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2362 *integer_decl
= NULL
;
2364 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2365 struct ctf_node
*left
, *right
;
2367 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2368 struct ctf_node
, siblings
);
2369 right
= _BT_LIST_FIRST_ENTRY(
2370 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2373 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2375 "Unexpected unary expression type: type=%d",
2376 left
->u
.unary_expression
.type
);
2381 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
2382 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2383 _BT_LOGE_DUP_ATTR(left
, "signed",
2384 "integer field class");
2389 signedness
= get_boolean(right
);
2390 if (signedness
< 0) {
2391 _BT_LOGE_NODE(right
,
2392 "Invalid boolean value for integer field class's `signed` attribute: "
2398 _SET(&set
, _INTEGER_SIGNED_SET
);
2399 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2401 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2402 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2403 "integer field class");
2408 byte_order
= get_real_byte_order(ctx
, right
);
2409 if (byte_order
== -1) {
2410 _BT_LOGE_NODE(right
,
2411 "Invalid `byte_order` attribute in integer field class: "
2417 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2418 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
2419 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2420 _BT_LOGE_DUP_ATTR(left
, "size",
2421 "integer field class");
2426 if (right
->u
.unary_expression
.type
!=
2427 UNARY_UNSIGNED_CONSTANT
) {
2428 _BT_LOGE_NODE(right
,
2429 "Invalid `size` attribute in integer field class: "
2430 "expecting unsigned constant integer: "
2432 right
->u
.unary_expression
.type
);
2437 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2439 _BT_LOGE_NODE(right
,
2440 "Invalid `size` attribute in integer field class: "
2441 "expecting positive constant integer: "
2442 "size=%" PRIu64
, size
);
2445 } else if (size
> 64) {
2446 _BT_LOGE_NODE(right
,
2447 "Invalid `size` attribute in integer field class: "
2448 "integer fields over 64 bits are not supported as of this version: "
2449 "size=%" PRIu64
, size
);
2454 _SET(&set
, _INTEGER_SIZE_SET
);
2455 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2457 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2458 _BT_LOGE_DUP_ATTR(left
, "align",
2459 "integer field class");
2464 if (right
->u
.unary_expression
.type
!=
2465 UNARY_UNSIGNED_CONSTANT
) {
2466 _BT_LOGE_NODE(right
,
2467 "Invalid `align` attribute in integer field class: "
2468 "expecting unsigned constant integer: "
2470 right
->u
.unary_expression
.type
);
2476 right
->u
.unary_expression
.u
.unsigned_constant
;
2477 if (!is_align_valid(alignment
)) {
2478 _BT_LOGE_NODE(right
,
2479 "Invalid `align` attribute in integer field class: "
2480 "expecting power of two: "
2481 "align=%" PRIu64
, alignment
);
2486 _SET(&set
, _INTEGER_ALIGN_SET
);
2487 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
2488 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2489 _BT_LOGE_DUP_ATTR(left
, "base",
2490 "integer field class");
2495 switch (right
->u
.unary_expression
.type
) {
2496 case UNARY_UNSIGNED_CONSTANT
:
2498 uint64_t constant
= right
->u
.unary_expression
.
2499 u
.unsigned_constant
;
2503 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2506 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2509 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2512 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2515 _BT_LOGE_NODE(right
,
2516 "Invalid `base` attribute in integer field class: "
2518 right
->u
.unary_expression
.u
.unsigned_constant
);
2526 char *s_right
= concatenate_unary_strings(
2527 &expression
->u
.ctf_expression
.right
);
2529 _BT_LOGE_NODE(right
,
2530 "Unexpected unary expression for integer field class's `base` attribute.");
2535 if (!strcmp(s_right
, "decimal") ||
2536 !strcmp(s_right
, "dec") ||
2537 !strcmp(s_right
, "d") ||
2538 !strcmp(s_right
, "i") ||
2539 !strcmp(s_right
, "u")) {
2540 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2541 } else if (!strcmp(s_right
, "hexadecimal") ||
2542 !strcmp(s_right
, "hex") ||
2543 !strcmp(s_right
, "x") ||
2544 !strcmp(s_right
, "X") ||
2545 !strcmp(s_right
, "p")) {
2546 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2547 } else if (!strcmp(s_right
, "octal") ||
2548 !strcmp(s_right
, "oct") ||
2549 !strcmp(s_right
, "o")) {
2550 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2551 } else if (!strcmp(s_right
, "binary") ||
2552 !strcmp(s_right
, "b")) {
2553 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2555 _BT_LOGE_NODE(right
,
2556 "Unexpected unary expression for integer field class's `base` attribute: "
2557 "base=\"%s\"", s_right
);
2567 _BT_LOGE_NODE(right
,
2568 "Invalid `base` attribute in integer field class: "
2569 "expecting unsigned constant integer or unary string.");
2574 _SET(&set
, _INTEGER_BASE_SET
);
2575 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2579 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2580 _BT_LOGE_DUP_ATTR(left
, "encoding",
2581 "integer field class");
2586 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2587 _BT_LOGE_NODE(right
,
2588 "Invalid `encoding` attribute in integer field class: "
2589 "expecting unary string.");
2594 s_right
= concatenate_unary_strings(
2595 &expression
->u
.ctf_expression
.right
);
2597 _BT_LOGE_NODE(right
,
2598 "Unexpected unary expression for integer field class's `encoding` attribute.");
2603 if (!strcmp(s_right
, "UTF8") ||
2604 !strcmp(s_right
, "utf8") ||
2605 !strcmp(s_right
, "utf-8") ||
2606 !strcmp(s_right
, "UTF-8") ||
2607 !strcmp(s_right
, "ASCII") ||
2608 !strcmp(s_right
, "ascii")) {
2609 encoding
= CTF_ENCODING_UTF8
;
2610 } else if (!strcmp(s_right
, "none")) {
2611 encoding
= CTF_ENCODING_NONE
;
2613 _BT_LOGE_NODE(right
,
2614 "Invalid `encoding` attribute in integer field class: "
2615 "unknown encoding: encoding=\"%s\"",
2623 _SET(&set
, _INTEGER_ENCODING_SET
);
2624 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
2625 const char *clock_name
;
2627 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2628 _BT_LOGE_DUP_ATTR(left
, "map",
2629 "integer field class");
2634 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2635 _BT_LOGE_NODE(right
,
2636 "Invalid `map` attribute in integer field class: "
2637 "expecting unary string.");
2643 get_map_clock_name_value(
2644 &expression
->u
.ctf_expression
.right
);
2646 char *s_right
= concatenate_unary_strings(
2647 &expression
->u
.ctf_expression
.right
);
2650 _BT_LOGE_NODE(right
,
2651 "Unexpected unary expression for integer field class's `map` attribute.");
2656 _BT_LOGE_NODE(right
,
2657 "Invalid `map` attribute in integer field class: "
2658 "cannot find clock class at this point: name=\"%s\"",
2660 _SET(&set
, _INTEGER_MAP_SET
);
2665 mapped_clock_class
=
2666 ctf_trace_class_borrow_clock_class_by_name(
2667 ctx
->ctf_tc
, clock_name
);
2668 if (!mapped_clock_class
) {
2669 _BT_LOGE_NODE(right
,
2670 "Invalid `map` attribute in integer field class: "
2671 "cannot find clock class at this point: name=\"%s\"",
2677 _SET(&set
, _INTEGER_MAP_SET
);
2680 "Unknown attribute in integer field class: "
2682 left
->u
.unary_expression
.u
.string
);
2686 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2687 BT_LOGE_STR("Missing `size` attribute in integer field class.");
2692 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2693 if (size
% CHAR_BIT
) {
2694 /* Bit-packed alignment */
2697 /* Byte-packed alignment */
2698 alignment
= CHAR_BIT
;
2702 *integer_decl
= ctf_field_class_int_create();
2703 BT_ASSERT(*integer_decl
);
2704 (*integer_decl
)->base
.base
.alignment
= alignment
;
2705 (*integer_decl
)->base
.byte_order
= byte_order
;
2706 (*integer_decl
)->base
.size
= size
;
2707 (*integer_decl
)->is_signed
= (signedness
> 0);
2708 (*integer_decl
)->disp_base
= base
;
2709 (*integer_decl
)->encoding
= encoding
;
2710 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2711 bt_clock_class_get_ref((*integer_decl
)->mapped_clock_class
);
2715 ctf_field_class_destroy((void *) *integer_decl
);
2716 *integer_decl
= NULL
;
2721 int visit_floating_point_number_decl(struct ctx
*ctx
,
2722 struct bt_list_head
*expressions
,
2723 struct ctf_field_class_float
**float_decl
)
2727 struct ctf_node
*expression
;
2728 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2729 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2733 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2734 struct ctf_node
*left
, *right
;
2736 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2737 struct ctf_node
, siblings
);
2738 right
= _BT_LIST_FIRST_ENTRY(
2739 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2742 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2744 "Unexpected unary expression type: type=%d",
2745 left
->u
.unary_expression
.type
);
2750 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
2751 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2752 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2753 "floating point number field class");
2758 byte_order
= get_real_byte_order(ctx
, right
);
2759 if (byte_order
== -1) {
2760 _BT_LOGE_NODE(right
,
2761 "Invalid `byte_order` attribute in floating point number field class: "
2767 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2768 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2770 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2771 _BT_LOGE_DUP_ATTR(left
, "exp_dig",
2772 "floating point number field class");
2777 if (right
->u
.unary_expression
.type
!=
2778 UNARY_UNSIGNED_CONSTANT
) {
2779 _BT_LOGE_NODE(right
,
2780 "Invalid `exp_dig` attribute in floating point number field class: "
2781 "expecting unsigned constant integer: "
2783 right
->u
.unary_expression
.type
);
2788 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2789 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2790 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2792 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2793 _BT_LOGE_DUP_ATTR(left
, "mant_dig",
2794 "floating point number field class");
2799 if (right
->u
.unary_expression
.type
!=
2800 UNARY_UNSIGNED_CONSTANT
) {
2801 _BT_LOGE_NODE(right
,
2802 "Invalid `mant_dig` attribute in floating point number field class: "
2803 "expecting unsigned constant integer: "
2805 right
->u
.unary_expression
.type
);
2810 mant_dig
= right
->u
.unary_expression
.u
.
2812 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2813 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2815 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2816 _BT_LOGE_DUP_ATTR(left
, "align",
2817 "floating point number field class");
2822 if (right
->u
.unary_expression
.type
!=
2823 UNARY_UNSIGNED_CONSTANT
) {
2824 _BT_LOGE_NODE(right
,
2825 "Invalid `align` attribute in floating point number field class: "
2826 "expecting unsigned constant integer: "
2828 right
->u
.unary_expression
.type
);
2833 alignment
= right
->u
.unary_expression
.u
.
2836 if (!is_align_valid(alignment
)) {
2837 _BT_LOGE_NODE(right
,
2838 "Invalid `align` attribute in floating point number field class: "
2839 "expecting power of two: "
2840 "align=%" PRIu64
, alignment
);
2845 _SET(&set
, _FLOAT_ALIGN_SET
);
2848 "Unknown attribute in floating point number field class: "
2850 left
->u
.unary_expression
.u
.string
);
2854 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2855 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2860 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2861 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2866 if (mant_dig
!= 24 && mant_dig
!= 53) {
2867 BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2872 if (mant_dig
== 24 && exp_dig
!= 8) {
2873 BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2878 if (mant_dig
== 53 && exp_dig
!= 11) {
2879 BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2884 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2885 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2886 /* Bit-packed alignment */
2889 /* Byte-packed alignment */
2890 alignment
= CHAR_BIT
;
2894 *float_decl
= ctf_field_class_float_create();
2895 BT_ASSERT(*float_decl
);
2896 (*float_decl
)->base
.base
.alignment
= alignment
;
2897 (*float_decl
)->base
.byte_order
= byte_order
;
2898 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2902 ctf_field_class_destroy((void *) *float_decl
);
2908 int visit_string_decl(struct ctx
*ctx
,
2909 struct bt_list_head
*expressions
,
2910 struct ctf_field_class_string
**string_decl
)
2914 struct ctf_node
*expression
;
2915 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2917 *string_decl
= NULL
;
2919 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2920 struct ctf_node
*left
, *right
;
2922 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2923 struct ctf_node
, siblings
);
2924 right
= _BT_LIST_FIRST_ENTRY(
2925 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2928 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2930 "Unexpected unary expression type: type=%d",
2931 left
->u
.unary_expression
.type
);
2936 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
2939 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2940 _BT_LOGE_DUP_ATTR(left
, "encoding",
2941 "string field class");
2946 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2947 _BT_LOGE_NODE(right
,
2948 "Invalid `encoding` attribute in string field class: "
2949 "expecting unary string.");
2954 s_right
= concatenate_unary_strings(
2955 &expression
->u
.ctf_expression
.right
);
2957 _BT_LOGE_NODE(right
,
2958 "Unexpected unary expression for string field class's `encoding` attribute.");
2963 if (!strcmp(s_right
, "UTF8") ||
2964 !strcmp(s_right
, "utf8") ||
2965 !strcmp(s_right
, "utf-8") ||
2966 !strcmp(s_right
, "UTF-8") ||
2967 !strcmp(s_right
, "ASCII") ||
2968 !strcmp(s_right
, "ascii")) {
2969 encoding
= CTF_ENCODING_UTF8
;
2970 } else if (!strcmp(s_right
, "none")) {
2971 encoding
= CTF_ENCODING_NONE
;
2973 _BT_LOGE_NODE(right
,
2974 "Invalid `encoding` attribute in string field class: "
2975 "unknown encoding: encoding=\"%s\"",
2983 _SET(&set
, _STRING_ENCODING_SET
);
2986 "Unknown attribute in string field class: "
2988 left
->u
.unary_expression
.u
.string
);
2992 *string_decl
= ctf_field_class_string_create();
2993 BT_ASSERT(*string_decl
);
2994 (*string_decl
)->encoding
= encoding
;
2998 ctf_field_class_destroy((void *) *string_decl
);
2999 *string_decl
= NULL
;
3004 int visit_field_class_specifier_list(struct ctx
*ctx
,
3005 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
3008 struct ctf_node
*first
, *node
;
3012 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
3013 _BT_LOGE_NODE(ts_list
,
3014 "Unexpected node type: node-type=%d", ts_list
->type
);
3019 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
3020 struct ctf_node
, siblings
);
3021 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
3022 _BT_LOGE_NODE(first
,
3023 "Unexpected node type: node-type=%d", first
->type
);
3028 node
= first
->u
.field_class_specifier
.node
;
3030 switch (first
->u
.field_class_specifier
.type
) {
3031 case TYPESPEC_INTEGER
:
3032 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
3039 case TYPESPEC_FLOATING_POINT
:
3040 ret
= visit_floating_point_number_decl(ctx
,
3041 &node
->u
.floating_point
.expressions
, (void *) decl
);
3047 case TYPESPEC_STRING
:
3048 ret
= visit_string_decl(ctx
,
3049 &node
->u
.string
.expressions
, (void *) decl
);
3055 case TYPESPEC_STRUCT
:
3056 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
3057 &node
->u
._struct
.declaration_list
,
3058 node
->u
._struct
.has_body
,
3059 &node
->u
._struct
.min_align
, (void *) decl
);
3065 case TYPESPEC_VARIANT
:
3066 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
3067 node
->u
.variant
.choice
,
3068 &node
->u
.variant
.declaration_list
,
3069 node
->u
.variant
.has_body
, (void *) decl
);
3076 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
3077 node
->u
._enum
.container_field_class
,
3078 &node
->u
._enum
.enumerator_list
,
3079 node
->u
._enum
.has_body
, (void *) decl
);
3087 case TYPESPEC_SHORT
:
3090 case TYPESPEC_FLOAT
:
3091 case TYPESPEC_DOUBLE
:
3092 case TYPESPEC_SIGNED
:
3093 case TYPESPEC_UNSIGNED
:
3095 case TYPESPEC_COMPLEX
:
3096 case TYPESPEC_IMAGINARY
:
3097 case TYPESPEC_CONST
:
3098 case TYPESPEC_ID_TYPE
:
3099 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
3101 _BT_LOGE_NODE(first
,
3102 "Cannot visit field class specifier: ret=%d",
3109 _BT_LOGE_NODE(first
,
3110 "Unexpected field class specifier type: node-type=%d",
3111 first
->u
.field_class_specifier
.type
);
3120 ctf_field_class_destroy((void *) *decl
);
3126 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3127 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
3133 switch (node
->type
) {
3135 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3136 &node
->u
.field_class_def
.field_class_declarators
);
3139 "Cannot add field class found in event class.");
3143 case NODE_TYPEALIAS
:
3144 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3145 node
->u
.field_class_alias
.alias
);
3148 "Cannot add field class alias found in event class.");
3152 case NODE_CTF_EXPRESSION
:
3154 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3156 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3161 if (!strcmp(left
, "name")) {
3162 /* This is already known at this stage */
3163 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3164 _BT_LOGE_DUP_ATTR(node
, "name", "event class");
3169 _SET(set
, _EVENT_NAME_SET
);
3170 } else if (!strcmp(left
, "id")) {
3173 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3174 _BT_LOGE_DUP_ATTR(node
, "id", "event class");
3179 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3181 /* Only read "id" if get_unary_unsigned() succeeded. */
3182 if (ret
|| (!ret
&& id
< 0)) {
3184 "Unexpected unary expression for event class's `id` attribute.");
3189 event_class
->id
= id
;
3190 _SET(set
, _EVENT_ID_SET
);
3191 } else if (!strcmp(left
, "stream_id")) {
3192 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3193 _BT_LOGE_DUP_ATTR(node
, "stream_id",
3199 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3203 * Only read "stream_id" if get_unary_unsigned()
3206 if (ret
|| (!ret
&& *stream_id
< 0)) {
3208 "Unexpected unary expression for event class's `stream_id` attribute.");
3213 _SET(set
, _EVENT_STREAM_ID_SET
);
3214 } else if (!strcmp(left
, "context")) {
3215 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3217 "Duplicate `context` entry in event class.");
3222 ret
= visit_field_class_specifier_list(ctx
,
3223 _BT_LIST_FIRST_ENTRY(
3224 &node
->u
.ctf_expression
.right
,
3225 struct ctf_node
, siblings
),
3226 &event_class
->spec_context_fc
);
3229 "Cannot create event class's context field class.");
3233 BT_ASSERT(event_class
->spec_context_fc
);
3234 _SET(set
, _EVENT_CONTEXT_SET
);
3235 } else if (!strcmp(left
, "fields")) {
3236 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3238 "Duplicate `fields` entry in event class.");
3243 ret
= visit_field_class_specifier_list(ctx
,
3244 _BT_LIST_FIRST_ENTRY(
3245 &node
->u
.ctf_expression
.right
,
3246 struct ctf_node
, siblings
),
3247 &event_class
->payload_fc
);
3250 "Cannot create event class's payload field class.");
3254 BT_ASSERT(event_class
->payload_fc
);
3255 _SET(set
, _EVENT_FIELDS_SET
);
3256 } else if (!strcmp(left
, "loglevel")) {
3257 uint64_t loglevel_value
;
3258 bt_event_class_log_level log_level
= -1;
3260 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3261 _BT_LOGE_DUP_ATTR(node
, "loglevel",
3267 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3271 "Unexpected unary expression for event class's `loglevel` attribute.");
3276 switch (loglevel_value
) {
3278 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3281 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3284 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3287 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3290 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3293 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3296 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3299 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3302 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3305 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3308 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3311 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3314 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3317 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3320 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3323 _BT_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3324 "log-level=%" PRIu64
, loglevel_value
);
3327 if (log_level
!= -1) {
3328 event_class
->log_level
= log_level
;
3331 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3332 } else if (!strcmp(left
, "model.emf.uri")) {
3335 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3336 _BT_LOGE_DUP_ATTR(node
, "model.emf.uri",
3342 right
= concatenate_unary_strings(
3343 &node
->u
.ctf_expression
.right
);
3346 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3351 if (strlen(right
) == 0) {
3353 "Not setting event class's EMF URI because it's empty.");
3355 g_string_assign(event_class
->emf_uri
,
3360 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3363 "Unknown attribute in event class: "
3364 "attr-name=\"%s\"", left
);
3388 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3392 struct ctf_node
*iter
;
3393 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3395 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3396 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3400 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3403 "Cannot concatenate unary strings.");
3407 if (!strcmp(left
, "name")) {
3408 name
= concatenate_unary_strings(
3409 &iter
->u
.ctf_expression
.right
);
3412 "Unexpected unary expression for event class's `name` attribute.");
3433 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3437 struct ctf_node
*iter
;
3438 uint64_t stream_id
= 0;
3439 char *event_name
= NULL
;
3440 struct ctf_event_class
*event_class
= NULL
;
3441 struct ctf_stream_class
*stream_class
= NULL
;
3442 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3443 bool pop_scope
= false;
3445 if (node
->visited
) {
3449 node
->visited
= TRUE
;
3450 event_name
= get_event_decl_name(ctx
, node
);
3453 "Missing `name` attribute in event class.");
3458 event_class
= ctf_event_class_create();
3459 BT_ASSERT(event_class
);
3460 g_string_assign(event_class
->name
, event_name
);
3461 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3464 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3465 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3468 _BT_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3474 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3476 * Allow missing stream_id if there is only a single
3479 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3481 /* Create implicit stream class if there's none */
3483 stream_class
= ctf_stream_class_create();
3484 BT_ASSERT(stream_class
);
3485 stream_class
->id
= stream_id
;
3486 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3488 stream_class
= stream_class
;
3491 /* Single stream class: get its ID */
3492 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3493 stream_id
= stream_class
->id
;
3497 "Missing `stream_id` attribute in event class.");
3503 /* We have the stream ID now; get the stream class if found */
3504 if (!stream_class
) {
3505 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3506 ctx
->ctf_tc
, stream_id
);
3507 if (!stream_class
) {
3509 "Cannot find stream class at this point: "
3510 "id=%" PRId64
, stream_id
);
3516 BT_ASSERT(stream_class
);
3518 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3519 /* Allow only one event without ID per stream */
3520 if (stream_class
->event_classes
->len
!= 0) {
3522 "Missing `id` attribute in event class.");
3528 event_class
->id
= 0;
3531 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3534 "Duplicate event class (same ID) in the same stream class: "
3535 "id=%" PRId64
, event_class
->id
);
3540 ctf_stream_class_append_event_class(stream_class
, event_class
);
3545 ctf_event_class_destroy(event_class
);
3565 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3566 struct ctf_field_class
*fc
)
3568 bt_clock_class
*clock_class_to_map_to
= NULL
;
3569 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3571 uint64_t clock_class_count
;
3577 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3578 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3582 if (int_fc
->mapped_clock_class
) {
3583 /* Already mapped */
3587 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3589 switch (clock_class_count
) {
3592 * No clock class exists in the trace at this point. Create an
3593 * implicit one at 1 GHz, named `default`, and use this clock
3596 clock_class_to_map_to
= bt_clock_class_create();
3597 BT_ASSERT(clock_class_to_map_to
);
3598 bt_clock_class_set_frequency(clock_class_to_map_to
,
3599 UINT64_C(1000000000));
3600 ret
= bt_clock_class_set_name(clock_class_to_map_to
,
3602 BT_ASSERT(ret
== 0);
3603 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3604 clock_class_to_map_to
);
3605 bt_clock_class_get_ref(clock_class_to_map_to
);
3609 * Only one clock class exists in the trace at this point: use
3612 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3613 bt_clock_class_get_ref(clock_class_to_map_to
);
3617 * Timestamp field not mapped to a clock class and there's more
3618 * than one clock class in the trace: this is an error.
3620 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3621 "but there's more than one clock class in the trace at this point.");
3626 BT_ASSERT(clock_class_to_map_to
);
3627 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3628 bt_clock_class_get_ref(int_fc
->mapped_clock_class
);
3631 bt_clock_class_put_ref(clock_class_to_map_to
);
3636 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3637 struct ctf_field_class
*root_fc
, const char *field_name
)
3641 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3642 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3648 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3649 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3653 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3654 count
= struct_fc
->members
->len
;
3656 count
= var_fc
->options
->len
;
3659 for (i
= 0; i
< count
; i
++) {
3660 struct ctf_named_field_class
*named_fc
= NULL
;
3662 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3663 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3665 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3666 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3670 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3671 ret
= auto_map_field_to_trace_clock_class(ctx
,
3674 BT_LOGE("Cannot automatically map field to trace's clock class: "
3675 "field-name=\"%s\"", field_name
);
3680 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3683 BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3684 "field-name=\"%s\", root-field-name=\"%s\"",
3685 field_name
, named_fc
->name
->str
);
3695 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3696 struct ctf_stream_class
*stream_class
, int *set
)
3701 switch (node
->type
) {
3703 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3704 &node
->u
.field_class_def
.field_class_declarators
);
3707 "Cannot add field class found in stream class.");
3711 case NODE_TYPEALIAS
:
3712 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3713 node
->u
.field_class_alias
.alias
);
3716 "Cannot add field class alias found in stream class.");
3720 case NODE_CTF_EXPRESSION
:
3722 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3724 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3729 if (!strcmp(left
, "id")) {
3732 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3733 _BT_LOGE_DUP_ATTR(node
, "id",
3734 "stream declaration");
3739 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3742 /* Only read "id" if get_unary_unsigned() succeeded. */
3743 if (ret
|| (!ret
&& id
< 0)) {
3745 "Unexpected unary expression for stream class's `id` attribute.");
3750 if (ctf_trace_class_borrow_stream_class_by_id(
3753 "Duplicate stream class (same ID): id=%" PRId64
,
3759 stream_class
->id
= id
;
3760 _SET(set
, _STREAM_ID_SET
);
3761 } else if (!strcmp(left
, "event.header")) {
3762 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3764 "Duplicate `event.header` entry in stream class.");
3769 ret
= visit_field_class_specifier_list(ctx
,
3770 _BT_LIST_FIRST_ENTRY(
3771 &node
->u
.ctf_expression
.right
,
3772 struct ctf_node
, siblings
),
3773 &stream_class
->event_header_fc
);
3776 "Cannot create stream class's event header field class.");
3780 BT_ASSERT(stream_class
->event_header_fc
);
3781 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3782 stream_class
->event_header_fc
, "timestamp");
3785 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3789 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3790 } else if (!strcmp(left
, "event.context")) {
3791 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3793 "Duplicate `event.context` entry in stream class.");
3798 ret
= visit_field_class_specifier_list(ctx
,
3799 _BT_LIST_FIRST_ENTRY(
3800 &node
->u
.ctf_expression
.right
,
3801 struct ctf_node
, siblings
),
3802 &stream_class
->event_common_context_fc
);
3805 "Cannot create stream class's event context field class.");
3809 BT_ASSERT(stream_class
->event_common_context_fc
);
3810 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3811 } else if (!strcmp(left
, "packet.context")) {
3812 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3814 "Duplicate `packet.context` entry in stream class.");
3819 ret
= visit_field_class_specifier_list(ctx
,
3820 _BT_LIST_FIRST_ENTRY(
3821 &node
->u
.ctf_expression
.right
,
3822 struct ctf_node
, siblings
),
3823 &stream_class
->packet_context_fc
);
3826 "Cannot create stream class's packet context field class.");
3830 BT_ASSERT(stream_class
->packet_context_fc
);
3831 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3832 stream_class
->packet_context_fc
,
3836 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3840 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3841 stream_class
->packet_context_fc
,
3845 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3849 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3852 "Unknown attribute in stream class: "
3853 "attr-name=\"%s\"", left
);
3874 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3878 struct ctf_node
*iter
;
3879 struct ctf_stream_class
*stream_class
= NULL
;
3880 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3882 if (node
->visited
) {
3886 node
->visited
= TRUE
;
3887 stream_class
= ctf_stream_class_create();
3888 BT_ASSERT(stream_class
);
3889 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3891 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3892 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3895 "Cannot visit stream class's entry: "
3904 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3905 /* Check that packet header has `stream_id` field */
3906 struct ctf_named_field_class
*named_fc
= NULL
;
3908 if (!ctx
->ctf_tc
->packet_header_fc
) {
3910 "Stream class has a `id` attribute, "
3911 "but trace has no packet header field class.");
3915 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3916 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3919 "Stream class has a `id` attribute, "
3920 "but trace's packet header field class has no `stream_id` field.");
3924 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3925 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3927 "Stream class has a `id` attribute, "
3928 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3932 /* Allow only _one_ ID-less stream */
3933 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3935 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3940 /* Automatic ID: 0 */
3941 stream_class
->id
= 0;
3945 * Make sure that this stream class's ID is currently unique in
3948 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3949 stream_class
->id
)) {
3951 "Duplicate stream class (same ID): id=%" PRId64
,
3957 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3958 stream_class
= NULL
;
3962 ctf_stream_class_destroy(stream_class
);
3963 stream_class
= NULL
;
3970 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3976 switch (node
->type
) {
3978 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3979 &node
->u
.field_class_def
.field_class_declarators
);
3982 "Cannot add field class found in trace (`trace` block).");
3986 case NODE_TYPEALIAS
:
3987 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3988 node
->u
.field_class_alias
.alias
);
3991 "Cannot add field class alias found in trace (`trace` block).");
3995 case NODE_CTF_EXPRESSION
:
3997 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3999 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
4004 if (!strcmp(left
, "major")) {
4005 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
4006 _BT_LOGE_DUP_ATTR(node
, "major", "trace");
4011 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4015 "Unexpected unary expression for trace's `major` attribute.");
4022 "Invalid trace's `minor` attribute: expecting 1.");
4026 ctx
->ctf_tc
->major
= val
;
4027 _SET(set
, _TRACE_MAJOR_SET
);
4028 } else if (!strcmp(left
, "minor")) {
4029 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
4030 _BT_LOGE_DUP_ATTR(node
, "minor", "trace");
4035 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4039 "Unexpected unary expression for trace's `minor` attribute.");
4046 "Invalid trace's `minor` attribute: expecting 8.");
4050 ctx
->ctf_tc
->minor
= val
;
4051 _SET(set
, _TRACE_MINOR_SET
);
4052 } else if (!strcmp(left
, "uuid")) {
4053 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
4054 _BT_LOGE_DUP_ATTR(node
, "uuid", "trace");
4059 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
,
4063 "Invalid trace's `uuid` attribute.");
4067 ctx
->ctf_tc
->is_uuid_set
= true;
4068 _SET(set
, _TRACE_UUID_SET
);
4069 } else if (!strcmp(left
, "byte_order")) {
4070 /* Default byte order is already known at this stage */
4071 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
4072 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4078 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= -1);
4079 _SET(set
, _TRACE_BYTE_ORDER_SET
);
4080 } else if (!strcmp(left
, "packet.header")) {
4081 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
4083 "Duplicate `packet.header` entry in trace.");
4088 ret
= visit_field_class_specifier_list(ctx
,
4089 _BT_LIST_FIRST_ENTRY(
4090 &node
->u
.ctf_expression
.right
,
4091 struct ctf_node
, siblings
),
4092 &ctx
->ctf_tc
->packet_header_fc
);
4095 "Cannot create trace's packet header field class.");
4099 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
4100 _SET(set
, _TRACE_PACKET_HEADER_SET
);
4103 "Unknown attribute in stream class: "
4104 "attr-name=\"%s\"", left
);
4112 _BT_LOGE_NODE(node
, "Unknown expression in trace.");
4125 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
4129 struct ctf_node
*iter
;
4130 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
4132 if (node
->visited
) {
4136 node
->visited
= TRUE
;
4138 if (ctx
->is_trace_visited
) {
4139 _BT_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
4144 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4146 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
4147 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
4149 _BT_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
4158 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
4160 "Missing `major` attribute in trace (`trace` block).");
4165 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
4167 "Missing `minor` attribute in trace (`trace` block).");
4172 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4174 "Missing `byte_order` attribute in trace (`trace` block).");
4179 ctx
->is_trace_visited
= true;
4189 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4193 struct ctf_node
*entry_node
;
4194 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4196 if (node
->visited
) {
4200 node
->visited
= TRUE
;
4202 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4203 struct bt_list_head
*right_head
=
4204 &entry_node
->u
.ctf_expression
.right
;
4206 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4207 _BT_LOGE_NODE(entry_node
,
4208 "Wrong expression in environment entry: "
4209 "node-type=%d", entry_node
->type
);
4214 left
= concatenate_unary_strings(
4215 &entry_node
->u
.ctf_expression
.left
);
4217 _BT_LOGE_NODE(entry_node
,
4218 "Cannot get environment entry's name.");
4223 if (is_unary_string(right_head
)) {
4224 char *right
= concatenate_unary_strings(right_head
);
4227 _BT_LOGE_NODE(entry_node
,
4228 "Unexpected unary expression for environment entry's value: "
4229 "name=\"%s\"", left
);
4234 if (strcmp(left
, "tracer_name") == 0) {
4235 if (strncmp(right
, "lttng", 5) == 0) {
4236 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4237 "tracer-name=\"%s\"",
4239 ctx
->is_lttng
= true;
4243 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4244 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4247 } else if (is_unary_unsigned(right_head
) ||
4248 is_unary_signed(right_head
)) {
4251 if (is_unary_unsigned(right_head
)) {
4252 ret
= get_unary_unsigned(right_head
,
4255 ret
= get_unary_signed(right_head
, &v
);
4258 _BT_LOGE_NODE(entry_node
,
4259 "Unexpected unary expression for environment entry's value: "
4260 "name=\"%s\"", left
);
4265 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4266 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4269 _BT_LOGW_NODE(entry_node
,
4270 "Environment entry has unknown type: "
4271 "name=\"%s\"", left
);
4287 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4292 struct ctf_node
*node
;
4293 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4295 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4296 if (node
->type
== NODE_CTF_EXPRESSION
) {
4297 struct ctf_node
*right_node
;
4299 left
= concatenate_unary_strings(
4300 &node
->u
.ctf_expression
.left
);
4303 "Cannot concatenate unary strings.");
4308 if (!strcmp(left
, "byte_order")) {
4309 enum ctf_byte_order bo
;
4311 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4312 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4318 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4319 right_node
= _BT_LIST_FIRST_ENTRY(
4320 &node
->u
.ctf_expression
.right
,
4321 struct ctf_node
, siblings
);
4322 bo
= byte_order_from_unary_expr(right_node
);
4325 "Invalid `byte_order` attribute in trace (`trace` block): "
4326 "expecting `le`, `be`, or `network`.");
4329 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4331 "Invalid `byte_order` attribute in trace (`trace` block): "
4332 "cannot be set to `native` here.");
4337 ctx
->ctf_tc
->default_byte_order
= bo
;
4345 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4346 _BT_LOGE_NODE(trace_node
,
4347 "Missing `byte_order` attribute in trace (`trace` block).");
4360 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4361 bt_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4362 uint64_t *offset_cycles
)
4367 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4368 _BT_LOGE_NODE(entry_node
,
4369 "Unexpected node type: node-type=%d",
4375 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4377 _BT_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4382 if (!strcmp(left
, "name")) {
4385 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4386 _BT_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4391 right
= concatenate_unary_strings(
4392 &entry_node
->u
.ctf_expression
.right
);
4394 _BT_LOGE_NODE(entry_node
,
4395 "Unexpected unary expression for clock class's `name` attribute.");
4400 ret
= bt_clock_class_set_name(clock
, right
);
4402 _BT_LOGE_NODE(entry_node
,
4403 "cannot set clock class's name");
4409 _SET(set
, _CLOCK_NAME_SET
);
4410 } else if (!strcmp(left
, "uuid")) {
4411 uint8_t uuid
[BABELTRACE_UUID_LEN
];
4413 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4414 _BT_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4419 ret
= get_unary_uuid(&entry_node
->u
.ctf_expression
.right
, uuid
);
4421 _BT_LOGE_NODE(entry_node
,
4422 "Invalid clock class's `uuid` attribute.");
4426 bt_clock_class_set_uuid(clock
, uuid
);
4427 _SET(set
, _CLOCK_UUID_SET
);
4428 } else if (!strcmp(left
, "description")) {
4431 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4432 _BT_LOGE_DUP_ATTR(entry_node
, "description",
4438 right
= concatenate_unary_strings(
4439 &entry_node
->u
.ctf_expression
.right
);
4441 _BT_LOGE_NODE(entry_node
,
4442 "Unexpected unary expression for clock class's `description` attribute.");
4447 ret
= bt_clock_class_set_description(clock
, right
);
4449 _BT_LOGE_NODE(entry_node
,
4450 "Cannot set clock class's description.");
4456 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4457 } else if (!strcmp(left
, "freq")) {
4458 uint64_t freq
= UINT64_C(-1);
4460 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4461 _BT_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4466 ret
= get_unary_unsigned(
4467 &entry_node
->u
.ctf_expression
.right
, &freq
);
4469 _BT_LOGE_NODE(entry_node
,
4470 "Unexpected unary expression for clock class's `freq` attribute.");
4475 if (freq
== UINT64_C(-1) || freq
== 0) {
4476 _BT_LOGE_NODE(entry_node
,
4477 "Invalid clock class frequency: freq=%" PRIu64
,
4483 bt_clock_class_set_frequency(clock
, freq
);
4484 _SET(set
, _CLOCK_FREQ_SET
);
4485 } else if (!strcmp(left
, "precision")) {
4488 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4489 _BT_LOGE_DUP_ATTR(entry_node
, "precision",
4495 ret
= get_unary_unsigned(
4496 &entry_node
->u
.ctf_expression
.right
, &precision
);
4498 _BT_LOGE_NODE(entry_node
,
4499 "Unexpected unary expression for clock class's `precision` attribute.");
4504 bt_clock_class_set_precision(clock
, precision
);
4505 _SET(set
, _CLOCK_PRECISION_SET
);
4506 } else if (!strcmp(left
, "offset_s")) {
4507 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4508 _BT_LOGE_DUP_ATTR(entry_node
, "offset_s",
4514 ret
= get_unary_signed(
4515 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4517 _BT_LOGE_NODE(entry_node
,
4518 "Unexpected unary expression for clock class's `offset_s` attribute.");
4523 _SET(set
, _CLOCK_OFFSET_S_SET
);
4524 } else if (!strcmp(left
, "offset")) {
4525 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4526 _BT_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4531 ret
= get_unary_unsigned(
4532 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4534 _BT_LOGE_NODE(entry_node
,
4535 "Unexpected unary expression for clock class's `offset` attribute.");
4540 _SET(set
, _CLOCK_OFFSET_SET
);
4541 } else if (!strcmp(left
, "absolute")) {
4542 struct ctf_node
*right
;
4544 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4545 _BT_LOGE_DUP_ATTR(entry_node
, "absolute",
4551 right
= _BT_LIST_FIRST_ENTRY(
4552 &entry_node
->u
.ctf_expression
.right
,
4553 struct ctf_node
, siblings
);
4554 ret
= get_boolean(right
);
4556 _BT_LOGE_NODE(entry_node
,
4557 "Unexpected unary expression for clock class's `absolute` attribute.");
4562 bt_clock_class_set_is_absolute(clock
, ret
);
4563 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4565 _BT_LOGW_NODE(entry_node
,
4566 "Unknown attribute in clock class: attr-name=\"%s\"",
4580 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4585 if (frequency
== UINT64_C(1000000000)) {
4588 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4595 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4596 uint64_t *offset_cycles
, uint64_t freq
)
4598 if (*offset_cycles
>= freq
) {
4599 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4601 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4602 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4607 void apply_clock_class_offset(struct ctx
*ctx
,
4608 bt_clock_class
*clock
)
4611 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4612 uint64_t offset_ns_to_apply
;
4613 int64_t cur_offset_s
;
4614 uint64_t cur_offset_cycles
;
4616 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4617 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4621 /* Transfer nanoseconds to seconds as much as possible */
4622 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4623 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4624 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4625 const int64_t extra_s
= -abs_extra_s
;
4626 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4627 (extra_s
* INT64_C(1000000000));
4629 BT_ASSERT(offset_ns
> 0);
4630 offset_ns_to_apply
= (uint64_t) offset_ns
;
4631 offset_s_to_apply
+= extra_s
;
4633 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4634 INT64_C(1000000000);
4635 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4636 (extra_s
* INT64_C(1000000000));
4638 BT_ASSERT(offset_ns
>= 0);
4639 offset_ns_to_apply
= (uint64_t) offset_ns
;
4640 offset_s_to_apply
+= extra_s
;
4643 freq
= bt_clock_class_get_frequency(clock
);
4644 bt_clock_class_get_offset(clock
,
4645 &cur_offset_s
, &cur_offset_cycles
);
4648 cur_offset_s
+= offset_s_to_apply
;
4649 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4652 * Recalibrate offsets because the part in cycles can be greater
4653 * than the frequency at this point.
4655 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4657 /* Set final offsets */
4658 bt_clock_class_set_offset(clock
, cur_offset_s
, cur_offset_cycles
);
4665 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4669 bt_clock_class
*clock
;
4670 struct ctf_node
*entry_node
;
4671 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4672 const char *clock_class_name
;
4673 int64_t offset_seconds
= 0;
4674 uint64_t offset_cycles
= 0;
4677 if (clock_node
->visited
) {
4681 clock_node
->visited
= TRUE
;
4683 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4684 clock
= bt_clock_class_create();
4686 _BT_LOGE_NODE(clock_node
,
4687 "Cannot create default clock class.");
4692 /* CTF: not absolute by default */
4693 bt_clock_class_set_is_absolute(clock
, BT_FALSE
);
4695 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4696 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4697 &offset_seconds
, &offset_cycles
);
4699 _BT_LOGE_NODE(entry_node
,
4700 "Cannot visit clock class's entry: ret=%d",
4706 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4707 _BT_LOGE_NODE(clock_node
,
4708 "Missing `name` attribute in clock class.");
4713 clock_class_name
= bt_clock_class_get_name(clock
);
4714 BT_ASSERT(clock_class_name
);
4715 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4717 * Old versions of LTTng forgot to set its clock class
4718 * as absolute, even if it is. This is important because
4719 * it's a condition to be able to sort messages
4720 * from different sources.
4722 bt_clock_class_set_is_absolute(clock
, BT_TRUE
);
4726 * Adjust offsets so that the part in cycles is less than the
4727 * frequency (move to the part in seconds).
4729 freq
= bt_clock_class_get_frequency(clock
);
4730 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4731 BT_ASSERT(offset_cycles
< bt_clock_class_get_frequency(clock
));
4732 bt_clock_class_set_offset(clock
, offset_seconds
, offset_cycles
);
4733 apply_clock_class_offset(ctx
, clock
);
4734 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4735 bt_clock_class_get_ref(clock
);
4738 BT_CLOCK_CLASS_PUT_REF_AND_RESET(clock
);
4743 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4747 if (root_decl_node
->visited
) {
4751 root_decl_node
->visited
= TRUE
;
4753 switch (root_decl_node
->type
) {
4755 ret
= visit_field_class_def(ctx
,
4756 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4757 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4759 _BT_LOGE_NODE(root_decl_node
,
4760 "Cannot add field class found in root scope.");
4764 case NODE_TYPEALIAS
:
4765 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4766 root_decl_node
->u
.field_class_alias
.alias
);
4768 _BT_LOGE_NODE(root_decl_node
,
4769 "Cannot add field class alias found in root scope.");
4773 case NODE_TYPE_SPECIFIER_LIST
:
4775 struct ctf_field_class
*decl
= NULL
;
4778 * Just add the field class specifier to the root
4779 * declaration scope. Put local reference.
4781 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4783 _BT_LOGE_NODE(root_decl_node
,
4784 "Cannot visit root scope's field class: "
4790 ctf_field_class_destroy(decl
);
4795 _BT_LOGE_NODE(root_decl_node
,
4796 "Unexpected node type: node-type=%d",
4797 root_decl_node
->type
);
4807 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4808 bt_self_component_source
*self_comp
,
4809 const struct ctf_metadata_decoder_config
*decoder_config
)
4811 struct ctx
*ctx
= NULL
;
4813 /* Create visitor's context */
4814 ctx
= ctx_create(self_comp
, decoder_config
);
4816 BT_LOGE_STR("Cannot create visitor's context.");
4827 return (void *) ctx
;
4831 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4833 ctx_destroy((void *) visitor
);
4837 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4838 struct ctf_visitor_generate_ir
*visitor
)
4840 struct ctx
*ctx
= (void *) visitor
;
4844 if (ctx
->trace_class
) {
4845 bt_trace_class_get_ref(ctx
->trace_class
);
4848 return ctx
->trace_class
;
4852 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4853 struct ctf_visitor_generate_ir
*visitor
)
4855 struct ctx
*ctx
= (void *) visitor
;
4858 BT_ASSERT(ctx
->ctf_tc
);
4863 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4864 struct ctf_node
*node
)
4867 struct ctx
*ctx
= (void *) visitor
;
4869 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4871 switch (node
->type
) {
4874 struct ctf_node
*iter
;
4875 bool got_trace_decl
= false;
4878 * The first thing we need is the native byte order of
4879 * the trace block, because early class aliases can have
4880 * a `byte_order` attribute set to `native`. If we don't
4881 * have the native byte order yet, and we don't have any
4882 * trace block yet, then fail with EINCOMPLETE.
4884 if (ctx
->ctf_tc
->default_byte_order
== -1) {
4885 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4886 if (got_trace_decl
) {
4888 "Duplicate trace (`trace` block).");
4893 ret
= set_trace_byte_order(ctx
, iter
);
4896 "Cannot set trace's native byte order: "
4901 got_trace_decl
= true;
4904 if (!got_trace_decl
) {
4905 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4911 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4912 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4913 BT_ASSERT(ctx
->current_scope
&&
4914 ctx
->current_scope
->parent_scope
== NULL
);
4917 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4918 ret
= visit_env(ctx
, iter
);
4921 "Cannot visit trace's environment (`env` block) entry: "
4927 BT_ASSERT(ctx
->current_scope
&&
4928 ctx
->current_scope
->parent_scope
== NULL
);
4931 * Visit clock blocks.
4933 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4934 ret
= visit_clock_decl(ctx
, iter
);
4937 "Cannot visit clock class: ret=%d",
4943 BT_ASSERT(ctx
->current_scope
&&
4944 ctx
->current_scope
->parent_scope
== NULL
);
4947 * Visit root declarations next, as they can be used by any
4950 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4952 ret
= visit_root_decl(ctx
, iter
);
4955 "Cannot visit root entry: ret=%d",
4961 BT_ASSERT(ctx
->current_scope
&&
4962 ctx
->current_scope
->parent_scope
== NULL
);
4964 /* Callsite blocks are not supported */
4965 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4967 "\"callsite\" blocks are not supported as of this version.");
4970 BT_ASSERT(ctx
->current_scope
&&
4971 ctx
->current_scope
->parent_scope
== NULL
);
4974 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4975 ret
= visit_trace_decl(ctx
, iter
);
4978 "Cannot visit trace (`trace` block): "
4984 BT_ASSERT(ctx
->current_scope
&&
4985 ctx
->current_scope
->parent_scope
== NULL
);
4988 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4989 ret
= visit_stream_decl(ctx
, iter
);
4992 "Cannot visit stream class: ret=%d",
4998 BT_ASSERT(ctx
->current_scope
&&
4999 ctx
->current_scope
->parent_scope
== NULL
);
5002 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
5003 ret
= visit_event_decl(ctx
, iter
);
5006 "Cannot visit event class: ret=%d",
5012 BT_ASSERT(ctx
->current_scope
&&
5013 ctx
->current_scope
->parent_scope
== NULL
);
5018 "Unexpected node type: node-type=%d",
5024 /* Update default clock classes */
5025 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
);
5031 /* Update trace class meanings */
5032 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
5038 /* Update text arrays and sequences */
5039 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
5045 /* Resolve sequence lengths and variant tags */
5046 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
);
5052 if (ctx
->trace_class
) {
5054 * Update "in IR" for field classes.
5056 * If we have no IR trace class, then we'll have no way
5057 * to create IR fields anyway, so we leave all the
5058 * `in_ir` members false.
5060 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
5067 /* Update saved value indexes */
5068 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
5074 /* Validate what we have so far */
5075 ret
= ctf_trace_class_validate(ctx
->ctf_tc
);
5081 if (ctx
->trace_class
) {
5082 /* Copy new CTF metadata -> new IR metadata */
5083 ret
= ctf_trace_class_translate(ctx
->trace_class
, ctx
->ctf_tc
);