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 being filled (owned by this) */
197 struct bt_private_trace
*trace
;
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 /* Eventual name suffix of the trace to set (owned by this) */
212 char *trace_class_name_suffix
;
214 /* Config passed by the user */
215 struct ctf_metadata_decoder_config decoder_config
;
221 struct ctf_visitor_generate_ir
;
224 * Creates a new declaration scope.
226 * @param par_scope Parent scope (NULL if creating a root scope)
227 * @returns New declaration scope, or NULL on error
230 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx_decl_scope
*par_scope
)
232 struct ctx_decl_scope
*scope
;
234 scope
= g_new(struct ctx_decl_scope
, 1);
236 BT_LOGE_STR("Failed to allocate one declaration scope.");
240 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
241 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
242 scope
->parent_scope
= par_scope
;
249 * Destroys a declaration scope.
251 * This function does not destroy the parent scope.
253 * @param scope Scope to destroy
256 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
262 g_hash_table_destroy(scope
->decl_map
);
270 * Returns the GQuark of a prefixed alias.
272 * @param prefix Prefix character
274 * @returns Associated GQuark, or 0 on error
277 GQuark
get_prefixed_named_quark(char prefix
, const char *name
)
283 /* Prefix character + original string + '\0' */
284 char *prname
= g_new(char, strlen(name
) + 2);
286 BT_LOGE_STR("Failed to allocate a string.");
290 sprintf(prname
, "%c%s", prefix
, name
);
291 qname
= g_quark_from_string(prname
);
299 * Looks up a prefixed class alias within a declaration scope.
301 * @param scope Declaration scope
302 * @param prefix Prefix character
303 * @param name Alias name
304 * @param levels Number of levels to dig into (-1 means infinite)
305 * @param copy True to return a copy
306 * @returns Declaration (owned by caller if \p copy is true),
307 * or NULL if not found
310 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
311 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
312 int levels
, bool copy
)
316 struct ctf_field_class
*decl
= NULL
;
317 struct ctx_decl_scope
*cur_scope
= scope
;
321 qname
= get_prefixed_named_quark(prefix
, name
);
330 while (cur_scope
&& cur_levels
< levels
) {
331 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
332 (gconstpointer
) GUINT_TO_POINTER(qname
));
334 /* Caller's reference */
336 decl
= ctf_field_class_copy(decl
);
343 cur_scope
= cur_scope
->parent_scope
;
352 * Looks up a class alias within a declaration scope.
354 * @param scope Declaration scope
355 * @param name Alias name
356 * @param levels Number of levels to dig into (-1 means infinite)
357 * @param copy True to return a copy
358 * @returns Declaration (owned by caller if \p copy is true),
359 * or NULL if not found
362 struct ctf_field_class
*ctx_decl_scope_lookup_alias(
363 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
366 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ALIAS
,
371 * Looks up an enumeration within a declaration scope.
373 * @param scope Declaration scope
374 * @param name Enumeration name
375 * @param levels Number of levels to dig into (-1 means infinite)
376 * @param copy True to return a copy
377 * @returns Declaration (owned by caller if \p copy is true),
378 * or NULL if not found
381 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(
382 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
385 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ENUM
,
390 * Looks up a structure within a declaration scope.
392 * @param scope Declaration scope
393 * @param name Structure name
394 * @param levels Number of levels to dig into (-1 means infinite)
395 * @param copy True to return a copy
396 * @returns Declaration (owned by caller if \p copy is true),
397 * or NULL if not found
400 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(
401 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
404 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
405 _PREFIX_STRUCT
, name
, levels
, copy
);
409 * Looks up a variant within a declaration scope.
411 * @param scope Declaration scope
412 * @param name Variant name
413 * @param levels Number of levels to dig into (-1 means infinite)
414 * @param copy True to return a copy
415 * @returns Declaration (owned by caller if \p copy is true),
416 * or NULL if not found
419 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(
420 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
423 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
424 _PREFIX_VARIANT
, name
, levels
, copy
);
428 * Registers a prefixed class alias within a declaration scope.
430 * @param scope Declaration scope
431 * @param prefix Prefix character
432 * @param name Alias name (non-NULL)
433 * @param decl Field class to register (copied)
434 * @returns 0 if registration went okay, negative value otherwise
437 int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope
*scope
,
438 char prefix
, const char *name
, struct ctf_field_class
*decl
)
446 qname
= get_prefixed_named_quark(prefix
, name
);
452 /* Make sure alias does not exist in local scope */
453 if (ctx_decl_scope_lookup_prefix_alias(scope
, prefix
, name
, 1,
459 decl
= ctf_field_class_copy(decl
);
461 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
468 * Registers a class alias within a declaration scope.
470 * @param scope Declaration scope
471 * @param name Alias name (non-NULL)
472 * @param decl Field class to register (copied)
473 * @returns 0 if registration went okay, negative value otherwise
476 int ctx_decl_scope_register_alias(struct ctx_decl_scope
*scope
,
477 const char *name
, struct ctf_field_class
*decl
)
479 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ALIAS
,
480 name
, (void *) decl
);
484 * Registers an enumeration declaration within a declaration scope.
486 * @param scope Declaration scope
487 * @param name Enumeration name (non-NULL)
488 * @param decl Enumeration field class to register (copied)
489 * @returns 0 if registration went okay, negative value otherwise
492 int ctx_decl_scope_register_enum(struct ctx_decl_scope
*scope
,
493 const char *name
, struct ctf_field_class_enum
*decl
)
495 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ENUM
,
496 name
, (void *) decl
);
500 * Registers a structure declaration within a declaration scope.
502 * @param scope Declaration scope
503 * @param name Structure name (non-NULL)
504 * @param decl Structure field class to register (copied)
505 * @returns 0 if registration went okay, negative value otherwise
508 int ctx_decl_scope_register_struct(struct ctx_decl_scope
*scope
,
509 const char *name
, struct ctf_field_class_struct
*decl
)
511 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_STRUCT
,
512 name
, (void *) decl
);
516 * Registers a variant declaration within a declaration scope.
518 * @param scope Declaration scope
519 * @param name Variant name (non-NULL)
520 * @param decl Variant field class to register
521 * @returns 0 if registration went okay, negative value otherwise
524 int ctx_decl_scope_register_variant(struct ctx_decl_scope
*scope
,
525 const char *name
, struct ctf_field_class_variant
*decl
)
527 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_VARIANT
,
528 name
, (void *) decl
);
532 * Destroys a visitor context.
534 * @param ctx Visitor context to destroy
537 void ctx_destroy(struct ctx
*ctx
)
539 struct ctx_decl_scope
*scope
;
545 scope
= ctx
->current_scope
;
548 * Destroy all scopes, from current one to the root scope.
551 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
553 ctx_decl_scope_destroy(scope
);
554 scope
= parent_scope
;
557 bt_object_put_ref(ctx
->trace
);
560 ctf_trace_class_destroy(ctx
->ctf_tc
);
563 if (ctx
->trace_class_name_suffix
) {
564 free(ctx
->trace_class_name_suffix
);
574 * Creates a new visitor context.
576 * @param trace Associated trace
577 * @returns New visitor context, or NULL on error
580 struct ctx
*ctx_create(const struct ctf_metadata_decoder_config
*decoder_config
,
581 const char *trace_class_name_suffix
)
583 struct ctx
*ctx
= NULL
;
585 BT_ASSERT(decoder_config
);
587 ctx
= g_new0(struct ctx
, 1);
589 BT_LOGE_STR("Failed to allocate one visitor context.");
593 ctx
->trace
= bt_private_trace_create();
595 BT_LOGE_STR("Cannot create empty trace.");
599 ctx
->ctf_tc
= ctf_trace_class_create();
601 BT_LOGE_STR("Cannot create CTF trace class.");
605 /* Root declaration scope */
606 ctx
->current_scope
= ctx_decl_scope_create(NULL
);
607 if (!ctx
->current_scope
) {
608 BT_LOGE_STR("Cannot create declaration scope.");
612 if (trace_class_name_suffix
) {
613 ctx
->trace_class_name_suffix
= strdup(trace_class_name_suffix
);
614 if (!ctx
->trace_class_name_suffix
) {
615 BT_LOGE_STR("Failed to copy string.");
620 ctx
->decoder_config
= *decoder_config
;
632 * Pushes a new declaration scope on top of a visitor context's
633 * declaration scope stack.
635 * @param ctx Visitor context
636 * @returns 0 on success, or a negative value on error
639 int ctx_push_scope(struct ctx
*ctx
)
642 struct ctx_decl_scope
*new_scope
;
645 new_scope
= ctx_decl_scope_create(ctx
->current_scope
);
647 BT_LOGE_STR("Cannot create declaration scope.");
652 ctx
->current_scope
= new_scope
;
659 void ctx_pop_scope(struct ctx
*ctx
)
661 struct ctx_decl_scope
*parent_scope
= NULL
;
665 if (!ctx
->current_scope
) {
669 parent_scope
= ctx
->current_scope
->parent_scope
;
670 ctx_decl_scope_destroy(ctx
->current_scope
);
671 ctx
->current_scope
= parent_scope
;
678 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
679 struct ctf_field_class
**decl
);
682 char *remove_underscores_from_field_ref(const char *field_ref
)
688 UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
,
689 UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
,
690 } state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
692 BT_ASSERT(field_ref
);
693 ret
= calloc(strlen(field_ref
) + 1, 1);
695 BT_LOGE("Failed to allocate a string: size=%zu",
696 strlen(field_ref
) + 1);
703 while (*in_ch
!= '\0') {
707 /* Remove whitespace */
711 if (state
== UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
) {
713 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
719 state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
722 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
737 int is_unary_string(struct bt_list_head
*head
)
740 struct ctf_node
*node
;
742 bt_list_for_each_entry(node
, head
, siblings
) {
743 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
747 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
756 char *concatenate_unary_strings(struct bt_list_head
*head
)
760 struct ctf_node
*node
;
762 str
= g_string_new(NULL
);
765 bt_list_for_each_entry(node
, head
, siblings
) {
769 node
->type
!= NODE_UNARY_EXPRESSION
||
770 node
->u
.unary_expression
.type
!= UNARY_STRING
||
773 node
->u
.unary_expression
.link
!=
781 switch (node
->u
.unary_expression
.link
) {
783 g_string_append(str
, ".");
785 case UNARY_ARROWLINK
:
786 g_string_append(str
, "->");
788 case UNARY_DOTDOTDOT
:
789 g_string_append(str
, "...");
795 src_string
= node
->u
.unary_expression
.u
.string
;
796 g_string_append(str
, src_string
);
800 /* Destroys the container, returns the underlying string */
801 return g_string_free(str
, FALSE
);
804 /* This always returns NULL */
805 return g_string_free(str
, TRUE
);
809 const char *get_map_clock_name_value(struct bt_list_head
*head
)
812 struct ctf_node
*node
;
813 const char *name
= NULL
;
815 bt_list_for_each_entry(node
, head
, siblings
) {
817 int uexpr_type
= node
->u
.unary_expression
.type
;
818 int uexpr_link
= node
->u
.unary_expression
.link
;
819 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
820 uexpr_type
!= UNARY_STRING
||
821 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
826 /* Needs to be chained with . */
827 switch (node
->u
.unary_expression
.link
) {
830 case UNARY_ARROWLINK
:
831 case UNARY_DOTDOTDOT
:
837 src_string
= node
->u
.unary_expression
.u
.string
;
841 if (strcmp("clock", src_string
)) {
849 if (strcmp("value", src_string
)) {
854 /* Extra identifier, unknown */
868 int is_unary_unsigned(struct bt_list_head
*head
)
871 struct ctf_node
*node
;
873 bt_list_for_each_entry(node
, head
, siblings
) {
874 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
878 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
887 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
891 struct ctf_node
*node
;
895 if (bt_list_empty(head
)) {
900 bt_list_for_each_entry(node
, head
, siblings
) {
901 int uexpr_type
= node
->u
.unary_expression
.type
;
902 int uexpr_link
= node
->u
.unary_expression
.link
;
903 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
904 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
905 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
907 _BT_LOGE_NODE(node
, "Invalid constant unsigned integer.");
912 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
921 int is_unary_signed(struct bt_list_head
*head
)
924 struct ctf_node
*node
;
926 bt_list_for_each_entry(node
, head
, siblings
) {
927 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
931 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
940 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
944 struct ctf_node
*node
;
946 bt_list_for_each_entry(node
, head
, siblings
) {
947 int uexpr_type
= node
->u
.unary_expression
.type
;
948 int uexpr_link
= node
->u
.unary_expression
.link
;
949 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
950 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
951 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
952 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
958 switch (uexpr_type
) {
959 case UNARY_UNSIGNED_CONSTANT
:
961 node
->u
.unary_expression
.u
.unsigned_constant
;
963 case UNARY_SIGNED_CONSTANT
:
964 *value
= node
->u
.unary_expression
.u
.signed_constant
;
979 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
983 struct ctf_node
*node
;
985 bt_list_for_each_entry(node
, head
, siblings
) {
986 int uexpr_type
= node
->u
.unary_expression
.type
;
987 int uexpr_link
= node
->u
.unary_expression
.link
;
988 const char *src_string
;
990 if (node
->type
!= NODE_UNARY_EXPRESSION
||
991 uexpr_type
!= UNARY_STRING
||
992 uexpr_link
!= UNARY_LINK_UNKNOWN
||
998 src_string
= node
->u
.unary_expression
.u
.string
;
999 ret
= bt_uuid_parse(src_string
, uuid
);
1002 "Cannot parse UUID: uuid=\"%s\"", src_string
);
1012 int get_boolean(struct ctf_node
*unary_expr
)
1016 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
1017 _BT_LOGE_NODE(unary_expr
,
1018 "Expecting unary expression: node-type=%d",
1024 switch (unary_expr
->u
.unary_expression
.type
) {
1025 case UNARY_UNSIGNED_CONSTANT
:
1026 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
1028 case UNARY_SIGNED_CONSTANT
:
1029 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
1033 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
1035 if (!strcmp(str
, "true") || !strcmp(str
, "TRUE")) {
1037 } else if (!strcmp(str
, "false") || !strcmp(str
, "FALSE")) {
1040 _BT_LOGE_NODE(unary_expr
,
1041 "Unexpected boolean value: value=\"%s\"", str
);
1048 _BT_LOGE_NODE(unary_expr
,
1049 "Unexpected unary expression type: node-type=%d",
1050 unary_expr
->u
.unary_expression
.type
);
1060 enum ctf_byte_order
byte_order_from_unary_expr(struct ctf_node
*unary_expr
)
1063 enum ctf_byte_order bo
= -1;
1065 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1066 _BT_LOGE_NODE(unary_expr
,
1067 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1071 str
= unary_expr
->u
.unary_expression
.u
.string
;
1073 if (!strcmp(str
, "be") || !strcmp(str
, "network")) {
1074 bo
= CTF_BYTE_ORDER_BIG
;
1075 } else if (!strcmp(str
, "le")) {
1076 bo
= CTF_BYTE_ORDER_LITTLE
;
1077 } else if (!strcmp(str
, "native")) {
1078 bo
= CTF_BYTE_ORDER_DEFAULT
;
1080 _BT_LOGE_NODE(unary_expr
,
1081 "Unexpected \"byte_order\" attribute value: "
1082 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1092 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1093 struct ctf_node
*uexpr
)
1095 enum ctf_byte_order bo
= byte_order_from_unary_expr(uexpr
);
1097 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
1098 bo
= ctx
->ctf_tc
->default_byte_order
;
1105 int is_align_valid(uint64_t align
)
1107 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
1111 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
1116 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1117 _BT_LOGE_NODE(cls_specifier
,
1118 "Unexpected node type: node-type=%d",
1119 cls_specifier
->type
);
1124 switch (cls_specifier
->u
.field_class_specifier
.type
) {
1126 g_string_append(str
, "void");
1129 g_string_append(str
, "char");
1131 case TYPESPEC_SHORT
:
1132 g_string_append(str
, "short");
1135 g_string_append(str
, "int");
1138 g_string_append(str
, "long");
1140 case TYPESPEC_FLOAT
:
1141 g_string_append(str
, "float");
1143 case TYPESPEC_DOUBLE
:
1144 g_string_append(str
, "double");
1146 case TYPESPEC_SIGNED
:
1147 g_string_append(str
, "signed");
1149 case TYPESPEC_UNSIGNED
:
1150 g_string_append(str
, "unsigned");
1153 g_string_append(str
, "bool");
1155 case TYPESPEC_COMPLEX
:
1156 g_string_append(str
, "_Complex");
1158 case TYPESPEC_IMAGINARY
:
1159 g_string_append(str
, "_Imaginary");
1161 case TYPESPEC_CONST
:
1162 g_string_append(str
, "const");
1164 case TYPESPEC_ID_TYPE
:
1165 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1166 g_string_append(str
,
1167 cls_specifier
->u
.field_class_specifier
.id_type
);
1170 case TYPESPEC_STRUCT
:
1172 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1174 if (!node
->u
._struct
.name
) {
1175 _BT_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1180 g_string_append(str
, "struct ");
1181 g_string_append(str
, node
->u
._struct
.name
);
1184 case TYPESPEC_VARIANT
:
1186 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1188 if (!node
->u
.variant
.name
) {
1189 _BT_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1194 g_string_append(str
, "variant ");
1195 g_string_append(str
, node
->u
.variant
.name
);
1200 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1202 if (!node
->u
._enum
.enum_id
) {
1204 "Unexpected empty enumeration field class (`enum`) name.");
1209 g_string_append(str
, "enum ");
1210 g_string_append(str
, node
->u
._enum
.enum_id
);
1213 case TYPESPEC_FLOATING_POINT
:
1214 case TYPESPEC_INTEGER
:
1215 case TYPESPEC_STRING
:
1217 _BT_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1218 "Unexpected field class specifier type: %d",
1219 cls_specifier
->u
.field_class_specifier
.type
);
1229 int get_class_specifier_list_name(struct ctx
*ctx
,
1230 struct ctf_node
*cls_specifier_list
, GString
*str
)
1233 struct ctf_node
*iter
;
1234 int alias_item_nr
= 0;
1235 struct bt_list_head
*head
=
1236 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1238 bt_list_for_each_entry(iter
, head
, siblings
) {
1239 if (alias_item_nr
!= 0) {
1240 g_string_append(str
, " ");
1244 ret
= get_class_specifier_name(ctx
, iter
, str
);
1255 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1256 struct ctf_node
*cls_specifier_list
,
1257 struct ctf_node
*node_field_class_declarator
)
1263 struct ctf_node
*iter
;
1264 struct bt_list_head
*pointers
=
1265 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1267 str
= g_string_new("");
1268 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1270 g_string_free(str
, TRUE
);
1274 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1275 g_string_append(str
, " *");
1277 if (iter
->u
.pointer
.const_qualifier
) {
1278 g_string_append(str
, " const");
1282 str_c
= g_string_free(str
, FALSE
);
1283 qalias
= g_quark_from_string(str_c
);
1291 int visit_field_class_declarator(struct ctx
*ctx
,
1292 struct ctf_node
*cls_specifier_list
,
1293 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1294 struct ctf_field_class
**field_decl
,
1295 struct ctf_field_class
*nested_decl
)
1298 * During this whole function, nested_decl is always OURS,
1299 * whereas field_decl is an output which we create, but
1300 * belongs to the caller (it is moved).
1305 /* Validate field class declarator node */
1306 if (node_field_class_declarator
) {
1307 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1309 _BT_LOGE_NODE(node_field_class_declarator
,
1310 "Unexpected field class declarator type: type=%d",
1311 node_field_class_declarator
->u
.field_class_declarator
.type
);
1316 /* TODO: GCC bitfields not supported yet */
1317 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1319 _BT_LOGE_NODE(node_field_class_declarator
,
1320 "GCC bitfields are not supported as of this version.");
1326 /* Find the right nested declaration if not provided */
1328 struct bt_list_head
*pointers
=
1329 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1331 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1335 * If we have a pointer declarator, it HAS to
1336 * be present in the field class aliases (else
1339 qalias
= create_class_alias_identifier(ctx
,
1340 cls_specifier_list
, node_field_class_declarator
);
1342 ctx_decl_scope_lookup_alias(ctx
->current_scope
,
1343 g_quark_to_string(qalias
), -1, true);
1345 _BT_LOGE_NODE(node_field_class_declarator
,
1346 "Cannot find class alias: name=\"%s\"",
1347 g_quark_to_string(qalias
));
1352 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1353 /* Pointer: force integer's base to 16 */
1354 struct ctf_field_class_int
*int_fc
=
1355 (void *) nested_decl
;
1358 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1361 ret
= visit_field_class_specifier_list(ctx
,
1362 cls_specifier_list
, &nested_decl
);
1364 BT_ASSERT(!nested_decl
);
1370 BT_ASSERT(nested_decl
);
1372 if (!node_field_class_declarator
) {
1373 *field_decl
= nested_decl
;
1378 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1379 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1381 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1387 *field_name
= g_quark_from_string(id
);
1392 *field_decl
= nested_decl
;
1396 struct ctf_node
*first
;
1397 struct ctf_field_class
*decl
= NULL
;
1398 struct ctf_field_class
*outer_field_decl
= NULL
;
1399 struct bt_list_head
*length
=
1400 &node_field_class_declarator
->
1401 u
.field_class_declarator
.u
.nested
.length
;
1403 /* Create array/sequence, pass nested_decl as child */
1404 if (bt_list_empty(length
)) {
1405 _BT_LOGE_NODE(node_field_class_declarator
,
1406 "Expecting length field reference or value.");
1411 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1412 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1413 _BT_LOGE_NODE(first
,
1414 "Unexpected node type: node-type=%d",
1420 switch (first
->u
.unary_expression
.type
) {
1421 case UNARY_UNSIGNED_CONSTANT
:
1423 struct ctf_field_class_array
*array_decl
= NULL
;
1425 array_decl
= ctf_field_class_array_create();
1426 BT_ASSERT(array_decl
);
1427 array_decl
->length
=
1428 first
->u
.unary_expression
.u
.unsigned_constant
;
1429 array_decl
->base
.elem_fc
= nested_decl
;
1431 decl
= (void *) array_decl
;
1436 /* Lookup unsigned integer definition, create seq. */
1437 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1438 char *length_name
= concatenate_unary_strings(length
);
1441 _BT_LOGE_NODE(node_field_class_declarator
,
1442 "Cannot concatenate unary strings.");
1447 if (strncmp(length_name
, "env.", 4) == 0) {
1448 /* This is, in fact, an array */
1449 const char *env_entry_name
= &length_name
[4];
1450 struct ctf_trace_class_env_entry
*env_entry
=
1451 ctf_trace_class_borrow_env_entry_by_name(
1452 ctx
->ctf_tc
, env_entry_name
);
1453 struct ctf_field_class_array
*array_decl
;
1456 _BT_LOGE_NODE(node_field_class_declarator
,
1457 "Cannot find environment entry: "
1458 "name=\"%s\"", env_entry_name
);
1463 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1464 _BT_LOGE_NODE(node_field_class_declarator
,
1465 "Wrong environment entry type "
1466 "(expecting integer): "
1467 "name=\"%s\"", env_entry_name
);
1472 if (env_entry
->value
.i
< 0) {
1473 _BT_LOGE_NODE(node_field_class_declarator
,
1474 "Invalid, negative array length: "
1475 "env-entry-name=\"%s\", "
1478 env_entry
->value
.i
);
1483 array_decl
= ctf_field_class_array_create();
1484 BT_ASSERT(array_decl
);
1485 array_decl
->length
=
1486 (uint64_t) env_entry
->value
.i
;
1487 array_decl
->base
.elem_fc
= nested_decl
;
1489 decl
= (void *) array_decl
;
1491 char *length_name_no_underscore
=
1492 remove_underscores_from_field_ref(
1494 if (!length_name_no_underscore
) {
1496 * remove_underscores_from_field_ref()
1502 seq_decl
= ctf_field_class_sequence_create();
1503 BT_ASSERT(seq_decl
);
1504 seq_decl
->base
.elem_fc
= nested_decl
;
1506 g_string_assign(seq_decl
->length_ref
,
1507 length_name_no_underscore
);
1508 free(length_name_no_underscore
);
1509 decl
= (void *) seq_decl
;
1512 g_free(length_name
);
1520 BT_ASSERT(!nested_decl
);
1522 BT_ASSERT(!*field_decl
);
1525 * At this point, we found the next nested declaration.
1526 * We currently own this (and lost the ownership of
1527 * nested_decl in the meantime). Pass this next
1528 * nested declaration as the content of the outer
1529 * container, MOVING its ownership.
1531 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1533 node_field_class_declarator
->
1534 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1535 &outer_field_decl
, decl
);
1538 BT_ASSERT(!outer_field_decl
);
1543 BT_ASSERT(outer_field_decl
);
1544 *field_decl
= outer_field_decl
;
1545 outer_field_decl
= NULL
;
1548 BT_ASSERT(*field_decl
);
1552 ctf_field_class_destroy(*field_decl
);
1560 ctf_field_class_destroy(nested_decl
);
1566 int visit_struct_decl_field(struct ctx
*ctx
,
1567 struct ctf_field_class_struct
*struct_decl
,
1568 struct ctf_node
*cls_specifier_list
,
1569 struct bt_list_head
*field_class_declarators
)
1572 struct ctf_node
*iter
;
1573 struct ctf_field_class
*field_decl
= NULL
;
1575 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1578 const char *field_name
;
1580 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1581 &qfield_name
, iter
, &field_decl
, NULL
);
1583 BT_ASSERT(!field_decl
);
1584 _BT_LOGE_NODE(cls_specifier_list
,
1585 "Cannot visit field class declarator: ret=%d", ret
);
1589 BT_ASSERT(field_decl
);
1590 field_name
= g_quark_to_string(qfield_name
);
1592 /* Check if field with same name already exists */
1593 if (ctf_field_class_struct_borrow_member_by_name(
1594 struct_decl
, field_name
)) {
1595 _BT_LOGE_NODE(cls_specifier_list
,
1596 "Duplicate field in structure field class: "
1597 "field-name=\"%s\"", field_name
);
1602 /* Add field to structure */
1603 ctf_field_class_struct_append_member(struct_decl
,
1604 field_name
, field_decl
);
1611 ctf_field_class_destroy(field_decl
);
1617 int visit_variant_decl_field(struct ctx
*ctx
,
1618 struct ctf_field_class_variant
*variant_decl
,
1619 struct ctf_node
*cls_specifier_list
,
1620 struct bt_list_head
*field_class_declarators
)
1623 struct ctf_node
*iter
;
1624 struct ctf_field_class
*field_decl
= NULL
;
1626 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1629 const char *field_name
;
1631 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1632 &qfield_name
, iter
, &field_decl
, NULL
);
1634 BT_ASSERT(!field_decl
);
1635 _BT_LOGE_NODE(cls_specifier_list
,
1636 "Cannot visit field class declarator: ret=%d", ret
);
1640 BT_ASSERT(field_decl
);
1641 field_name
= g_quark_to_string(qfield_name
);
1643 /* Check if field with same name already exists */
1644 if (ctf_field_class_variant_borrow_option_by_name(
1645 variant_decl
, field_name
)) {
1646 _BT_LOGE_NODE(cls_specifier_list
,
1647 "Duplicate field in variant field class: "
1648 "field-name=\"%s\"", field_name
);
1653 /* Add field to structure */
1654 ctf_field_class_variant_append_option(variant_decl
,
1655 field_name
, field_decl
);
1662 ctf_field_class_destroy(field_decl
);
1668 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1669 struct bt_list_head
*field_class_declarators
)
1673 struct ctf_node
*iter
;
1674 struct ctf_field_class
*class_decl
= NULL
;
1676 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1677 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1678 &qidentifier
, iter
, &class_decl
, NULL
);
1681 "Cannot visit field class declarator: ret=%d", ret
);
1686 /* Do not allow field class def and alias of untagged variants */
1687 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1688 struct ctf_field_class_variant
*var_fc
=
1689 (void *) class_decl
;
1691 if (var_fc
->tag_path
.path
->len
== 0) {
1693 "Type definition of untagged variant field class is not allowed.");
1699 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1700 g_quark_to_string(qidentifier
), class_decl
);
1703 "Cannot register field class alias: name=\"%s\"",
1704 g_quark_to_string(qidentifier
));
1710 ctf_field_class_destroy(class_decl
);
1716 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1717 struct ctf_node
*alias
)
1721 struct ctf_node
*node
;
1722 GQuark qdummy_field_name
;
1723 struct ctf_field_class
*class_decl
= NULL
;
1725 /* Create target field class */
1726 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1729 node
= _BT_LIST_FIRST_ENTRY(
1730 &target
->u
.field_class_alias_target
.field_class_declarators
,
1731 struct ctf_node
, siblings
);
1734 ret
= visit_field_class_declarator(ctx
,
1735 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1736 &qdummy_field_name
, node
, &class_decl
, NULL
);
1738 BT_ASSERT(!class_decl
);
1740 "Cannot visit field class declarator: ret=%d", ret
);
1744 /* Do not allow field class def and alias of untagged variants */
1745 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1746 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1748 if (var_fc
->tag_path
.path
->len
== 0) {
1749 _BT_LOGE_NODE(target
,
1750 "Type definition of untagged variant field class is not allowed.");
1757 * The semantic validator does not check whether the target is
1758 * abstract or not (if it has an identifier). Check it here.
1760 if (qdummy_field_name
!= 0) {
1761 _BT_LOGE_NODE(target
,
1762 "Expecting empty identifier: id=\"%s\"",
1763 g_quark_to_string(qdummy_field_name
));
1768 /* Create alias identifier */
1769 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1770 struct ctf_node
, siblings
);
1771 qalias
= create_class_alias_identifier(ctx
,
1772 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1773 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1774 g_quark_to_string(qalias
), class_decl
);
1777 "Cannot register class alias: name=\"%s\"",
1778 g_quark_to_string(qalias
));
1783 ctf_field_class_destroy(class_decl
);
1789 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1790 struct ctf_field_class_struct
*struct_decl
)
1794 switch (entry_node
->type
) {
1796 ret
= visit_field_class_def(ctx
,
1797 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1798 &entry_node
->u
.field_class_def
.field_class_declarators
);
1800 _BT_LOGE_NODE(entry_node
,
1801 "Cannot add field class found in structure field class: ret=%d",
1806 case NODE_TYPEALIAS
:
1807 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1808 entry_node
->u
.field_class_alias
.alias
);
1810 _BT_LOGE_NODE(entry_node
,
1811 "Cannot add field class alias found in structure field class: ret=%d",
1816 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1818 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1819 entry_node
->u
.struct_or_variant_declaration
.
1820 field_class_specifier_list
,
1821 &entry_node
->u
.struct_or_variant_declaration
.
1822 field_class_declarators
);
1828 _BT_LOGE_NODE(entry_node
,
1829 "Unexpected node type: node-type=%d", entry_node
->type
);
1839 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1840 struct ctf_field_class_variant
*variant_decl
)
1844 switch (entry_node
->type
) {
1846 ret
= visit_field_class_def(ctx
,
1847 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1848 &entry_node
->u
.field_class_def
.field_class_declarators
);
1850 _BT_LOGE_NODE(entry_node
,
1851 "Cannot add field class found in variant field class: ret=%d",
1856 case NODE_TYPEALIAS
:
1857 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1858 entry_node
->u
.field_class_alias
.alias
);
1860 _BT_LOGE_NODE(entry_node
,
1861 "Cannot add field class alias found in variant field class: ret=%d",
1866 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1868 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1869 entry_node
->u
.struct_or_variant_declaration
.
1870 field_class_specifier_list
,
1871 &entry_node
->u
.struct_or_variant_declaration
.
1872 field_class_declarators
);
1878 _BT_LOGE_NODE(entry_node
,
1879 "Unexpected node type: node-type=%d",
1890 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1891 struct bt_list_head
*decl_list
, int has_body
,
1892 struct bt_list_head
*min_align
,
1893 struct ctf_field_class_struct
**struct_decl
)
1897 BT_ASSERT(struct_decl
);
1898 *struct_decl
= NULL
;
1900 /* For named struct (without body), lookup in declaration scope */
1903 BT_LOGE_STR("Bodyless structure field class: missing name.");
1908 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1910 if (!*struct_decl
) {
1911 BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
1917 struct ctf_node
*entry_node
;
1918 uint64_t min_align_value
= 0;
1921 if (ctx_decl_scope_lookup_struct(
1922 ctx
->current_scope
, name
, 1, false)) {
1923 BT_LOGE("Structure field class already declared in local scope: "
1924 "name=\"struct %s\"", name
);
1930 if (!bt_list_empty(min_align
)) {
1931 ret
= get_unary_unsigned(min_align
, &min_align_value
);
1933 BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1939 *struct_decl
= ctf_field_class_struct_create();
1940 BT_ASSERT(*struct_decl
);
1942 if (min_align_value
!= 0) {
1943 (*struct_decl
)->base
.alignment
= min_align_value
;
1946 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1948 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1949 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1952 _BT_LOGE_NODE(entry_node
,
1953 "Cannot visit structure field class entry: "
1963 ret
= ctx_decl_scope_register_struct(ctx
->current_scope
,
1964 name
, *struct_decl
);
1966 BT_LOGE("Cannot register structure field class in declaration scope: "
1967 "name=\"struct %s\", ret=%d", name
, ret
);
1976 ctf_field_class_destroy((void *) *struct_decl
);
1977 *struct_decl
= NULL
;
1982 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1983 const char *tag
, struct bt_list_head
*decl_list
,
1984 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1987 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1989 BT_ASSERT(variant_decl
);
1990 *variant_decl
= NULL
;
1992 /* For named variant (without body), lookup in declaration scope */
1995 BT_LOGE_STR("Bodyless variant field class: missing name.");
2000 untagged_variant_decl
=
2001 ctx_decl_scope_lookup_variant(ctx
->current_scope
,
2003 if (!untagged_variant_decl
) {
2004 BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
2010 struct ctf_node
*entry_node
;
2013 if (ctx_decl_scope_lookup_variant(ctx
->current_scope
,
2015 BT_LOGE("Variant field class already declared in local scope: "
2016 "name=\"variant %s\"", name
);
2022 untagged_variant_decl
= ctf_field_class_variant_create();
2023 BT_ASSERT(untagged_variant_decl
);
2024 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
2026 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
2027 ret
= visit_variant_decl_entry(ctx
, entry_node
,
2028 untagged_variant_decl
);
2030 _BT_LOGE_NODE(entry_node
,
2031 "Cannot visit variant field class entry: "
2041 ret
= ctx_decl_scope_register_variant(
2042 ctx
->current_scope
, name
,
2043 untagged_variant_decl
);
2045 BT_LOGE("Cannot register variant field class in declaration scope: "
2046 "name=\"variant %s\", ret=%d", name
, ret
);
2053 * If tagged, create tagged variant and return; otherwise
2054 * return untagged variant.
2057 *variant_decl
= untagged_variant_decl
;
2058 untagged_variant_decl
= NULL
;
2061 * At this point, we have a fresh untagged variant; nobody
2062 * else owns it. Set its tag now.
2064 char *tag_no_underscore
=
2065 remove_underscores_from_field_ref(tag
);
2067 if (!tag_no_underscore
) {
2068 /* remove_underscores_from_field_ref() logs errors */
2072 g_string_assign(untagged_variant_decl
->tag_ref
,
2074 free(tag_no_underscore
);
2075 *variant_decl
= untagged_variant_decl
;
2076 untagged_variant_decl
= NULL
;
2079 BT_ASSERT(!untagged_variant_decl
);
2080 BT_ASSERT(*variant_decl
);
2084 ctf_field_class_destroy((void *) untagged_variant_decl
);
2085 untagged_variant_decl
= NULL
;
2086 ctf_field_class_destroy((void *) *variant_decl
);
2087 *variant_decl
= NULL
;
2100 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
2101 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
2105 struct ctf_node
*iter
;
2106 struct uori start
= {
2114 const char *label
= enumerator
->u
.enumerator
.id
;
2115 const char *effective_label
= label
;
2116 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2118 bt_list_for_each_entry(iter
, values
, siblings
) {
2119 struct uori
*target
;
2121 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2123 "Wrong expression for enumeration field class label: "
2124 "node-type=%d, label=\"%s\"", iter
->type
,
2136 switch (iter
->u
.unary_expression
.type
) {
2137 case UNARY_SIGNED_CONSTANT
:
2138 target
->is_signed
= true;
2140 iter
->u
.unary_expression
.u
.signed_constant
;
2142 case UNARY_UNSIGNED_CONSTANT
:
2143 target
->is_signed
= false;
2145 iter
->u
.unary_expression
.u
.unsigned_constant
;
2149 "Invalid enumeration field class entry: "
2150 "expecting constant signed or unsigned integer: "
2151 "node-type=%d, label=\"%s\"",
2152 iter
->u
.unary_expression
.type
, label
);
2159 "Invalid enumeration field class entry: label=\"%s\"",
2176 if (end
.is_signed
) {
2177 last
->value
.i
= end
.value
.i
+ 1;
2179 last
->value
.u
= end
.value
.u
+ 1;
2182 if (label
[0] == '_') {
2184 * Strip the first underscore of any enumeration field
2185 * class's label in case this enumeration FC is used as
2186 * a variant FC tag later. The variant FC choice names
2187 * could also start with `_`, in which case the prefix
2188 * is removed, and it the resulting choice name needs to
2191 effective_label
= &label
[1];
2194 ctf_field_class_enum_append_mapping(enum_decl
, effective_label
,
2195 start
.value
.u
, end
.value
.u
);
2203 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2204 struct ctf_node
*container_cls
,
2205 struct bt_list_head
*enumerator_list
,
2206 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2210 struct ctf_field_class_int
*integer_decl
= NULL
;
2212 BT_ASSERT(enum_decl
);
2215 /* For named enum (without body), lookup in declaration scope */
2218 BT_LOGE_STR("Bodyless enumeration field class: missing name.");
2223 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2226 BT_LOGE("Cannot find enumeration field class: "
2227 "name=\"enum %s\"", name
);
2232 struct ctf_node
*iter
;
2233 struct uori last_value
= {
2239 if (ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2241 BT_LOGE("Enumeration field class already declared in local scope: "
2242 "name=\"enum %s\"", name
);
2248 if (!container_cls
) {
2249 integer_decl
= (void *) ctx_decl_scope_lookup_alias(
2250 ctx
->current_scope
, "int", -1, true);
2251 if (!integer_decl
) {
2252 BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2257 ret
= visit_field_class_declarator(ctx
, container_cls
,
2258 &qdummy_id
, NULL
, (void *) &integer_decl
,
2261 BT_ASSERT(!integer_decl
);
2267 BT_ASSERT(integer_decl
);
2269 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2270 BT_LOGE("Container field class for enumeration field class is not an integer field class: "
2271 "fc-type=%d", integer_decl
->base
.base
.type
);
2276 *enum_decl
= ctf_field_class_enum_create();
2277 BT_ASSERT(*enum_decl
);
2278 (*enum_decl
)->base
.base
.base
.alignment
=
2279 integer_decl
->base
.base
.alignment
;
2280 ctf_field_class_int_copy_content((void *) *enum_decl
,
2281 (void *) integer_decl
);
2282 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2284 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2285 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2289 "Cannot visit enumeration field class entry: "
2296 ret
= ctx_decl_scope_register_enum(ctx
->current_scope
,
2299 BT_LOGE("Cannot register enumeration field class in declaration scope: "
2309 ctf_field_class_destroy((void *) *enum_decl
);
2313 ctf_field_class_destroy((void *) integer_decl
);
2314 integer_decl
= NULL
;
2319 int visit_field_class_specifier(struct ctx
*ctx
,
2320 struct ctf_node
*cls_specifier_list
,
2321 struct ctf_field_class
**decl
)
2324 GString
*str
= NULL
;
2327 str
= g_string_new("");
2328 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2330 _BT_LOGE_NODE(cls_specifier_list
,
2331 "Cannot get field class specifier list's name: ret=%d", ret
);
2335 *decl
= ctx_decl_scope_lookup_alias(ctx
->current_scope
, str
->str
, -1,
2338 _BT_LOGE_NODE(cls_specifier_list
,
2339 "Cannot find field class alias: name=\"%s\"", str
->str
);
2347 ctf_field_class_destroy(*decl
);
2352 g_string_free(str
, TRUE
);
2359 int visit_integer_decl(struct ctx
*ctx
,
2360 struct bt_list_head
*expressions
,
2361 struct ctf_field_class_int
**integer_decl
)
2366 struct ctf_node
*expression
;
2367 uint64_t alignment
= 0, size
= 0;
2368 struct bt_private_clock_class
*mapped_clock_class
= NULL
;
2369 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2370 enum bt_field_class_integer_preferred_display_base base
=
2371 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2372 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2374 *integer_decl
= NULL
;
2376 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2377 struct ctf_node
*left
, *right
;
2379 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2380 struct ctf_node
, siblings
);
2381 right
= _BT_LIST_FIRST_ENTRY(
2382 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2385 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2387 "Unexpected unary expression type: type=%d",
2388 left
->u
.unary_expression
.type
);
2393 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
2394 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2395 _BT_LOGE_DUP_ATTR(left
, "signed",
2396 "integer field class");
2401 signedness
= get_boolean(right
);
2402 if (signedness
< 0) {
2403 _BT_LOGE_NODE(right
,
2404 "Invalid boolean value for integer field class's `signed` attribute: "
2410 _SET(&set
, _INTEGER_SIGNED_SET
);
2411 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2413 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2414 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2415 "integer field class");
2420 byte_order
= get_real_byte_order(ctx
, right
);
2421 if (byte_order
== -1) {
2422 _BT_LOGE_NODE(right
,
2423 "Invalid `byte_order` attribute in integer field class: "
2429 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2430 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
2431 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2432 _BT_LOGE_DUP_ATTR(left
, "size",
2433 "integer field class");
2438 if (right
->u
.unary_expression
.type
!=
2439 UNARY_UNSIGNED_CONSTANT
) {
2440 _BT_LOGE_NODE(right
,
2441 "Invalid `size` attribute in integer field class: "
2442 "expecting unsigned constant integer: "
2444 right
->u
.unary_expression
.type
);
2449 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2451 _BT_LOGE_NODE(right
,
2452 "Invalid `size` attribute in integer field class: "
2453 "expecting positive constant integer: "
2454 "size=%" PRIu64
, size
);
2457 } else if (size
> 64) {
2458 _BT_LOGE_NODE(right
,
2459 "Invalid `size` attribute in integer field class: "
2460 "integer fields over 64 bits are not supported as of this version: "
2461 "size=%" PRIu64
, size
);
2466 _SET(&set
, _INTEGER_SIZE_SET
);
2467 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2469 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2470 _BT_LOGE_DUP_ATTR(left
, "align",
2471 "integer field class");
2476 if (right
->u
.unary_expression
.type
!=
2477 UNARY_UNSIGNED_CONSTANT
) {
2478 _BT_LOGE_NODE(right
,
2479 "Invalid `align` attribute in integer field class: "
2480 "expecting unsigned constant integer: "
2482 right
->u
.unary_expression
.type
);
2488 right
->u
.unary_expression
.u
.unsigned_constant
;
2489 if (!is_align_valid(alignment
)) {
2490 _BT_LOGE_NODE(right
,
2491 "Invalid `align` attribute in integer field class: "
2492 "expecting power of two: "
2493 "align=%" PRIu64
, alignment
);
2498 _SET(&set
, _INTEGER_ALIGN_SET
);
2499 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
2500 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2501 _BT_LOGE_DUP_ATTR(left
, "base",
2502 "integer field class");
2507 switch (right
->u
.unary_expression
.type
) {
2508 case UNARY_UNSIGNED_CONSTANT
:
2510 uint64_t constant
= right
->u
.unary_expression
.
2511 u
.unsigned_constant
;
2515 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2518 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2521 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2524 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2527 _BT_LOGE_NODE(right
,
2528 "Invalid `base` attribute in integer field class: "
2530 right
->u
.unary_expression
.u
.unsigned_constant
);
2538 char *s_right
= concatenate_unary_strings(
2539 &expression
->u
.ctf_expression
.right
);
2541 _BT_LOGE_NODE(right
,
2542 "Unexpected unary expression for integer field class's `base` attribute.");
2547 if (!strcmp(s_right
, "decimal") ||
2548 !strcmp(s_right
, "dec") ||
2549 !strcmp(s_right
, "d") ||
2550 !strcmp(s_right
, "i") ||
2551 !strcmp(s_right
, "u")) {
2552 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2553 } else if (!strcmp(s_right
, "hexadecimal") ||
2554 !strcmp(s_right
, "hex") ||
2555 !strcmp(s_right
, "x") ||
2556 !strcmp(s_right
, "X") ||
2557 !strcmp(s_right
, "p")) {
2558 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2559 } else if (!strcmp(s_right
, "octal") ||
2560 !strcmp(s_right
, "oct") ||
2561 !strcmp(s_right
, "o")) {
2562 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2563 } else if (!strcmp(s_right
, "binary") ||
2564 !strcmp(s_right
, "b")) {
2565 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2567 _BT_LOGE_NODE(right
,
2568 "Unexpected unary expression for integer field class's `base` attribute: "
2569 "base=\"%s\"", s_right
);
2579 _BT_LOGE_NODE(right
,
2580 "Invalid `base` attribute in integer field class: "
2581 "expecting unsigned constant integer or unary string.");
2586 _SET(&set
, _INTEGER_BASE_SET
);
2587 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2591 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2592 _BT_LOGE_DUP_ATTR(left
, "encoding",
2593 "integer field class");
2598 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2599 _BT_LOGE_NODE(right
,
2600 "Invalid `encoding` attribute in integer field class: "
2601 "expecting unary string.");
2606 s_right
= concatenate_unary_strings(
2607 &expression
->u
.ctf_expression
.right
);
2609 _BT_LOGE_NODE(right
,
2610 "Unexpected unary expression for integer field class's `encoding` attribute.");
2615 if (!strcmp(s_right
, "UTF8") ||
2616 !strcmp(s_right
, "utf8") ||
2617 !strcmp(s_right
, "utf-8") ||
2618 !strcmp(s_right
, "UTF-8") ||
2619 !strcmp(s_right
, "ASCII") ||
2620 !strcmp(s_right
, "ascii")) {
2621 encoding
= CTF_ENCODING_UTF8
;
2622 } else if (!strcmp(s_right
, "none")) {
2623 encoding
= CTF_ENCODING_NONE
;
2625 _BT_LOGE_NODE(right
,
2626 "Invalid `encoding` attribute in integer field class: "
2627 "unknown encoding: encoding=\"%s\"",
2635 _SET(&set
, _INTEGER_ENCODING_SET
);
2636 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
2637 const char *clock_name
;
2639 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2640 _BT_LOGE_DUP_ATTR(left
, "map",
2641 "integer field class");
2646 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2647 _BT_LOGE_NODE(right
,
2648 "Invalid `map` attribute in integer field class: "
2649 "expecting unary string.");
2655 get_map_clock_name_value(
2656 &expression
->u
.ctf_expression
.right
);
2658 char *s_right
= concatenate_unary_strings(
2659 &expression
->u
.ctf_expression
.right
);
2662 _BT_LOGE_NODE(right
,
2663 "Unexpected unary expression for integer field class's `map` attribute.");
2668 _BT_LOGE_NODE(right
,
2669 "Invalid `map` attribute in integer field class: "
2670 "cannot find clock class at this point: name=\"%s\"",
2672 _SET(&set
, _INTEGER_MAP_SET
);
2677 mapped_clock_class
=
2678 ctf_trace_class_borrow_clock_class_by_name(
2679 ctx
->ctf_tc
, clock_name
);
2680 if (!mapped_clock_class
) {
2681 _BT_LOGE_NODE(right
,
2682 "Invalid `map` attribute in integer field class: "
2683 "cannot find clock class at this point: name=\"%s\"",
2689 _SET(&set
, _INTEGER_MAP_SET
);
2692 "Unknown attribute in integer field class: "
2694 left
->u
.unary_expression
.u
.string
);
2698 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2699 BT_LOGE_STR("Missing `size` attribute in integer field class.");
2704 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2705 if (size
% CHAR_BIT
) {
2706 /* Bit-packed alignment */
2709 /* Byte-packed alignment */
2710 alignment
= CHAR_BIT
;
2714 *integer_decl
= ctf_field_class_int_create();
2715 BT_ASSERT(*integer_decl
);
2716 (*integer_decl
)->base
.base
.alignment
= alignment
;
2717 (*integer_decl
)->base
.byte_order
= byte_order
;
2718 (*integer_decl
)->base
.size
= size
;
2719 (*integer_decl
)->is_signed
= (signedness
> 0);
2720 (*integer_decl
)->disp_base
= base
;
2721 (*integer_decl
)->encoding
= encoding
;
2722 (*integer_decl
)->mapped_clock_class
= bt_object_get_ref(mapped_clock_class
);
2726 ctf_field_class_destroy((void *) *integer_decl
);
2727 *integer_decl
= NULL
;
2732 int visit_floating_point_number_decl(struct ctx
*ctx
,
2733 struct bt_list_head
*expressions
,
2734 struct ctf_field_class_float
**float_decl
)
2738 struct ctf_node
*expression
;
2739 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2740 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2744 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2745 struct ctf_node
*left
, *right
;
2747 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2748 struct ctf_node
, siblings
);
2749 right
= _BT_LIST_FIRST_ENTRY(
2750 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2753 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2755 "Unexpected unary expression type: type=%d",
2756 left
->u
.unary_expression
.type
);
2761 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
2762 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2763 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2764 "floating point number field class");
2769 byte_order
= get_real_byte_order(ctx
, right
);
2770 if (byte_order
== -1) {
2771 _BT_LOGE_NODE(right
,
2772 "Invalid `byte_order` attribute in floating point number field class: "
2778 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2779 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2781 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2782 _BT_LOGE_DUP_ATTR(left
, "exp_dig",
2783 "floating point number field class");
2788 if (right
->u
.unary_expression
.type
!=
2789 UNARY_UNSIGNED_CONSTANT
) {
2790 _BT_LOGE_NODE(right
,
2791 "Invalid `exp_dig` attribute in floating point number field class: "
2792 "expecting unsigned constant integer: "
2794 right
->u
.unary_expression
.type
);
2799 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2800 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2801 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2803 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2804 _BT_LOGE_DUP_ATTR(left
, "mant_dig",
2805 "floating point number field class");
2810 if (right
->u
.unary_expression
.type
!=
2811 UNARY_UNSIGNED_CONSTANT
) {
2812 _BT_LOGE_NODE(right
,
2813 "Invalid `mant_dig` attribute in floating point number field class: "
2814 "expecting unsigned constant integer: "
2816 right
->u
.unary_expression
.type
);
2821 mant_dig
= right
->u
.unary_expression
.u
.
2823 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2824 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2826 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2827 _BT_LOGE_DUP_ATTR(left
, "align",
2828 "floating point number field class");
2833 if (right
->u
.unary_expression
.type
!=
2834 UNARY_UNSIGNED_CONSTANT
) {
2835 _BT_LOGE_NODE(right
,
2836 "Invalid `align` attribute in floating point number field class: "
2837 "expecting unsigned constant integer: "
2839 right
->u
.unary_expression
.type
);
2844 alignment
= right
->u
.unary_expression
.u
.
2847 if (!is_align_valid(alignment
)) {
2848 _BT_LOGE_NODE(right
,
2849 "Invalid `align` attribute in floating point number field class: "
2850 "expecting power of two: "
2851 "align=%" PRIu64
, alignment
);
2856 _SET(&set
, _FLOAT_ALIGN_SET
);
2859 "Unknown attribute in floating point number field class: "
2861 left
->u
.unary_expression
.u
.string
);
2865 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2866 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2871 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2872 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2877 if (mant_dig
!= 24 && mant_dig
!= 53) {
2878 BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2883 if (mant_dig
== 24 && exp_dig
!= 8) {
2884 BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2889 if (mant_dig
== 53 && exp_dig
!= 11) {
2890 BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2895 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2896 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2897 /* Bit-packed alignment */
2900 /* Byte-packed alignment */
2901 alignment
= CHAR_BIT
;
2905 *float_decl
= ctf_field_class_float_create();
2906 BT_ASSERT(*float_decl
);
2907 (*float_decl
)->base
.base
.alignment
= alignment
;
2908 (*float_decl
)->base
.byte_order
= byte_order
;
2909 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2913 ctf_field_class_destroy((void *) *float_decl
);
2919 int visit_string_decl(struct ctx
*ctx
,
2920 struct bt_list_head
*expressions
,
2921 struct ctf_field_class_string
**string_decl
)
2925 struct ctf_node
*expression
;
2926 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2928 *string_decl
= NULL
;
2930 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2931 struct ctf_node
*left
, *right
;
2933 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2934 struct ctf_node
, siblings
);
2935 right
= _BT_LIST_FIRST_ENTRY(
2936 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2939 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2941 "Unexpected unary expression type: type=%d",
2942 left
->u
.unary_expression
.type
);
2947 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
2950 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2951 _BT_LOGE_DUP_ATTR(left
, "encoding",
2952 "string field class");
2957 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2958 _BT_LOGE_NODE(right
,
2959 "Invalid `encoding` attribute in string field class: "
2960 "expecting unary string.");
2965 s_right
= concatenate_unary_strings(
2966 &expression
->u
.ctf_expression
.right
);
2968 _BT_LOGE_NODE(right
,
2969 "Unexpected unary expression for string field class's `encoding` attribute.");
2974 if (!strcmp(s_right
, "UTF8") ||
2975 !strcmp(s_right
, "utf8") ||
2976 !strcmp(s_right
, "utf-8") ||
2977 !strcmp(s_right
, "UTF-8") ||
2978 !strcmp(s_right
, "ASCII") ||
2979 !strcmp(s_right
, "ascii")) {
2980 encoding
= CTF_ENCODING_UTF8
;
2981 } else if (!strcmp(s_right
, "none")) {
2982 encoding
= CTF_ENCODING_NONE
;
2984 _BT_LOGE_NODE(right
,
2985 "Invalid `encoding` attribute in string field class: "
2986 "unknown encoding: encoding=\"%s\"",
2994 _SET(&set
, _STRING_ENCODING_SET
);
2997 "Unknown attribute in string field class: "
2999 left
->u
.unary_expression
.u
.string
);
3003 *string_decl
= ctf_field_class_string_create();
3004 BT_ASSERT(*string_decl
);
3005 (*string_decl
)->encoding
= encoding
;
3009 ctf_field_class_destroy((void *) *string_decl
);
3010 *string_decl
= NULL
;
3015 int visit_field_class_specifier_list(struct ctx
*ctx
,
3016 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
3019 struct ctf_node
*first
, *node
;
3023 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
3024 _BT_LOGE_NODE(ts_list
,
3025 "Unexpected node type: node-type=%d", ts_list
->type
);
3030 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
3031 struct ctf_node
, siblings
);
3032 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
3033 _BT_LOGE_NODE(first
,
3034 "Unexpected node type: node-type=%d", first
->type
);
3039 node
= first
->u
.field_class_specifier
.node
;
3041 switch (first
->u
.field_class_specifier
.type
) {
3042 case TYPESPEC_INTEGER
:
3043 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
3050 case TYPESPEC_FLOATING_POINT
:
3051 ret
= visit_floating_point_number_decl(ctx
,
3052 &node
->u
.floating_point
.expressions
, (void *) decl
);
3058 case TYPESPEC_STRING
:
3059 ret
= visit_string_decl(ctx
,
3060 &node
->u
.string
.expressions
, (void *) decl
);
3066 case TYPESPEC_STRUCT
:
3067 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
3068 &node
->u
._struct
.declaration_list
,
3069 node
->u
._struct
.has_body
,
3070 &node
->u
._struct
.min_align
, (void *) decl
);
3076 case TYPESPEC_VARIANT
:
3077 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
3078 node
->u
.variant
.choice
,
3079 &node
->u
.variant
.declaration_list
,
3080 node
->u
.variant
.has_body
, (void *) decl
);
3087 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
3088 node
->u
._enum
.container_field_class
,
3089 &node
->u
._enum
.enumerator_list
,
3090 node
->u
._enum
.has_body
, (void *) decl
);
3098 case TYPESPEC_SHORT
:
3101 case TYPESPEC_FLOAT
:
3102 case TYPESPEC_DOUBLE
:
3103 case TYPESPEC_SIGNED
:
3104 case TYPESPEC_UNSIGNED
:
3106 case TYPESPEC_COMPLEX
:
3107 case TYPESPEC_IMAGINARY
:
3108 case TYPESPEC_CONST
:
3109 case TYPESPEC_ID_TYPE
:
3110 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
3112 _BT_LOGE_NODE(first
,
3113 "Cannot visit field class specifier: ret=%d",
3120 _BT_LOGE_NODE(first
,
3121 "Unexpected field class specifier type: node-type=%d",
3122 first
->u
.field_class_specifier
.type
);
3131 ctf_field_class_destroy((void *) *decl
);
3137 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3138 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
3144 switch (node
->type
) {
3146 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3147 &node
->u
.field_class_def
.field_class_declarators
);
3150 "Cannot add field class found in event class.");
3154 case NODE_TYPEALIAS
:
3155 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3156 node
->u
.field_class_alias
.alias
);
3159 "Cannot add field class alias found in event class.");
3163 case NODE_CTF_EXPRESSION
:
3165 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3167 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3172 if (!strcmp(left
, "name")) {
3173 /* This is already known at this stage */
3174 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3175 _BT_LOGE_DUP_ATTR(node
, "name", "event class");
3180 _SET(set
, _EVENT_NAME_SET
);
3181 } else if (!strcmp(left
, "id")) {
3184 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3185 _BT_LOGE_DUP_ATTR(node
, "id", "event class");
3190 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3192 /* Only read "id" if get_unary_unsigned() succeeded. */
3193 if (ret
|| (!ret
&& id
< 0)) {
3195 "Unexpected unary expression for event class's `id` attribute.");
3200 event_class
->id
= id
;
3201 _SET(set
, _EVENT_ID_SET
);
3202 } else if (!strcmp(left
, "stream_id")) {
3203 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3204 _BT_LOGE_DUP_ATTR(node
, "stream_id",
3210 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3214 * Only read "stream_id" if get_unary_unsigned()
3217 if (ret
|| (!ret
&& *stream_id
< 0)) {
3219 "Unexpected unary expression for event class's `stream_id` attribute.");
3224 _SET(set
, _EVENT_STREAM_ID_SET
);
3225 } else if (!strcmp(left
, "context")) {
3226 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3228 "Duplicate `context` entry in event class.");
3233 ret
= visit_field_class_specifier_list(ctx
,
3234 _BT_LIST_FIRST_ENTRY(
3235 &node
->u
.ctf_expression
.right
,
3236 struct ctf_node
, siblings
),
3237 &event_class
->spec_context_fc
);
3240 "Cannot create event class's context field class.");
3244 BT_ASSERT(event_class
->spec_context_fc
);
3245 _SET(set
, _EVENT_CONTEXT_SET
);
3246 } else if (!strcmp(left
, "fields")) {
3247 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3249 "Duplicate `fields` entry in event class.");
3254 ret
= visit_field_class_specifier_list(ctx
,
3255 _BT_LIST_FIRST_ENTRY(
3256 &node
->u
.ctf_expression
.right
,
3257 struct ctf_node
, siblings
),
3258 &event_class
->payload_fc
);
3261 "Cannot create event class's payload field class.");
3265 BT_ASSERT(event_class
->payload_fc
);
3266 _SET(set
, _EVENT_FIELDS_SET
);
3267 } else if (!strcmp(left
, "loglevel")) {
3268 uint64_t loglevel_value
;
3269 enum bt_event_class_log_level log_level
= -1;
3271 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3272 _BT_LOGE_DUP_ATTR(node
, "loglevel",
3278 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3282 "Unexpected unary expression for event class's `loglevel` attribute.");
3287 switch (loglevel_value
) {
3289 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3292 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3295 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3298 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3301 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3304 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3307 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3310 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3313 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3316 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3319 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3322 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3325 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3328 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3331 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3334 _BT_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3335 "log-level=%" PRIu64
, loglevel_value
);
3338 if (log_level
!= -1) {
3339 event_class
->log_level
= log_level
;
3342 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3343 } else if (!strcmp(left
, "model.emf.uri")) {
3346 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3347 _BT_LOGE_DUP_ATTR(node
, "model.emf.uri",
3353 right
= concatenate_unary_strings(
3354 &node
->u
.ctf_expression
.right
);
3357 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3362 if (strlen(right
) == 0) {
3364 "Not setting event class's EMF URI because it's empty.");
3366 g_string_assign(event_class
->emf_uri
,
3371 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3374 "Unknown attribute in event class: "
3375 "attr-name=\"%s\"", left
);
3399 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3403 struct ctf_node
*iter
;
3404 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3406 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3407 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3411 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3414 "Cannot concatenate unary strings.");
3418 if (!strcmp(left
, "name")) {
3419 name
= concatenate_unary_strings(
3420 &iter
->u
.ctf_expression
.right
);
3423 "Unexpected unary expression for event class's `name` attribute.");
3444 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3448 struct ctf_node
*iter
;
3449 uint64_t stream_id
= 0;
3450 char *event_name
= NULL
;
3451 struct ctf_event_class
*event_class
= NULL
;
3452 struct ctf_stream_class
*stream_class
= NULL
;
3453 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3454 bool pop_scope
= false;
3456 if (node
->visited
) {
3460 node
->visited
= TRUE
;
3461 event_name
= get_event_decl_name(ctx
, node
);
3464 "Missing `name` attribute in event class.");
3469 event_class
= ctf_event_class_create();
3470 BT_ASSERT(event_class
);
3471 g_string_assign(event_class
->name
, event_name
);
3472 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3475 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3476 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3479 _BT_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3485 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3487 * Allow missing stream_id if there is only a single
3490 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3492 /* Create implicit stream class if there's none */
3494 stream_class
= ctf_stream_class_create();
3495 BT_ASSERT(stream_class
);
3496 stream_class
->id
= stream_id
;
3497 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3499 stream_class
= stream_class
;
3502 /* Single stream class: get its ID */
3503 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3504 stream_id
= stream_class
->id
;
3508 "Missing `stream_id` attribute in event class.");
3514 /* We have the stream ID now; get the stream class if found */
3515 if (!stream_class
) {
3516 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3517 ctx
->ctf_tc
, stream_id
);
3518 if (!stream_class
) {
3520 "Cannot find stream class at this point: "
3521 "id=%" PRId64
, stream_id
);
3527 BT_ASSERT(stream_class
);
3529 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3530 /* Allow only one event without ID per stream */
3531 if (stream_class
->event_classes
->len
!= 0) {
3533 "Missing `id` attribute in event class.");
3539 event_class
->id
= 0;
3542 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3545 "Duplicate event class (same ID) in the same stream class: "
3546 "id=%" PRId64
, event_class
->id
);
3551 ctf_stream_class_append_event_class(stream_class
, event_class
);
3556 ctf_event_class_destroy(event_class
);
3576 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3577 struct ctf_field_class
*fc
)
3579 struct bt_private_clock_class
*clock_class_to_map_to
= NULL
;
3580 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3582 uint64_t clock_class_count
;
3588 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3589 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3593 if (int_fc
->mapped_clock_class
) {
3594 /* Already mapped */
3598 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3600 switch (clock_class_count
) {
3603 * No clock class exists in the trace at this point. Create an
3604 * implicit one at 1 GHz, named `default`, and use this clock
3607 clock_class_to_map_to
= bt_private_clock_class_create();
3608 BT_ASSERT(clock_class_to_map_to
);
3609 bt_private_clock_class_set_frequency(clock_class_to_map_to
,
3610 UINT64_C(1000000000));
3611 ret
= bt_private_clock_class_set_name(clock_class_to_map_to
,
3613 BT_ASSERT(ret
== 0);
3614 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3615 bt_object_get_ref(clock_class_to_map_to
));
3619 * Only one clock class exists in the trace at this point: use
3622 clock_class_to_map_to
=
3623 bt_object_get_ref(ctx
->ctf_tc
->clock_classes
->pdata
[0]);
3627 * Timestamp field not mapped to a clock class and there's more
3628 * than one clock class in the trace: this is an error.
3630 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3631 "but there's more than one clock class in the trace at this point.");
3636 BT_ASSERT(clock_class_to_map_to
);
3637 int_fc
->mapped_clock_class
= bt_object_get_ref(clock_class_to_map_to
);
3640 bt_object_put_ref(clock_class_to_map_to
);
3645 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3646 struct ctf_field_class
*root_fc
, const char *field_name
)
3650 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3651 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3657 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3658 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3662 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3663 count
= struct_fc
->members
->len
;
3665 count
= var_fc
->options
->len
;
3668 for (i
= 0; i
< count
; i
++) {
3669 struct ctf_named_field_class
*named_fc
= NULL
;
3671 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3672 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3674 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3675 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3679 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3680 ret
= auto_map_field_to_trace_clock_class(ctx
,
3683 BT_LOGE("Cannot automatically map field to trace's clock class: "
3684 "field-name=\"%s\"", field_name
);
3689 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3692 BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3693 "field-name=\"%s\", root-field-name=\"%s\"",
3694 field_name
, named_fc
->name
->str
);
3704 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3705 struct ctf_stream_class
*stream_class
, int *set
)
3710 switch (node
->type
) {
3712 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3713 &node
->u
.field_class_def
.field_class_declarators
);
3716 "Cannot add field class found in stream class.");
3720 case NODE_TYPEALIAS
:
3721 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3722 node
->u
.field_class_alias
.alias
);
3725 "Cannot add field class alias found in stream class.");
3729 case NODE_CTF_EXPRESSION
:
3731 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3733 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3738 if (!strcmp(left
, "id")) {
3741 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3742 _BT_LOGE_DUP_ATTR(node
, "id",
3743 "stream declaration");
3748 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3751 /* Only read "id" if get_unary_unsigned() succeeded. */
3752 if (ret
|| (!ret
&& id
< 0)) {
3754 "Unexpected unary expression for stream class's `id` attribute.");
3759 if (ctf_trace_class_borrow_stream_class_by_id(
3762 "Duplicate stream class (same ID): id=%" PRId64
,
3768 stream_class
->id
= id
;
3769 _SET(set
, _STREAM_ID_SET
);
3770 } else if (!strcmp(left
, "event.header")) {
3771 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3773 "Duplicate `event.header` entry in stream class.");
3778 ret
= visit_field_class_specifier_list(ctx
,
3779 _BT_LIST_FIRST_ENTRY(
3780 &node
->u
.ctf_expression
.right
,
3781 struct ctf_node
, siblings
),
3782 &stream_class
->event_header_fc
);
3785 "Cannot create stream class's event header field class.");
3789 BT_ASSERT(stream_class
->event_header_fc
);
3790 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3791 stream_class
->event_header_fc
, "timestamp");
3794 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3798 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3799 } else if (!strcmp(left
, "event.context")) {
3800 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3802 "Duplicate `event.context` entry in stream class.");
3807 ret
= visit_field_class_specifier_list(ctx
,
3808 _BT_LIST_FIRST_ENTRY(
3809 &node
->u
.ctf_expression
.right
,
3810 struct ctf_node
, siblings
),
3811 &stream_class
->event_common_context_fc
);
3814 "Cannot create stream class's event context field class.");
3818 BT_ASSERT(stream_class
->event_common_context_fc
);
3819 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3820 } else if (!strcmp(left
, "packet.context")) {
3821 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3823 "Duplicate `packet.context` entry in stream class.");
3828 ret
= visit_field_class_specifier_list(ctx
,
3829 _BT_LIST_FIRST_ENTRY(
3830 &node
->u
.ctf_expression
.right
,
3831 struct ctf_node
, siblings
),
3832 &stream_class
->packet_context_fc
);
3835 "Cannot create stream class's packet context field class.");
3839 BT_ASSERT(stream_class
->packet_context_fc
);
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_begin` to trace's clock class.");
3849 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3850 stream_class
->packet_context_fc
,
3854 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3858 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3861 "Unknown attribute in stream class: "
3862 "attr-name=\"%s\"", left
);
3883 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3887 struct ctf_node
*iter
;
3888 struct ctf_stream_class
*stream_class
= NULL
;
3889 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3891 if (node
->visited
) {
3895 node
->visited
= TRUE
;
3896 stream_class
= ctf_stream_class_create();
3897 BT_ASSERT(stream_class
);
3898 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3900 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3901 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3904 "Cannot visit stream class's entry: "
3913 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3914 /* Check that packet header has `stream_id` field */
3915 struct ctf_named_field_class
*named_fc
= NULL
;
3917 if (!ctx
->ctf_tc
->packet_header_fc
) {
3919 "Stream class has a `id` attribute, "
3920 "but trace has no packet header field class.");
3924 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3925 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3928 "Stream class has a `id` attribute, "
3929 "but trace's packet header field class has no `stream_id` field.");
3933 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3934 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3936 "Stream class has a `id` attribute, "
3937 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3941 /* Allow only _one_ ID-less stream */
3942 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3944 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3949 /* Automatic ID: 0 */
3950 stream_class
->id
= 0;
3954 * Make sure that this stream class's ID is currently unique in
3957 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3958 stream_class
->id
)) {
3960 "Duplicate stream class (same ID): id=%" PRId64
,
3966 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3967 stream_class
= NULL
;
3971 ctf_stream_class_destroy(stream_class
);
3972 stream_class
= NULL
;
3979 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3985 switch (node
->type
) {
3987 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3988 &node
->u
.field_class_def
.field_class_declarators
);
3991 "Cannot add field class found in trace (`trace` block).");
3995 case NODE_TYPEALIAS
:
3996 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3997 node
->u
.field_class_alias
.alias
);
4000 "Cannot add field class alias found in trace (`trace` block).");
4004 case NODE_CTF_EXPRESSION
:
4006 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
4008 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
4013 if (!strcmp(left
, "major")) {
4014 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
4015 _BT_LOGE_DUP_ATTR(node
, "major", "trace");
4020 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4024 "Unexpected unary expression for trace's `major` attribute.");
4031 "Invalid trace's `minor` attribute: expecting 1.");
4035 ctx
->ctf_tc
->major
= val
;
4036 _SET(set
, _TRACE_MAJOR_SET
);
4037 } else if (!strcmp(left
, "minor")) {
4038 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
4039 _BT_LOGE_DUP_ATTR(node
, "minor", "trace");
4044 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4048 "Unexpected unary expression for trace's `minor` attribute.");
4055 "Invalid trace's `minor` attribute: expecting 8.");
4059 ctx
->ctf_tc
->minor
= val
;
4060 _SET(set
, _TRACE_MINOR_SET
);
4061 } else if (!strcmp(left
, "uuid")) {
4062 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
4063 _BT_LOGE_DUP_ATTR(node
, "uuid", "trace");
4068 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
,
4072 "Invalid trace's `uuid` attribute.");
4076 ctx
->ctf_tc
->is_uuid_set
= true;
4077 _SET(set
, _TRACE_UUID_SET
);
4078 } else if (!strcmp(left
, "byte_order")) {
4079 /* Default byte order is already known at this stage */
4080 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
4081 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4087 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= -1);
4088 _SET(set
, _TRACE_BYTE_ORDER_SET
);
4089 } else if (!strcmp(left
, "packet.header")) {
4090 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
4092 "Duplicate `packet.header` entry in trace.");
4097 ret
= visit_field_class_specifier_list(ctx
,
4098 _BT_LIST_FIRST_ENTRY(
4099 &node
->u
.ctf_expression
.right
,
4100 struct ctf_node
, siblings
),
4101 &ctx
->ctf_tc
->packet_header_fc
);
4104 "Cannot create trace's packet header field class.");
4108 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
4109 _SET(set
, _TRACE_PACKET_HEADER_SET
);
4112 "Unknown attribute in stream class: "
4113 "attr-name=\"%s\"", left
);
4121 _BT_LOGE_NODE(node
, "Unknown expression in trace.");
4134 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
4138 struct ctf_node
*iter
;
4139 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
4141 if (node
->visited
) {
4145 node
->visited
= TRUE
;
4147 if (ctx
->is_trace_visited
) {
4148 _BT_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
4153 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4155 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
4156 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
4158 _BT_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
4167 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
4169 "Missing `major` attribute in trace (`trace` block).");
4174 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
4176 "Missing `minor` attribute in trace (`trace` block).");
4181 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4183 "Missing `byte_order` attribute in trace (`trace` block).");
4188 ctx
->is_trace_visited
= true;
4198 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4202 struct ctf_node
*entry_node
;
4203 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4205 if (node
->visited
) {
4209 node
->visited
= TRUE
;
4211 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4212 struct bt_list_head
*right_head
=
4213 &entry_node
->u
.ctf_expression
.right
;
4215 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4216 _BT_LOGE_NODE(entry_node
,
4217 "Wrong expression in environment entry: "
4218 "node-type=%d", entry_node
->type
);
4223 left
= concatenate_unary_strings(
4224 &entry_node
->u
.ctf_expression
.left
);
4226 _BT_LOGE_NODE(entry_node
,
4227 "Cannot get environment entry's name.");
4232 if (is_unary_string(right_head
)) {
4233 char *right
= concatenate_unary_strings(right_head
);
4236 _BT_LOGE_NODE(entry_node
,
4237 "Unexpected unary expression for environment entry's value: "
4238 "name=\"%s\"", left
);
4243 if (strcmp(left
, "tracer_name") == 0) {
4244 if (strncmp(right
, "lttng", 5) == 0) {
4245 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4246 "tracer-name=\"%s\"",
4248 ctx
->is_lttng
= true;
4252 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4253 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4256 } else if (is_unary_unsigned(right_head
) ||
4257 is_unary_signed(right_head
)) {
4260 if (is_unary_unsigned(right_head
)) {
4261 ret
= get_unary_unsigned(right_head
,
4264 ret
= get_unary_signed(right_head
, &v
);
4267 _BT_LOGE_NODE(entry_node
,
4268 "Unexpected unary expression for environment entry's value: "
4269 "name=\"%s\"", left
);
4274 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4275 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4278 _BT_LOGW_NODE(entry_node
,
4279 "Environment entry has unknown type: "
4280 "name=\"%s\"", left
);
4296 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4301 struct ctf_node
*node
;
4302 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4304 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4305 if (node
->type
== NODE_CTF_EXPRESSION
) {
4306 struct ctf_node
*right_node
;
4308 left
= concatenate_unary_strings(
4309 &node
->u
.ctf_expression
.left
);
4312 "Cannot concatenate unary strings.");
4317 if (!strcmp(left
, "byte_order")) {
4318 enum ctf_byte_order bo
;
4320 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4321 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4327 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4328 right_node
= _BT_LIST_FIRST_ENTRY(
4329 &node
->u
.ctf_expression
.right
,
4330 struct ctf_node
, siblings
);
4331 bo
= byte_order_from_unary_expr(right_node
);
4334 "Invalid `byte_order` attribute in trace (`trace` block): "
4335 "expecting `le`, `be`, or `network`.");
4338 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4340 "Invalid `byte_order` attribute in trace (`trace` block): "
4341 "cannot be set to `native` here.");
4346 ctx
->ctf_tc
->default_byte_order
= bo
;
4354 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4355 _BT_LOGE_NODE(trace_node
,
4356 "Missing `byte_order` attribute in trace (`trace` block).");
4369 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4370 struct bt_private_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4371 uint64_t *offset_cycles
)
4376 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4377 _BT_LOGE_NODE(entry_node
,
4378 "Unexpected node type: node-type=%d",
4384 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4386 _BT_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4391 if (!strcmp(left
, "name")) {
4394 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4395 _BT_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4400 right
= concatenate_unary_strings(
4401 &entry_node
->u
.ctf_expression
.right
);
4403 _BT_LOGE_NODE(entry_node
,
4404 "Unexpected unary expression for clock class's `name` attribute.");
4409 ret
= bt_private_clock_class_set_name(clock
, right
);
4411 _BT_LOGE_NODE(entry_node
,
4412 "cannot set clock class's name");
4418 _SET(set
, _CLOCK_NAME_SET
);
4419 } else if (!strcmp(left
, "uuid")) {
4420 uint8_t uuid
[BABELTRACE_UUID_LEN
];
4422 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4423 _BT_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4428 ret
= get_unary_uuid(&entry_node
->u
.ctf_expression
.right
, uuid
);
4430 _BT_LOGE_NODE(entry_node
,
4431 "Invalid clock class's `uuid` attribute.");
4435 bt_private_clock_class_set_uuid(clock
, uuid
);
4436 _SET(set
, _CLOCK_UUID_SET
);
4437 } else if (!strcmp(left
, "description")) {
4440 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4441 _BT_LOGE_DUP_ATTR(entry_node
, "description",
4447 right
= concatenate_unary_strings(
4448 &entry_node
->u
.ctf_expression
.right
);
4450 _BT_LOGE_NODE(entry_node
,
4451 "Unexpected unary expression for clock class's `description` attribute.");
4456 ret
= bt_private_clock_class_set_description(clock
, right
);
4458 _BT_LOGE_NODE(entry_node
,
4459 "Cannot set clock class's description.");
4465 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4466 } else if (!strcmp(left
, "freq")) {
4467 uint64_t freq
= UINT64_C(-1);
4469 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4470 _BT_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4475 ret
= get_unary_unsigned(
4476 &entry_node
->u
.ctf_expression
.right
, &freq
);
4478 _BT_LOGE_NODE(entry_node
,
4479 "Unexpected unary expression for clock class's `freq` attribute.");
4484 if (freq
== UINT64_C(-1) || freq
== 0) {
4485 _BT_LOGE_NODE(entry_node
,
4486 "Invalid clock class frequency: freq=%" PRIu64
,
4492 bt_private_clock_class_set_frequency(clock
, freq
);
4493 _SET(set
, _CLOCK_FREQ_SET
);
4494 } else if (!strcmp(left
, "precision")) {
4497 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4498 _BT_LOGE_DUP_ATTR(entry_node
, "precision",
4504 ret
= get_unary_unsigned(
4505 &entry_node
->u
.ctf_expression
.right
, &precision
);
4507 _BT_LOGE_NODE(entry_node
,
4508 "Unexpected unary expression for clock class's `precision` attribute.");
4513 bt_private_clock_class_set_precision(clock
, precision
);
4514 _SET(set
, _CLOCK_PRECISION_SET
);
4515 } else if (!strcmp(left
, "offset_s")) {
4516 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4517 _BT_LOGE_DUP_ATTR(entry_node
, "offset_s",
4523 ret
= get_unary_signed(
4524 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4526 _BT_LOGE_NODE(entry_node
,
4527 "Unexpected unary expression for clock class's `offset_s` attribute.");
4532 _SET(set
, _CLOCK_OFFSET_S_SET
);
4533 } else if (!strcmp(left
, "offset")) {
4534 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4535 _BT_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4540 ret
= get_unary_unsigned(
4541 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4543 _BT_LOGE_NODE(entry_node
,
4544 "Unexpected unary expression for clock class's `offset` attribute.");
4549 _SET(set
, _CLOCK_OFFSET_SET
);
4550 } else if (!strcmp(left
, "absolute")) {
4551 struct ctf_node
*right
;
4553 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4554 _BT_LOGE_DUP_ATTR(entry_node
, "absolute",
4560 right
= _BT_LIST_FIRST_ENTRY(
4561 &entry_node
->u
.ctf_expression
.right
,
4562 struct ctf_node
, siblings
);
4563 ret
= get_boolean(right
);
4565 _BT_LOGE_NODE(entry_node
,
4566 "Unexpected unary expression for clock class's `absolute` attribute.");
4571 bt_private_clock_class_set_is_absolute(clock
, ret
);
4572 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4574 _BT_LOGW_NODE(entry_node
,
4575 "Unknown attribute in clock class: attr-name=\"%s\"",
4589 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4594 if (frequency
== UINT64_C(1000000000)) {
4597 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4604 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4605 uint64_t *offset_cycles
, uint64_t freq
)
4607 if (*offset_cycles
>= freq
) {
4608 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4610 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4611 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4616 void apply_clock_class_offset(struct ctx
*ctx
,
4617 struct bt_private_clock_class
*clock
)
4620 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4621 uint64_t offset_ns_to_apply
;
4622 int64_t cur_offset_s
;
4623 uint64_t cur_offset_cycles
;
4625 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4626 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4630 /* Transfer nanoseconds to seconds as much as possible */
4631 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4632 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4633 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4634 const int64_t extra_s
= -abs_extra_s
;
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
;
4642 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4643 INT64_C(1000000000);
4644 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4645 (extra_s
* INT64_C(1000000000));
4647 BT_ASSERT(offset_ns
>= 0);
4648 offset_ns_to_apply
= (uint64_t) offset_ns
;
4649 offset_s_to_apply
+= extra_s
;
4652 freq
= bt_clock_class_get_frequency(
4653 bt_private_clock_class_as_clock_class(clock
));
4654 bt_clock_class_get_offset(bt_private_clock_class_as_clock_class(clock
),
4655 &cur_offset_s
, &cur_offset_cycles
);
4658 cur_offset_s
+= offset_s_to_apply
;
4659 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4662 * Recalibrate offsets because the part in cycles can be greater
4663 * than the frequency at this point.
4665 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4667 /* Set final offsets */
4668 bt_private_clock_class_set_offset(clock
, cur_offset_s
, cur_offset_cycles
);
4675 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4679 struct bt_private_clock_class
*clock
;
4680 struct ctf_node
*entry_node
;
4681 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4682 const char *clock_class_name
;
4683 int64_t offset_seconds
= 0;
4684 uint64_t offset_cycles
= 0;
4687 if (clock_node
->visited
) {
4691 clock_node
->visited
= TRUE
;
4693 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4694 clock
= bt_private_clock_class_create();
4696 _BT_LOGE_NODE(clock_node
,
4697 "Cannot create default clock class.");
4702 /* CTF: not absolute by default */
4703 bt_private_clock_class_set_is_absolute(clock
, BT_FALSE
);
4705 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4706 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4707 &offset_seconds
, &offset_cycles
);
4709 _BT_LOGE_NODE(entry_node
,
4710 "Cannot visit clock class's entry: ret=%d",
4716 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4717 _BT_LOGE_NODE(clock_node
,
4718 "Missing `name` attribute in clock class.");
4723 clock_class_name
= bt_clock_class_get_name(
4724 bt_private_clock_class_as_clock_class(clock
));
4725 BT_ASSERT(clock_class_name
);
4726 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4728 * Old versions of LTTng forgot to set its clock class
4729 * as absolute, even if it is. This is important because
4730 * it's a condition to be able to sort notifications
4731 * from different sources.
4733 bt_private_clock_class_set_is_absolute(clock
, BT_TRUE
);
4737 * Adjust offsets so that the part in cycles is less than the
4738 * frequency (move to the part in seconds).
4740 freq
= bt_clock_class_get_frequency(
4741 bt_private_clock_class_as_clock_class(clock
));
4742 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4743 BT_ASSERT(offset_cycles
< bt_clock_class_get_frequency(
4744 bt_private_clock_class_as_clock_class(clock
)));
4745 bt_private_clock_class_set_offset(clock
, offset_seconds
, offset_cycles
);
4746 apply_clock_class_offset(ctx
, clock
);
4747 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, bt_object_get_ref(clock
));
4750 BT_OBJECT_PUT_REF_AND_RESET(clock
);
4755 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4759 if (root_decl_node
->visited
) {
4763 root_decl_node
->visited
= TRUE
;
4765 switch (root_decl_node
->type
) {
4767 ret
= visit_field_class_def(ctx
,
4768 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4769 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4771 _BT_LOGE_NODE(root_decl_node
,
4772 "Cannot add field class found in root scope.");
4776 case NODE_TYPEALIAS
:
4777 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4778 root_decl_node
->u
.field_class_alias
.alias
);
4780 _BT_LOGE_NODE(root_decl_node
,
4781 "Cannot add field class alias found in root scope.");
4785 case NODE_TYPE_SPECIFIER_LIST
:
4787 struct ctf_field_class
*decl
= NULL
;
4790 * Just add the field class specifier to the root
4791 * declaration scope. Put local reference.
4793 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4795 _BT_LOGE_NODE(root_decl_node
,
4796 "Cannot visit root scope's field class: "
4802 ctf_field_class_destroy(decl
);
4807 _BT_LOGE_NODE(root_decl_node
,
4808 "Unexpected node type: node-type=%d",
4809 root_decl_node
->type
);
4819 int try_set_trace_class_name(struct ctx
*ctx
)
4821 GString
*name
= NULL
;
4823 struct ctf_trace_class_env_entry
*env_entry
;
4825 if (ctx
->ctf_tc
->name
->len
> 0) {
4830 name
= g_string_new(NULL
);
4832 BT_LOGE_STR("Failed to allocate a GString.");
4838 * Check if we have a trace environment string value named `hostname`.
4839 * If so, use it as the trace name's prefix.
4841 env_entry
= ctf_trace_class_borrow_env_entry_by_name(ctx
->ctf_tc
,
4844 env_entry
->type
== CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
) {
4845 g_string_append(name
, env_entry
->value
.str
->str
);
4847 if (ctx
->trace_class_name_suffix
) {
4848 g_string_append_c(name
, G_DIR_SEPARATOR
);
4852 if (ctx
->trace_class_name_suffix
) {
4853 g_string_append(name
, ctx
->trace_class_name_suffix
);
4856 g_string_assign(ctx
->ctf_tc
->name
, name
->str
);
4861 g_string_free(name
, TRUE
);
4868 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4869 const struct ctf_metadata_decoder_config
*decoder_config
,
4872 struct ctx
*ctx
= NULL
;
4874 /* Create visitor's context */
4875 ctx
= ctx_create(decoder_config
, name
);
4877 BT_LOGE_STR("Cannot create visitor's context.");
4888 return (void *) ctx
;
4892 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4894 ctx_destroy((void *) visitor
);
4898 struct bt_private_trace
*ctf_visitor_generate_ir_get_ir_trace(
4899 struct ctf_visitor_generate_ir
*visitor
)
4901 struct ctx
*ctx
= (void *) visitor
;
4904 BT_ASSERT(ctx
->trace
);
4905 return bt_object_get_ref(ctx
->trace
);
4909 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4910 struct ctf_visitor_generate_ir
*visitor
)
4912 struct ctx
*ctx
= (void *) visitor
;
4915 BT_ASSERT(ctx
->ctf_tc
);
4920 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4921 struct ctf_node
*node
)
4924 struct ctx
*ctx
= (void *) visitor
;
4926 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4928 switch (node
->type
) {
4931 struct ctf_node
*iter
;
4932 bool got_trace_decl
= false;
4935 * The first thing we need is the native byte order of
4936 * the trace block, because early class aliases can have
4937 * a `byte_order` attribute set to `native`. If we don't
4938 * have the native byte order yet, and we don't have any
4939 * trace block yet, then fail with EINCOMPLETE.
4941 if (ctx
->ctf_tc
->default_byte_order
== -1) {
4942 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4943 if (got_trace_decl
) {
4945 "Duplicate trace (`trace` block).");
4950 ret
= set_trace_byte_order(ctx
, iter
);
4953 "Cannot set trace's native byte order: "
4958 got_trace_decl
= true;
4961 if (!got_trace_decl
) {
4962 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4968 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4969 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4970 BT_ASSERT(ctx
->current_scope
&&
4971 ctx
->current_scope
->parent_scope
== NULL
);
4974 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4975 ret
= visit_env(ctx
, iter
);
4978 "Cannot visit trace's environment (`env` block) entry: "
4984 BT_ASSERT(ctx
->current_scope
&&
4985 ctx
->current_scope
->parent_scope
== NULL
);
4988 * Visit clock blocks.
4990 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4991 ret
= visit_clock_decl(ctx
, iter
);
4994 "Cannot visit clock class: ret=%d",
5000 BT_ASSERT(ctx
->current_scope
&&
5001 ctx
->current_scope
->parent_scope
== NULL
);
5004 * Visit root declarations next, as they can be used by any
5007 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
5009 ret
= visit_root_decl(ctx
, iter
);
5012 "Cannot visit root entry: ret=%d",
5018 BT_ASSERT(ctx
->current_scope
&&
5019 ctx
->current_scope
->parent_scope
== NULL
);
5021 /* Callsite blocks are not supported */
5022 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
5024 "\"callsite\" blocks are not supported as of this version.");
5027 BT_ASSERT(ctx
->current_scope
&&
5028 ctx
->current_scope
->parent_scope
== NULL
);
5031 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
5032 ret
= visit_trace_decl(ctx
, iter
);
5035 "Cannot visit trace (`trace` block): "
5041 BT_ASSERT(ctx
->current_scope
&&
5042 ctx
->current_scope
->parent_scope
== NULL
);
5045 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
5046 ret
= visit_stream_decl(ctx
, iter
);
5049 "Cannot visit stream class: ret=%d",
5055 BT_ASSERT(ctx
->current_scope
&&
5056 ctx
->current_scope
->parent_scope
== NULL
);
5059 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
5060 ret
= visit_event_decl(ctx
, iter
);
5063 "Cannot visit event class: ret=%d",
5069 BT_ASSERT(ctx
->current_scope
&&
5070 ctx
->current_scope
->parent_scope
== NULL
);
5075 "Unexpected node type: node-type=%d",
5081 /* Update default clock classes */
5082 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
);
5088 /* Set trace's name, if not already done */
5089 ret
= try_set_trace_class_name(ctx
);
5095 /* Update trace class meanings */
5096 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
5102 /* Update text arrays and sequences */
5103 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
5109 /* Resolve sequence lengths and variant tags */
5110 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
);
5116 /* Update "in IR" for field classes */
5117 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
5123 /* Update saved value indexes */
5124 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
5130 /* Validate what we have so far */
5131 ret
= ctf_trace_class_validate(ctx
->ctf_tc
);
5137 /* Copy new CTF metadata -> new IR metadata */
5138 ret
= ctf_trace_class_translate(ctx
->trace
, ctx
->ctf_tc
);