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_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp)
31 #define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level)
32 #define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
33 #include "logging/comp-logging.h"
41 #include "common/assert.h"
45 #include "common/common.h"
46 #include "common/uuid.h"
47 #include "compat/endian.h"
48 #include <babeltrace2/babeltrace.h>
55 #include "ctf-meta-visitors.h"
57 /* Bit value (left shift) */
58 #define _BV(_val) (1 << (_val))
60 /* Bit is set in a set of bits */
61 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
63 /* Set bit in a set of bits */
64 #define _SET(_set, _mask) (*(_set) |= (_mask))
66 /* Try to push scope, or go to the `error` label */
67 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
69 ret = ctx_push_scope(ctx); \
71 BT_COMP_LOGE_STR("Cannot push scope."); \
76 /* Bits for verifying existing attributes in various declarations */
78 _CLOCK_NAME_SET
= _BV(0),
79 _CLOCK_UUID_SET
= _BV(1),
80 _CLOCK_FREQ_SET
= _BV(2),
81 _CLOCK_PRECISION_SET
= _BV(3),
82 _CLOCK_OFFSET_S_SET
= _BV(4),
83 _CLOCK_OFFSET_SET
= _BV(5),
84 _CLOCK_ABSOLUTE_SET
= _BV(6),
85 _CLOCK_DESCRIPTION_SET
= _BV(7),
89 _INTEGER_ALIGN_SET
= _BV(0),
90 _INTEGER_SIZE_SET
= _BV(1),
91 _INTEGER_BASE_SET
= _BV(2),
92 _INTEGER_ENCODING_SET
= _BV(3),
93 _INTEGER_BYTE_ORDER_SET
= _BV(4),
94 _INTEGER_SIGNED_SET
= _BV(5),
95 _INTEGER_MAP_SET
= _BV(6),
99 _FLOAT_ALIGN_SET
= _BV(0),
100 _FLOAT_MANT_DIG_SET
= _BV(1),
101 _FLOAT_EXP_DIG_SET
= _BV(2),
102 _FLOAT_BYTE_ORDER_SET
= _BV(3),
106 _STRING_ENCODING_SET
= _BV(0),
110 _TRACE_MINOR_SET
= _BV(0),
111 _TRACE_MAJOR_SET
= _BV(1),
112 _TRACE_BYTE_ORDER_SET
= _BV(2),
113 _TRACE_UUID_SET
= _BV(3),
114 _TRACE_PACKET_HEADER_SET
= _BV(4),
118 _STREAM_ID_SET
= _BV(0),
119 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
120 _STREAM_EVENT_HEADER_SET
= _BV(2),
121 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
125 _EVENT_NAME_SET
= _BV(0),
126 _EVENT_ID_SET
= _BV(1),
127 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
128 _EVENT_STREAM_ID_SET
= _BV(3),
129 _EVENT_LOG_LEVEL_SET
= _BV(4),
130 _EVENT_CONTEXT_SET
= _BV(5),
131 _EVENT_FIELDS_SET
= _BV(6),
139 LOG_LEVEL_WARNING
= 4,
140 LOG_LEVEL_NOTICE
= 5,
142 LOG_LEVEL_DEBUG_SYSTEM
= 7,
143 LOG_LEVEL_DEBUG_PROGRAM
= 8,
144 LOG_LEVEL_DEBUG_PROCESS
= 9,
145 LOG_LEVEL_DEBUG_MODULE
= 10,
146 LOG_LEVEL_DEBUG_UNIT
= 11,
147 LOG_LEVEL_DEBUG_FUNCTION
= 12,
148 LOG_LEVEL_DEBUG_LINE
= 13,
149 LOG_LEVEL_DEBUG
= 14,
153 /* Prefixes of class aliases */
154 #define _PREFIX_ALIAS 'a'
155 #define _PREFIX_ENUM 'e'
156 #define _PREFIX_STRUCT 's'
157 #define _PREFIX_VARIANT 'v'
159 /* First entry in a BT list */
160 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
161 bt_list_entry((_ptr)->next, _class, _member)
163 #define _BT_COMP_LOGE_DUP_ATTR(_node, _attr, _entity) \
164 _BT_COMP_LOGE_LINENO((_node)->lineno, \
165 "Duplicate attribute in %s: attr-name=\"%s\"", \
168 #define _BT_COMP_LOGE_NODE(_node, _msg, args...) \
169 _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args)
171 #define _BT_COMP_LOGW_NODE(_node, _msg, args...) \
172 _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args)
174 #define _BT_COMP_LOGT_NODE(_node, _msg, args...) \
175 _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args)
178 * Declaration scope of a visitor context. This represents a TSDL
179 * lexical scope, so that aliases and named structures, variants,
180 * and enumerations may be registered and looked up hierarchically.
182 struct ctx_decl_scope
{
184 * Alias name to field class.
186 * GQuark -> struct ctf_field_class * (owned by this)
188 GHashTable
*decl_map
;
190 /* Parent scope; NULL if this is the root declaration scope */
191 struct ctx_decl_scope
*parent_scope
;
195 * Visitor context (private).
198 struct meta_log_config log_cfg
;
200 /* Trace IR trace class being filled (owned by this) */
201 bt_trace_class
*trace_class
;
203 /* CTF meta trace being filled (owned by this) */
204 struct ctf_trace_class
*ctf_tc
;
206 /* Current declaration scope (top of the stack) (owned by this) */
207 struct ctx_decl_scope
*current_scope
;
209 /* True if trace declaration is visited */
210 bool is_trace_visited
;
212 /* True if this is an LTTng trace */
215 /* Config passed by the user */
216 struct ctf_metadata_decoder_config decoder_config
;
222 struct ctf_visitor_generate_ir
;
225 * Creates a new declaration scope.
227 * @param par_scope Parent scope (NULL if creating a root scope)
228 * @returns New declaration scope, or NULL on error
231 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx
*ctx
,
232 struct ctx_decl_scope
*par_scope
)
234 struct ctx_decl_scope
*scope
;
236 scope
= g_new(struct ctx_decl_scope
, 1);
238 BT_COMP_LOGE_STR("Failed to allocate one declaration scope.");
242 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
243 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
244 scope
->parent_scope
= par_scope
;
251 * Destroys a declaration scope.
253 * This function does not destroy the parent scope.
255 * @param scope Scope to destroy
258 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
264 g_hash_table_destroy(scope
->decl_map
);
272 * Returns the GQuark of a prefixed alias.
274 * @param prefix Prefix character
276 * @returns Associated GQuark, or 0 on error
279 GQuark
get_prefixed_named_quark(struct ctx
*ctx
, char prefix
, const char *name
)
285 /* Prefix character + original string + '\0' */
286 char *prname
= g_new(char, strlen(name
) + 2);
288 BT_COMP_LOGE_STR("Failed to allocate a string.");
292 sprintf(prname
, "%c%s", prefix
, name
);
293 qname
= g_quark_from_string(prname
);
301 * Looks up a prefixed class alias within a declaration scope.
303 * @param scope Declaration scope
304 * @param prefix Prefix character
305 * @param name Alias name
306 * @param levels Number of levels to dig into (-1 means infinite)
307 * @param copy True to return a copy
308 * @returns Declaration (owned by caller if \p copy is true),
309 * or NULL if not found
312 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
313 struct ctx
*ctx
, struct ctx_decl_scope
*scope
, char prefix
,
314 const char *name
, int levels
, bool copy
)
318 struct ctf_field_class
*decl
= NULL
;
319 struct ctx_decl_scope
*cur_scope
= scope
;
323 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
332 while (cur_scope
&& cur_levels
< levels
) {
333 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
334 (gconstpointer
) GUINT_TO_POINTER(qname
));
336 /* Caller's reference */
338 decl
= ctf_field_class_copy(decl
);
345 cur_scope
= cur_scope
->parent_scope
;
354 * Looks up a class alias within a declaration scope.
356 * @param scope Declaration scope
357 * @param name Alias name
358 * @param levels Number of levels to dig into (-1 means infinite)
359 * @param copy True to return a copy
360 * @returns Declaration (owned by caller if \p copy is true),
361 * or NULL if not found
364 struct ctf_field_class
*ctx_decl_scope_lookup_alias(struct ctx
*ctx
,
365 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
368 return ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
373 * Looks up an enumeration within a declaration scope.
375 * @param scope Declaration scope
376 * @param name Enumeration name
377 * @param levels Number of levels to dig into (-1 means infinite)
378 * @param copy True to return a copy
379 * @returns Declaration (owned by caller if \p copy is true),
380 * or NULL if not found
383 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(struct ctx
*ctx
,
384 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
387 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
388 _PREFIX_ENUM
, name
, levels
, copy
);
392 * Looks up a structure within a declaration scope.
394 * @param scope Declaration scope
395 * @param name Structure name
396 * @param levels Number of levels to dig into (-1 means infinite)
397 * @param copy True to return a copy
398 * @returns Declaration (owned by caller if \p copy is true),
399 * or NULL if not found
402 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(struct ctx
*ctx
,
403 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
406 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
407 _PREFIX_STRUCT
, name
, levels
, copy
);
411 * Looks up a variant within a declaration scope.
413 * @param scope Declaration scope
414 * @param name Variant name
415 * @param levels Number of levels to dig into (-1 means infinite)
416 * @param copy True to return a copy
417 * @returns Declaration (owned by caller if \p copy is true),
418 * or NULL if not found
421 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(struct ctx
*ctx
,
422 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
425 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
426 _PREFIX_VARIANT
, name
, levels
, copy
);
430 * Registers a prefixed class alias within a declaration scope.
432 * @param scope Declaration scope
433 * @param prefix Prefix character
434 * @param name Alias name (non-NULL)
435 * @param decl Field class to register (copied)
436 * @returns 0 if registration went okay, negative value otherwise
439 int ctx_decl_scope_register_prefix_alias(struct ctx
*ctx
,
440 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
441 struct ctf_field_class
*decl
)
449 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
455 /* Make sure alias does not exist in local scope */
456 if (ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, prefix
, name
, 1,
462 decl
= ctf_field_class_copy(decl
);
464 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
471 * Registers a class alias within a declaration scope.
473 * @param scope Declaration scope
474 * @param name Alias name (non-NULL)
475 * @param decl Field class to register (copied)
476 * @returns 0 if registration went okay, negative value otherwise
479 int ctx_decl_scope_register_alias(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
480 const char *name
, struct ctf_field_class
*decl
)
482 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
483 name
, (void *) decl
);
487 * Registers an enumeration declaration within a declaration scope.
489 * @param scope Declaration scope
490 * @param name Enumeration name (non-NULL)
491 * @param decl Enumeration field class to register (copied)
492 * @returns 0 if registration went okay, negative value otherwise
495 int ctx_decl_scope_register_enum(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
496 const char *name
, struct ctf_field_class_enum
*decl
)
498 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ENUM
,
499 name
, (void *) decl
);
503 * Registers a structure declaration within a declaration scope.
505 * @param scope Declaration scope
506 * @param name Structure name (non-NULL)
507 * @param decl Structure field class to register (copied)
508 * @returns 0 if registration went okay, negative value otherwise
511 int ctx_decl_scope_register_struct(struct ctx
*ctx
,
512 struct ctx_decl_scope
*scope
, const char *name
,
513 struct ctf_field_class_struct
*decl
)
515 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_STRUCT
,
516 name
, (void *) decl
);
520 * Registers a variant declaration within a declaration scope.
522 * @param scope Declaration scope
523 * @param name Variant name (non-NULL)
524 * @param decl Variant field class to register
525 * @returns 0 if registration went okay, negative value otherwise
528 int ctx_decl_scope_register_variant(struct ctx
*ctx
,
529 struct ctx_decl_scope
*scope
, const char *name
,
530 struct ctf_field_class_variant
*decl
)
532 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_VARIANT
,
533 name
, (void *) decl
);
537 * Destroys a visitor context.
539 * @param ctx Visitor context to destroy
542 void ctx_destroy(struct ctx
*ctx
)
544 struct ctx_decl_scope
*scope
;
550 scope
= ctx
->current_scope
;
553 * Destroy all scopes, from current one to the root scope.
556 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
558 ctx_decl_scope_destroy(scope
);
559 scope
= parent_scope
;
562 bt_trace_class_put_ref(ctx
->trace_class
);
565 ctf_trace_class_destroy(ctx
->ctf_tc
);
575 * Creates a new visitor context.
577 * @param trace Associated trace
578 * @returns New visitor context, or NULL on error
581 struct ctx
*ctx_create(const struct ctf_metadata_decoder_config
*decoder_config
)
583 struct ctx
*ctx
= NULL
;
585 BT_ASSERT(decoder_config
);
587 ctx
= g_new0(struct ctx
, 1);
589 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
590 decoder_config
->self_comp
,
591 "Failed to allocate one visitor context.");
595 ctx
->log_cfg
.log_level
= decoder_config
->log_level
;
596 ctx
->log_cfg
.self_comp
= decoder_config
->self_comp
;
598 if (decoder_config
->self_comp
) {
599 ctx
->trace_class
= bt_trace_class_create(
600 decoder_config
->self_comp
);
601 if (!ctx
->trace_class
) {
602 BT_COMP_LOGE_STR("Cannot create empty trace class.");
607 ctx
->ctf_tc
= ctf_trace_class_create();
609 BT_COMP_LOGE_STR("Cannot create CTF trace class.");
613 /* Root declaration scope */
614 ctx
->current_scope
= ctx_decl_scope_create(ctx
, NULL
);
615 if (!ctx
->current_scope
) {
616 BT_COMP_LOGE_STR("Cannot create declaration scope.");
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
, ctx
->current_scope
);
647 BT_COMP_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 int is_unary_string(struct bt_list_head
*head
)
685 struct ctf_node
*node
;
687 bt_list_for_each_entry(node
, head
, siblings
) {
688 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
692 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
701 const char *get_map_clock_name_value(struct bt_list_head
*head
)
704 struct ctf_node
*node
;
705 const char *name
= NULL
;
707 bt_list_for_each_entry(node
, head
, siblings
) {
709 int uexpr_type
= node
->u
.unary_expression
.type
;
710 int uexpr_link
= node
->u
.unary_expression
.link
;
711 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
712 uexpr_type
!= UNARY_STRING
||
713 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
718 /* Needs to be chained with . */
719 switch (node
->u
.unary_expression
.link
) {
722 case UNARY_ARROWLINK
:
723 case UNARY_DOTDOTDOT
:
729 src_string
= node
->u
.unary_expression
.u
.string
;
733 if (strcmp("clock", src_string
)) {
741 if (strcmp("value", src_string
)) {
746 /* Extra identifier, unknown */
760 int is_unary_unsigned(struct bt_list_head
*head
)
763 struct ctf_node
*node
;
765 bt_list_for_each_entry(node
, head
, siblings
) {
766 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
770 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
779 int get_unary_unsigned(struct ctx
*ctx
, struct bt_list_head
*head
,
784 struct ctf_node
*node
;
788 if (bt_list_empty(head
)) {
793 bt_list_for_each_entry(node
, head
, siblings
) {
794 int uexpr_type
= node
->u
.unary_expression
.type
;
795 int uexpr_link
= node
->u
.unary_expression
.link
;
796 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
797 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
798 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
800 _BT_COMP_LOGE_NODE(node
, "Invalid constant unsigned integer.");
805 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
814 int is_unary_signed(struct bt_list_head
*head
)
817 struct ctf_node
*node
;
819 bt_list_for_each_entry(node
, head
, siblings
) {
820 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
824 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
833 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
837 struct ctf_node
*node
;
839 bt_list_for_each_entry(node
, head
, siblings
) {
840 int uexpr_type
= node
->u
.unary_expression
.type
;
841 int uexpr_link
= node
->u
.unary_expression
.link
;
842 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
843 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
844 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
845 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
851 switch (uexpr_type
) {
852 case UNARY_UNSIGNED_CONSTANT
:
854 node
->u
.unary_expression
.u
.unsigned_constant
;
856 case UNARY_SIGNED_CONSTANT
:
857 *value
= node
->u
.unary_expression
.u
.signed_constant
;
871 int get_unary_uuid(struct ctx
*ctx
, struct bt_list_head
*head
,
874 return ctf_ast_get_unary_uuid(head
, uuid
, ctx
->log_cfg
.log_level
,
875 ctx
->log_cfg
.self_comp
);
879 int get_boolean(struct ctx
*ctx
, struct ctf_node
*unary_expr
)
883 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
884 _BT_COMP_LOGE_NODE(unary_expr
,
885 "Expecting unary expression: node-type=%d",
891 switch (unary_expr
->u
.unary_expression
.type
) {
892 case UNARY_UNSIGNED_CONSTANT
:
893 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
895 case UNARY_SIGNED_CONSTANT
:
896 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
900 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
902 if (strcmp(str
, "true") == 0 || strcmp(str
, "TRUE") == 0) {
904 } else if (strcmp(str
, "false") == 0 || strcmp(str
, "FALSE") == 0) {
907 _BT_COMP_LOGE_NODE(unary_expr
,
908 "Unexpected boolean value: value=\"%s\"", str
);
915 _BT_COMP_LOGE_NODE(unary_expr
,
916 "Unexpected unary expression type: node-type=%d",
917 unary_expr
->u
.unary_expression
.type
);
927 enum ctf_byte_order
byte_order_from_unary_expr(struct ctx
*ctx
,
928 struct ctf_node
*unary_expr
)
931 enum ctf_byte_order bo
= CTF_BYTE_ORDER_UNKNOWN
;
933 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
934 _BT_COMP_LOGE_NODE(unary_expr
,
935 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
939 str
= unary_expr
->u
.unary_expression
.u
.string
;
941 if (strcmp(str
, "be") == 0 || strcmp(str
, "network") == 0) {
942 bo
= CTF_BYTE_ORDER_BIG
;
943 } else if (strcmp(str
, "le") == 0) {
944 bo
= CTF_BYTE_ORDER_LITTLE
;
945 } else if (strcmp(str
, "native") == 0) {
946 bo
= CTF_BYTE_ORDER_DEFAULT
;
948 _BT_COMP_LOGE_NODE(unary_expr
,
949 "Unexpected \"byte_order\" attribute value: "
950 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
960 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
961 struct ctf_node
*uexpr
)
963 enum ctf_byte_order bo
= byte_order_from_unary_expr(ctx
, uexpr
);
965 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
966 bo
= ctx
->ctf_tc
->default_byte_order
;
973 int is_align_valid(uint64_t align
)
975 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
979 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
984 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
985 _BT_COMP_LOGE_NODE(cls_specifier
,
986 "Unexpected node type: node-type=%d",
987 cls_specifier
->type
);
992 switch (cls_specifier
->u
.field_class_specifier
.type
) {
994 g_string_append(str
, "void");
997 g_string_append(str
, "char");
1000 g_string_append(str
, "short");
1003 g_string_append(str
, "int");
1006 g_string_append(str
, "long");
1008 case TYPESPEC_FLOAT
:
1009 g_string_append(str
, "float");
1011 case TYPESPEC_DOUBLE
:
1012 g_string_append(str
, "double");
1014 case TYPESPEC_SIGNED
:
1015 g_string_append(str
, "signed");
1017 case TYPESPEC_UNSIGNED
:
1018 g_string_append(str
, "unsigned");
1021 g_string_append(str
, "bool");
1023 case TYPESPEC_COMPLEX
:
1024 g_string_append(str
, "_Complex");
1026 case TYPESPEC_IMAGINARY
:
1027 g_string_append(str
, "_Imaginary");
1029 case TYPESPEC_CONST
:
1030 g_string_append(str
, "const");
1032 case TYPESPEC_ID_TYPE
:
1033 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1034 g_string_append(str
,
1035 cls_specifier
->u
.field_class_specifier
.id_type
);
1038 case TYPESPEC_STRUCT
:
1040 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1042 if (!node
->u
._struct
.name
) {
1043 _BT_COMP_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1048 g_string_append(str
, "struct ");
1049 g_string_append(str
, node
->u
._struct
.name
);
1052 case TYPESPEC_VARIANT
:
1054 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1056 if (!node
->u
.variant
.name
) {
1057 _BT_COMP_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1062 g_string_append(str
, "variant ");
1063 g_string_append(str
, node
->u
.variant
.name
);
1068 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1070 if (!node
->u
._enum
.enum_id
) {
1071 _BT_COMP_LOGE_NODE(node
,
1072 "Unexpected empty enumeration field class (`enum`) name.");
1077 g_string_append(str
, "enum ");
1078 g_string_append(str
, node
->u
._enum
.enum_id
);
1081 case TYPESPEC_FLOATING_POINT
:
1082 case TYPESPEC_INTEGER
:
1083 case TYPESPEC_STRING
:
1085 _BT_COMP_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1086 "Unexpected field class specifier type: %d",
1087 cls_specifier
->u
.field_class_specifier
.type
);
1097 int get_class_specifier_list_name(struct ctx
*ctx
,
1098 struct ctf_node
*cls_specifier_list
, GString
*str
)
1101 struct ctf_node
*iter
;
1102 int alias_item_nr
= 0;
1103 struct bt_list_head
*head
=
1104 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1106 bt_list_for_each_entry(iter
, head
, siblings
) {
1107 if (alias_item_nr
!= 0) {
1108 g_string_append(str
, " ");
1112 ret
= get_class_specifier_name(ctx
, iter
, str
);
1123 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1124 struct ctf_node
*cls_specifier_list
,
1125 struct ctf_node
*node_field_class_declarator
)
1131 struct ctf_node
*iter
;
1132 struct bt_list_head
*pointers
=
1133 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1135 str
= g_string_new("");
1136 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1138 g_string_free(str
, TRUE
);
1142 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1143 g_string_append(str
, " *");
1145 if (iter
->u
.pointer
.const_qualifier
) {
1146 g_string_append(str
, " const");
1150 str_c
= g_string_free(str
, FALSE
);
1151 qalias
= g_quark_from_string(str_c
);
1159 int visit_field_class_declarator(struct ctx
*ctx
,
1160 struct ctf_node
*cls_specifier_list
,
1161 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1162 struct ctf_field_class
**field_decl
,
1163 struct ctf_field_class
*nested_decl
)
1166 * During this whole function, nested_decl is always OURS,
1167 * whereas field_decl is an output which we create, but
1168 * belongs to the caller (it is moved).
1173 /* Validate field class declarator node */
1174 if (node_field_class_declarator
) {
1175 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1177 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1178 "Unexpected field class declarator type: type=%d",
1179 node_field_class_declarator
->u
.field_class_declarator
.type
);
1184 /* TODO: GCC bitfields not supported yet */
1185 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1187 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1188 "GCC bitfields are not supported as of this version.");
1194 /* Find the right nested declaration if not provided */
1196 struct bt_list_head
*pointers
=
1197 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1199 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1203 * If we have a pointer declarator, it HAS to
1204 * be present in the field class aliases (else
1207 qalias
= create_class_alias_identifier(ctx
,
1208 cls_specifier_list
, node_field_class_declarator
);
1210 ctx_decl_scope_lookup_alias(ctx
,
1212 g_quark_to_string(qalias
), -1, true);
1214 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1215 "Cannot find class alias: name=\"%s\"",
1216 g_quark_to_string(qalias
));
1221 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1222 /* Pointer: force integer's base to 16 */
1223 struct ctf_field_class_int
*int_fc
=
1224 (void *) nested_decl
;
1227 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1230 ret
= visit_field_class_specifier_list(ctx
,
1231 cls_specifier_list
, &nested_decl
);
1233 BT_ASSERT(!nested_decl
);
1239 BT_ASSERT(nested_decl
);
1241 if (!node_field_class_declarator
) {
1242 *field_decl
= nested_decl
;
1247 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1248 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1250 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1252 *field_name
= g_quark_from_string(id
);
1257 *field_decl
= nested_decl
;
1261 struct ctf_node
*first
;
1262 struct ctf_field_class
*decl
= NULL
;
1263 struct ctf_field_class
*outer_field_decl
= NULL
;
1264 struct bt_list_head
*length
=
1265 &node_field_class_declarator
->
1266 u
.field_class_declarator
.u
.nested
.length
;
1268 /* Create array/sequence, pass nested_decl as child */
1269 if (bt_list_empty(length
)) {
1270 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1271 "Expecting length field reference or value.");
1276 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1277 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1278 _BT_COMP_LOGE_NODE(first
,
1279 "Unexpected node type: node-type=%d",
1285 switch (first
->u
.unary_expression
.type
) {
1286 case UNARY_UNSIGNED_CONSTANT
:
1288 struct ctf_field_class_array
*array_decl
= NULL
;
1290 array_decl
= ctf_field_class_array_create();
1291 BT_ASSERT(array_decl
);
1292 array_decl
->length
=
1293 first
->u
.unary_expression
.u
.unsigned_constant
;
1294 array_decl
->base
.elem_fc
= nested_decl
;
1296 decl
= (void *) array_decl
;
1301 /* Lookup unsigned integer definition, create seq. */
1302 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1303 char *length_name
= ctf_ast_concatenate_unary_strings(length
);
1306 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1307 "Cannot concatenate unary strings.");
1312 if (strncmp(length_name
, "env.", 4) == 0) {
1313 /* This is, in fact, an array */
1314 const char *env_entry_name
= &length_name
[4];
1315 struct ctf_trace_class_env_entry
*env_entry
=
1316 ctf_trace_class_borrow_env_entry_by_name(
1317 ctx
->ctf_tc
, env_entry_name
);
1318 struct ctf_field_class_array
*array_decl
;
1321 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1322 "Cannot find environment entry: "
1323 "name=\"%s\"", env_entry_name
);
1328 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1329 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1330 "Wrong environment entry type "
1331 "(expecting integer): "
1332 "name=\"%s\"", env_entry_name
);
1337 if (env_entry
->value
.i
< 0) {
1338 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1339 "Invalid, negative array length: "
1340 "env-entry-name=\"%s\", "
1343 env_entry
->value
.i
);
1348 array_decl
= ctf_field_class_array_create();
1349 BT_ASSERT(array_decl
);
1350 array_decl
->length
=
1351 (uint64_t) env_entry
->value
.i
;
1352 array_decl
->base
.elem_fc
= nested_decl
;
1354 decl
= (void *) array_decl
;
1356 seq_decl
= ctf_field_class_sequence_create();
1357 BT_ASSERT(seq_decl
);
1358 seq_decl
->base
.elem_fc
= nested_decl
;
1360 g_string_assign(seq_decl
->length_ref
,
1362 decl
= (void *) seq_decl
;
1365 g_free(length_name
);
1373 BT_ASSERT(!nested_decl
);
1375 BT_ASSERT(!*field_decl
);
1378 * At this point, we found the next nested declaration.
1379 * We currently own this (and lost the ownership of
1380 * nested_decl in the meantime). Pass this next
1381 * nested declaration as the content of the outer
1382 * container, MOVING its ownership.
1384 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1386 node_field_class_declarator
->
1387 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1388 &outer_field_decl
, decl
);
1391 BT_ASSERT(!outer_field_decl
);
1396 BT_ASSERT(outer_field_decl
);
1397 *field_decl
= outer_field_decl
;
1398 outer_field_decl
= NULL
;
1401 BT_ASSERT(*field_decl
);
1405 ctf_field_class_destroy(*field_decl
);
1413 ctf_field_class_destroy(nested_decl
);
1419 int visit_struct_decl_field(struct ctx
*ctx
,
1420 struct ctf_field_class_struct
*struct_decl
,
1421 struct ctf_node
*cls_specifier_list
,
1422 struct bt_list_head
*field_class_declarators
)
1425 struct ctf_node
*iter
;
1426 struct ctf_field_class
*field_decl
= NULL
;
1428 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1431 const char *field_name
;
1433 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1434 &qfield_name
, iter
, &field_decl
, NULL
);
1436 BT_ASSERT(!field_decl
);
1437 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1438 "Cannot visit field class declarator: ret=%d", ret
);
1442 BT_ASSERT(field_decl
);
1443 field_name
= g_quark_to_string(qfield_name
);
1445 /* Check if field with same name already exists */
1446 if (ctf_field_class_struct_borrow_member_by_name(
1447 struct_decl
, field_name
)) {
1448 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1449 "Duplicate field in structure field class: "
1450 "field-name=\"%s\"", field_name
);
1455 /* Add field to structure */
1456 ctf_field_class_struct_append_member(struct_decl
,
1457 field_name
, field_decl
);
1464 ctf_field_class_destroy(field_decl
);
1470 int visit_variant_decl_field(struct ctx
*ctx
,
1471 struct ctf_field_class_variant
*variant_decl
,
1472 struct ctf_node
*cls_specifier_list
,
1473 struct bt_list_head
*field_class_declarators
)
1476 struct ctf_node
*iter
;
1477 struct ctf_field_class
*field_decl
= NULL
;
1479 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1482 const char *field_name
;
1484 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1485 &qfield_name
, iter
, &field_decl
, NULL
);
1487 BT_ASSERT(!field_decl
);
1488 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1489 "Cannot visit field class declarator: ret=%d", ret
);
1493 BT_ASSERT(field_decl
);
1494 field_name
= g_quark_to_string(qfield_name
);
1496 /* Check if field with same name already exists */
1497 if (ctf_field_class_variant_borrow_option_by_name(
1498 variant_decl
, field_name
)) {
1499 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1500 "Duplicate field in variant field class: "
1501 "field-name=\"%s\"", field_name
);
1506 /* Add field to structure */
1507 ctf_field_class_variant_append_option(variant_decl
,
1508 field_name
, field_decl
);
1515 ctf_field_class_destroy(field_decl
);
1521 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1522 struct bt_list_head
*field_class_declarators
)
1526 struct ctf_node
*iter
;
1527 struct ctf_field_class
*class_decl
= NULL
;
1529 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1530 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1531 &qidentifier
, iter
, &class_decl
, NULL
);
1533 _BT_COMP_LOGE_NODE(iter
,
1534 "Cannot visit field class declarator: ret=%d", ret
);
1539 /* Do not allow field class def and alias of untagged variants */
1540 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1541 struct ctf_field_class_variant
*var_fc
=
1542 (void *) class_decl
;
1544 if (var_fc
->tag_path
.path
->len
== 0) {
1545 _BT_COMP_LOGE_NODE(iter
,
1546 "Type definition of untagged variant field class is not allowed.");
1552 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1553 g_quark_to_string(qidentifier
), class_decl
);
1555 _BT_COMP_LOGE_NODE(iter
,
1556 "Cannot register field class alias: name=\"%s\"",
1557 g_quark_to_string(qidentifier
));
1563 ctf_field_class_destroy(class_decl
);
1569 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1570 struct ctf_node
*alias
)
1574 struct ctf_node
*node
;
1575 GQuark qdummy_field_name
;
1576 struct ctf_field_class
*class_decl
= NULL
;
1578 /* Create target field class */
1579 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1582 node
= _BT_LIST_FIRST_ENTRY(
1583 &target
->u
.field_class_alias_target
.field_class_declarators
,
1584 struct ctf_node
, siblings
);
1587 ret
= visit_field_class_declarator(ctx
,
1588 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1589 &qdummy_field_name
, node
, &class_decl
, NULL
);
1591 BT_ASSERT(!class_decl
);
1592 _BT_COMP_LOGE_NODE(node
,
1593 "Cannot visit field class declarator: ret=%d", ret
);
1597 /* Do not allow field class def and alias of untagged variants */
1598 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1599 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1601 if (var_fc
->tag_path
.path
->len
== 0) {
1602 _BT_COMP_LOGE_NODE(target
,
1603 "Type definition of untagged variant field class is not allowed.");
1610 * The semantic validator does not check whether the target is
1611 * abstract or not (if it has an identifier). Check it here.
1613 if (qdummy_field_name
!= 0) {
1614 _BT_COMP_LOGE_NODE(target
,
1615 "Expecting empty identifier: id=\"%s\"",
1616 g_quark_to_string(qdummy_field_name
));
1621 /* Create alias identifier */
1622 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1623 struct ctf_node
, siblings
);
1624 qalias
= create_class_alias_identifier(ctx
,
1625 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1626 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1627 g_quark_to_string(qalias
), class_decl
);
1629 _BT_COMP_LOGE_NODE(node
,
1630 "Cannot register class alias: name=\"%s\"",
1631 g_quark_to_string(qalias
));
1636 ctf_field_class_destroy(class_decl
);
1642 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1643 struct ctf_field_class_struct
*struct_decl
)
1647 switch (entry_node
->type
) {
1649 ret
= visit_field_class_def(ctx
,
1650 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1651 &entry_node
->u
.field_class_def
.field_class_declarators
);
1653 _BT_COMP_LOGE_NODE(entry_node
,
1654 "Cannot add field class found in structure field class: ret=%d",
1659 case NODE_TYPEALIAS
:
1660 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1661 entry_node
->u
.field_class_alias
.alias
);
1663 _BT_COMP_LOGE_NODE(entry_node
,
1664 "Cannot add field class alias found in structure field class: ret=%d",
1669 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1671 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1672 entry_node
->u
.struct_or_variant_declaration
.
1673 field_class_specifier_list
,
1674 &entry_node
->u
.struct_or_variant_declaration
.
1675 field_class_declarators
);
1681 _BT_COMP_LOGE_NODE(entry_node
,
1682 "Unexpected node type: node-type=%d", entry_node
->type
);
1692 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1693 struct ctf_field_class_variant
*variant_decl
)
1697 switch (entry_node
->type
) {
1699 ret
= visit_field_class_def(ctx
,
1700 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1701 &entry_node
->u
.field_class_def
.field_class_declarators
);
1703 _BT_COMP_LOGE_NODE(entry_node
,
1704 "Cannot add field class found in variant field class: ret=%d",
1709 case NODE_TYPEALIAS
:
1710 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1711 entry_node
->u
.field_class_alias
.alias
);
1713 _BT_COMP_LOGE_NODE(entry_node
,
1714 "Cannot add field class alias found in variant field class: ret=%d",
1719 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1721 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1722 entry_node
->u
.struct_or_variant_declaration
.
1723 field_class_specifier_list
,
1724 &entry_node
->u
.struct_or_variant_declaration
.
1725 field_class_declarators
);
1731 _BT_COMP_LOGE_NODE(entry_node
,
1732 "Unexpected node type: node-type=%d",
1743 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1744 struct bt_list_head
*decl_list
, int has_body
,
1745 struct bt_list_head
*min_align
,
1746 struct ctf_field_class_struct
**struct_decl
)
1750 BT_ASSERT(struct_decl
);
1751 *struct_decl
= NULL
;
1753 /* For named struct (without body), lookup in declaration scope */
1756 BT_COMP_LOGE_STR("Bodyless structure field class: missing name.");
1761 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
, ctx
->current_scope
,
1763 if (!*struct_decl
) {
1764 BT_COMP_LOGE("Cannot find structure field class: name=\"struct %s\"",
1770 struct ctf_node
*entry_node
;
1771 uint64_t min_align_value
= 0;
1774 if (ctx_decl_scope_lookup_struct(ctx
,
1775 ctx
->current_scope
, name
, 1, false)) {
1776 BT_COMP_LOGE("Structure field class already declared in local scope: "
1777 "name=\"struct %s\"", name
);
1783 if (!bt_list_empty(min_align
)) {
1784 ret
= get_unary_unsigned(ctx
, min_align
,
1787 BT_COMP_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1793 *struct_decl
= ctf_field_class_struct_create();
1794 BT_ASSERT(*struct_decl
);
1796 if (min_align_value
!= 0) {
1797 (*struct_decl
)->base
.alignment
= min_align_value
;
1800 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1802 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1803 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1806 _BT_COMP_LOGE_NODE(entry_node
,
1807 "Cannot visit structure field class entry: "
1817 ret
= ctx_decl_scope_register_struct(ctx
,
1818 ctx
->current_scope
, name
, *struct_decl
);
1820 BT_COMP_LOGE("Cannot register structure field class in declaration scope: "
1821 "name=\"struct %s\", ret=%d", name
, ret
);
1830 ctf_field_class_destroy((void *) *struct_decl
);
1831 *struct_decl
= NULL
;
1836 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1837 const char *tag
, struct bt_list_head
*decl_list
,
1838 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1841 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1843 BT_ASSERT(variant_decl
);
1844 *variant_decl
= NULL
;
1846 /* For named variant (without body), lookup in declaration scope */
1849 BT_COMP_LOGE_STR("Bodyless variant field class: missing name.");
1854 untagged_variant_decl
=
1855 ctx_decl_scope_lookup_variant(ctx
, ctx
->current_scope
,
1857 if (!untagged_variant_decl
) {
1858 BT_COMP_LOGE("Cannot find variant field class: name=\"variant %s\"",
1864 struct ctf_node
*entry_node
;
1867 if (ctx_decl_scope_lookup_variant(ctx
,
1868 ctx
->current_scope
, name
, 1, false)) {
1869 BT_COMP_LOGE("Variant field class already declared in local scope: "
1870 "name=\"variant %s\"", name
);
1876 untagged_variant_decl
= ctf_field_class_variant_create();
1877 BT_ASSERT(untagged_variant_decl
);
1878 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1880 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1881 ret
= visit_variant_decl_entry(ctx
, entry_node
,
1882 untagged_variant_decl
);
1884 _BT_COMP_LOGE_NODE(entry_node
,
1885 "Cannot visit variant field class entry: "
1895 ret
= ctx_decl_scope_register_variant(ctx
,
1896 ctx
->current_scope
, name
,
1897 untagged_variant_decl
);
1899 BT_COMP_LOGE("Cannot register variant field class in declaration scope: "
1900 "name=\"variant %s\", ret=%d", name
, ret
);
1907 * If tagged, create tagged variant and return; otherwise
1908 * return untagged variant.
1911 *variant_decl
= untagged_variant_decl
;
1912 untagged_variant_decl
= NULL
;
1915 * At this point, we have a fresh untagged variant; nobody
1916 * else owns it. Set its tag now.
1918 g_string_assign(untagged_variant_decl
->tag_ref
, tag
);
1919 *variant_decl
= untagged_variant_decl
;
1920 untagged_variant_decl
= NULL
;
1923 BT_ASSERT(!untagged_variant_decl
);
1924 BT_ASSERT(*variant_decl
);
1928 ctf_field_class_destroy((void *) untagged_variant_decl
);
1929 untagged_variant_decl
= NULL
;
1930 ctf_field_class_destroy((void *) *variant_decl
);
1931 *variant_decl
= NULL
;
1944 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
1945 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
1949 struct ctf_node
*iter
;
1950 struct uori start
= {
1958 const char *label
= enumerator
->u
.enumerator
.id
;
1959 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
1961 bt_list_for_each_entry(iter
, values
, siblings
) {
1962 struct uori
*target
;
1964 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
1965 _BT_COMP_LOGE_NODE(iter
,
1966 "Wrong expression for enumeration field class label: "
1967 "node-type=%d, label=\"%s\"", iter
->type
,
1979 switch (iter
->u
.unary_expression
.type
) {
1980 case UNARY_SIGNED_CONSTANT
:
1981 target
->is_signed
= true;
1983 iter
->u
.unary_expression
.u
.signed_constant
;
1985 case UNARY_UNSIGNED_CONSTANT
:
1986 target
->is_signed
= false;
1988 iter
->u
.unary_expression
.u
.unsigned_constant
;
1991 _BT_COMP_LOGE_NODE(iter
,
1992 "Invalid enumeration field class entry: "
1993 "expecting constant signed or unsigned integer: "
1994 "node-type=%d, label=\"%s\"",
1995 iter
->u
.unary_expression
.type
, label
);
2001 _BT_COMP_LOGE_NODE(iter
,
2002 "Invalid enumeration field class entry: label=\"%s\"",
2019 if (end
.is_signed
) {
2020 last
->value
.i
= end
.value
.i
+ 1;
2022 last
->value
.u
= end
.value
.u
+ 1;
2025 ctf_field_class_enum_map_range(enum_decl
, label
,
2026 start
.value
.u
, end
.value
.u
);
2034 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2035 struct ctf_node
*container_cls
,
2036 struct bt_list_head
*enumerator_list
,
2037 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2041 struct ctf_field_class_int
*integer_decl
= NULL
;
2043 BT_ASSERT(enum_decl
);
2046 /* For named enum (without body), lookup in declaration scope */
2049 BT_COMP_LOGE_STR("Bodyless enumeration field class: missing name.");
2054 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2057 BT_COMP_LOGE("Cannot find enumeration field class: "
2058 "name=\"enum %s\"", name
);
2063 struct ctf_node
*iter
;
2064 struct uori last_value
= {
2070 if (ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2072 BT_COMP_LOGE("Enumeration field class already declared in local scope: "
2073 "name=\"enum %s\"", name
);
2079 if (!container_cls
) {
2080 integer_decl
= (void *) ctx_decl_scope_lookup_alias(ctx
,
2081 ctx
->current_scope
, "int", -1, true);
2082 if (!integer_decl
) {
2083 BT_COMP_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2088 ret
= visit_field_class_declarator(ctx
, container_cls
,
2089 &qdummy_id
, NULL
, (void *) &integer_decl
,
2092 BT_ASSERT(!integer_decl
);
2098 BT_ASSERT(integer_decl
);
2100 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2101 BT_COMP_LOGE("Container field class for enumeration field class is not an integer field class: "
2102 "fc-type=%d", integer_decl
->base
.base
.type
);
2107 *enum_decl
= ctf_field_class_enum_create();
2108 BT_ASSERT(*enum_decl
);
2109 (*enum_decl
)->base
.base
.base
.alignment
=
2110 integer_decl
->base
.base
.alignment
;
2111 ctf_field_class_int_copy_content((void *) *enum_decl
,
2112 (void *) integer_decl
);
2113 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2115 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2116 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2119 _BT_COMP_LOGE_NODE(iter
,
2120 "Cannot visit enumeration field class entry: "
2127 ret
= ctx_decl_scope_register_enum(ctx
,
2128 ctx
->current_scope
, name
, *enum_decl
);
2130 BT_COMP_LOGE("Cannot register enumeration field class in declaration scope: "
2140 ctf_field_class_destroy((void *) *enum_decl
);
2144 ctf_field_class_destroy((void *) integer_decl
);
2145 integer_decl
= NULL
;
2150 int visit_field_class_specifier(struct ctx
*ctx
,
2151 struct ctf_node
*cls_specifier_list
,
2152 struct ctf_field_class
**decl
)
2155 GString
*str
= NULL
;
2158 str
= g_string_new("");
2159 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2161 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2162 "Cannot get field class specifier list's name: ret=%d", ret
);
2166 *decl
= ctx_decl_scope_lookup_alias(ctx
, ctx
->current_scope
, str
->str
,
2169 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2170 "Cannot find field class alias: name=\"%s\"", str
->str
);
2178 ctf_field_class_destroy(*decl
);
2183 g_string_free(str
, TRUE
);
2190 int visit_integer_decl(struct ctx
*ctx
,
2191 struct bt_list_head
*expressions
,
2192 struct ctf_field_class_int
**integer_decl
)
2197 struct ctf_node
*expression
;
2198 uint64_t alignment
= 0, size
= 0;
2199 struct ctf_clock_class
*mapped_clock_class
= NULL
;
2200 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2201 bt_field_class_integer_preferred_display_base base
=
2202 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2203 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2205 *integer_decl
= NULL
;
2207 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2208 struct ctf_node
*left
, *right
;
2210 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2211 struct ctf_node
, siblings
);
2212 right
= _BT_LIST_FIRST_ENTRY(
2213 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2216 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2217 _BT_COMP_LOGE_NODE(left
,
2218 "Unexpected unary expression type: type=%d",
2219 left
->u
.unary_expression
.type
);
2224 if (strcmp(left
->u
.unary_expression
.u
.string
, "signed") == 0) {
2225 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2226 _BT_COMP_LOGE_DUP_ATTR(left
, "signed",
2227 "integer field class");
2232 signedness
= get_boolean(ctx
, right
);
2233 if (signedness
< 0) {
2234 _BT_COMP_LOGE_NODE(right
,
2235 "Invalid boolean value for integer field class's `signed` attribute: "
2241 _SET(&set
, _INTEGER_SIGNED_SET
);
2242 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2243 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2244 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2245 "integer field class");
2250 byte_order
= get_real_byte_order(ctx
, right
);
2251 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2252 _BT_COMP_LOGE_NODE(right
,
2253 "Invalid `byte_order` attribute in integer field class: "
2259 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2260 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "size") == 0) {
2261 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2262 _BT_COMP_LOGE_DUP_ATTR(left
, "size",
2263 "integer field class");
2268 if (right
->u
.unary_expression
.type
!=
2269 UNARY_UNSIGNED_CONSTANT
) {
2270 _BT_COMP_LOGE_NODE(right
,
2271 "Invalid `size` attribute in integer field class: "
2272 "expecting unsigned constant integer: "
2274 right
->u
.unary_expression
.type
);
2279 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2281 _BT_COMP_LOGE_NODE(right
,
2282 "Invalid `size` attribute in integer field class: "
2283 "expecting positive constant integer: "
2284 "size=%" PRIu64
, size
);
2287 } else if (size
> 64) {
2288 _BT_COMP_LOGE_NODE(right
,
2289 "Invalid `size` attribute in integer field class: "
2290 "integer fields over 64 bits are not supported as of this version: "
2291 "size=%" PRIu64
, size
);
2296 _SET(&set
, _INTEGER_SIZE_SET
);
2297 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2298 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2299 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2300 "integer field class");
2305 if (right
->u
.unary_expression
.type
!=
2306 UNARY_UNSIGNED_CONSTANT
) {
2307 _BT_COMP_LOGE_NODE(right
,
2308 "Invalid `align` attribute in integer field class: "
2309 "expecting unsigned constant integer: "
2311 right
->u
.unary_expression
.type
);
2317 right
->u
.unary_expression
.u
.unsigned_constant
;
2318 if (!is_align_valid(alignment
)) {
2319 _BT_COMP_LOGE_NODE(right
,
2320 "Invalid `align` attribute in integer field class: "
2321 "expecting power of two: "
2322 "align=%" PRIu64
, alignment
);
2327 _SET(&set
, _INTEGER_ALIGN_SET
);
2328 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "base") == 0) {
2329 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2330 _BT_COMP_LOGE_DUP_ATTR(left
, "base",
2331 "integer field class");
2336 switch (right
->u
.unary_expression
.type
) {
2337 case UNARY_UNSIGNED_CONSTANT
:
2339 uint64_t constant
= right
->u
.unary_expression
.
2340 u
.unsigned_constant
;
2344 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2347 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2350 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2353 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2356 _BT_COMP_LOGE_NODE(right
,
2357 "Invalid `base` attribute in integer field class: "
2359 right
->u
.unary_expression
.u
.unsigned_constant
);
2367 char *s_right
= ctf_ast_concatenate_unary_strings(
2368 &expression
->u
.ctf_expression
.right
);
2370 _BT_COMP_LOGE_NODE(right
,
2371 "Unexpected unary expression for integer field class's `base` attribute.");
2376 if (strcmp(s_right
, "decimal") == 0 ||
2377 strcmp(s_right
, "dec") == 0 ||
2378 strcmp(s_right
, "d") == 0 ||
2379 strcmp(s_right
, "i") == 0 ||
2380 strcmp(s_right
, "u") == 0) {
2381 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2382 } else if (strcmp(s_right
, "hexadecimal") == 0 ||
2383 strcmp(s_right
, "hex") == 0 ||
2384 strcmp(s_right
, "x") == 0 ||
2385 strcmp(s_right
, "X") == 0 ||
2386 strcmp(s_right
, "p") == 0) {
2387 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2388 } else if (strcmp(s_right
, "octal") == 0 ||
2389 strcmp(s_right
, "oct") == 0 ||
2390 strcmp(s_right
, "o") == 0) {
2391 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2392 } else if (strcmp(s_right
, "binary") == 0 ||
2393 strcmp(s_right
, "b") == 0) {
2394 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2396 _BT_COMP_LOGE_NODE(right
,
2397 "Unexpected unary expression for integer field class's `base` attribute: "
2398 "base=\"%s\"", s_right
);
2408 _BT_COMP_LOGE_NODE(right
,
2409 "Invalid `base` attribute in integer field class: "
2410 "expecting unsigned constant integer or unary string.");
2415 _SET(&set
, _INTEGER_BASE_SET
);
2416 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2419 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2420 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2421 "integer field class");
2426 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2427 _BT_COMP_LOGE_NODE(right
,
2428 "Invalid `encoding` attribute in integer field class: "
2429 "expecting unary string.");
2434 s_right
= ctf_ast_concatenate_unary_strings(
2435 &expression
->u
.ctf_expression
.right
);
2437 _BT_COMP_LOGE_NODE(right
,
2438 "Unexpected unary expression for integer field class's `encoding` attribute.");
2443 if (strcmp(s_right
, "UTF8") == 0 ||
2444 strcmp(s_right
, "utf8") == 0 ||
2445 strcmp(s_right
, "utf-8") == 0 ||
2446 strcmp(s_right
, "UTF-8") == 0 ||
2447 strcmp(s_right
, "ASCII") == 0 ||
2448 strcmp(s_right
, "ascii") == 0) {
2449 encoding
= CTF_ENCODING_UTF8
;
2450 } else if (strcmp(s_right
, "none") == 0) {
2451 encoding
= CTF_ENCODING_NONE
;
2453 _BT_COMP_LOGE_NODE(right
,
2454 "Invalid `encoding` attribute in integer field class: "
2455 "unknown encoding: encoding=\"%s\"",
2463 _SET(&set
, _INTEGER_ENCODING_SET
);
2464 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "map") == 0) {
2465 const char *clock_name
;
2467 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2468 _BT_COMP_LOGE_DUP_ATTR(left
, "map",
2469 "integer field class");
2474 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2475 _BT_COMP_LOGE_NODE(right
,
2476 "Invalid `map` attribute in integer field class: "
2477 "expecting unary string.");
2483 get_map_clock_name_value(
2484 &expression
->u
.ctf_expression
.right
);
2486 char *s_right
= ctf_ast_concatenate_unary_strings(
2487 &expression
->u
.ctf_expression
.right
);
2490 _BT_COMP_LOGE_NODE(right
,
2491 "Unexpected unary expression for integer field class's `map` attribute.");
2496 _BT_COMP_LOGE_NODE(right
,
2497 "Invalid `map` attribute in integer field class: "
2498 "cannot find clock class at this point: name=\"%s\"",
2500 _SET(&set
, _INTEGER_MAP_SET
);
2505 mapped_clock_class
=
2506 ctf_trace_class_borrow_clock_class_by_name(
2507 ctx
->ctf_tc
, clock_name
);
2508 if (!mapped_clock_class
) {
2509 _BT_COMP_LOGE_NODE(right
,
2510 "Invalid `map` attribute in integer field class: "
2511 "cannot find clock class at this point: name=\"%s\"",
2517 _SET(&set
, _INTEGER_MAP_SET
);
2519 _BT_COMP_LOGW_NODE(left
,
2520 "Unknown attribute in integer field class: "
2522 left
->u
.unary_expression
.u
.string
);
2526 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2527 BT_COMP_LOGE_STR("Missing `size` attribute in integer field class.");
2532 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2533 if (size
% CHAR_BIT
) {
2534 /* Bit-packed alignment */
2537 /* Byte-packed alignment */
2538 alignment
= CHAR_BIT
;
2542 *integer_decl
= ctf_field_class_int_create();
2543 BT_ASSERT(*integer_decl
);
2544 (*integer_decl
)->base
.base
.alignment
= alignment
;
2545 (*integer_decl
)->base
.byte_order
= byte_order
;
2546 (*integer_decl
)->base
.size
= size
;
2547 (*integer_decl
)->is_signed
= (signedness
> 0);
2548 (*integer_decl
)->disp_base
= base
;
2549 (*integer_decl
)->encoding
= encoding
;
2550 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2554 ctf_field_class_destroy((void *) *integer_decl
);
2555 *integer_decl
= NULL
;
2560 int visit_floating_point_number_decl(struct ctx
*ctx
,
2561 struct bt_list_head
*expressions
,
2562 struct ctf_field_class_float
**float_decl
)
2566 struct ctf_node
*expression
;
2567 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2568 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2572 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2573 struct ctf_node
*left
, *right
;
2575 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2576 struct ctf_node
, siblings
);
2577 right
= _BT_LIST_FIRST_ENTRY(
2578 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2581 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2582 _BT_COMP_LOGE_NODE(left
,
2583 "Unexpected unary expression type: type=%d",
2584 left
->u
.unary_expression
.type
);
2589 if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2590 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2591 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2592 "floating point number field class");
2597 byte_order
= get_real_byte_order(ctx
, right
);
2598 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2599 _BT_COMP_LOGE_NODE(right
,
2600 "Invalid `byte_order` attribute in floating point number field class: "
2606 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2607 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig") == 0) {
2608 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2609 _BT_COMP_LOGE_DUP_ATTR(left
, "exp_dig",
2610 "floating point number field class");
2615 if (right
->u
.unary_expression
.type
!=
2616 UNARY_UNSIGNED_CONSTANT
) {
2617 _BT_COMP_LOGE_NODE(right
,
2618 "Invalid `exp_dig` attribute in floating point number field class: "
2619 "expecting unsigned constant integer: "
2621 right
->u
.unary_expression
.type
);
2626 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2627 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2628 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig") == 0) {
2629 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2630 _BT_COMP_LOGE_DUP_ATTR(left
, "mant_dig",
2631 "floating point number field class");
2636 if (right
->u
.unary_expression
.type
!=
2637 UNARY_UNSIGNED_CONSTANT
) {
2638 _BT_COMP_LOGE_NODE(right
,
2639 "Invalid `mant_dig` attribute in floating point number field class: "
2640 "expecting unsigned constant integer: "
2642 right
->u
.unary_expression
.type
);
2647 mant_dig
= right
->u
.unary_expression
.u
.
2649 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2650 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2651 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2652 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2653 "floating point number field class");
2658 if (right
->u
.unary_expression
.type
!=
2659 UNARY_UNSIGNED_CONSTANT
) {
2660 _BT_COMP_LOGE_NODE(right
,
2661 "Invalid `align` attribute in floating point number field class: "
2662 "expecting unsigned constant integer: "
2664 right
->u
.unary_expression
.type
);
2669 alignment
= right
->u
.unary_expression
.u
.
2672 if (!is_align_valid(alignment
)) {
2673 _BT_COMP_LOGE_NODE(right
,
2674 "Invalid `align` attribute in floating point number field class: "
2675 "expecting power of two: "
2676 "align=%" PRIu64
, alignment
);
2681 _SET(&set
, _FLOAT_ALIGN_SET
);
2683 _BT_COMP_LOGW_NODE(left
,
2684 "Unknown attribute in floating point number field class: "
2686 left
->u
.unary_expression
.u
.string
);
2690 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2691 BT_COMP_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2696 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2697 BT_COMP_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2702 if (mant_dig
!= 24 && mant_dig
!= 53) {
2703 BT_COMP_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2708 if (mant_dig
== 24 && exp_dig
!= 8) {
2709 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2714 if (mant_dig
== 53 && exp_dig
!= 11) {
2715 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2720 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2721 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2722 /* Bit-packed alignment */
2725 /* Byte-packed alignment */
2726 alignment
= CHAR_BIT
;
2730 *float_decl
= ctf_field_class_float_create();
2731 BT_ASSERT(*float_decl
);
2732 (*float_decl
)->base
.base
.alignment
= alignment
;
2733 (*float_decl
)->base
.byte_order
= byte_order
;
2734 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2738 ctf_field_class_destroy((void *) *float_decl
);
2744 int visit_string_decl(struct ctx
*ctx
,
2745 struct bt_list_head
*expressions
,
2746 struct ctf_field_class_string
**string_decl
)
2750 struct ctf_node
*expression
;
2751 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2753 *string_decl
= NULL
;
2755 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2756 struct ctf_node
*left
, *right
;
2758 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2759 struct ctf_node
, siblings
);
2760 right
= _BT_LIST_FIRST_ENTRY(
2761 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2764 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2765 _BT_COMP_LOGE_NODE(left
,
2766 "Unexpected unary expression type: type=%d",
2767 left
->u
.unary_expression
.type
);
2772 if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2775 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2776 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2777 "string field class");
2782 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2783 _BT_COMP_LOGE_NODE(right
,
2784 "Invalid `encoding` attribute in string field class: "
2785 "expecting unary string.");
2790 s_right
= ctf_ast_concatenate_unary_strings(
2791 &expression
->u
.ctf_expression
.right
);
2793 _BT_COMP_LOGE_NODE(right
,
2794 "Unexpected unary expression for string field class's `encoding` attribute.");
2799 if (strcmp(s_right
, "UTF8") == 0 ||
2800 strcmp(s_right
, "utf8") == 0 ||
2801 strcmp(s_right
, "utf-8") == 0 ||
2802 strcmp(s_right
, "UTF-8") == 0 ||
2803 strcmp(s_right
, "ASCII") == 0 ||
2804 strcmp(s_right
, "ascii") == 0) {
2805 encoding
= CTF_ENCODING_UTF8
;
2806 } else if (strcmp(s_right
, "none") == 0) {
2807 encoding
= CTF_ENCODING_NONE
;
2809 _BT_COMP_LOGE_NODE(right
,
2810 "Invalid `encoding` attribute in string field class: "
2811 "unknown encoding: encoding=\"%s\"",
2819 _SET(&set
, _STRING_ENCODING_SET
);
2821 _BT_COMP_LOGW_NODE(left
,
2822 "Unknown attribute in string field class: "
2824 left
->u
.unary_expression
.u
.string
);
2828 *string_decl
= ctf_field_class_string_create();
2829 BT_ASSERT(*string_decl
);
2830 (*string_decl
)->encoding
= encoding
;
2834 ctf_field_class_destroy((void *) *string_decl
);
2835 *string_decl
= NULL
;
2840 int visit_field_class_specifier_list(struct ctx
*ctx
,
2841 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
2844 struct ctf_node
*first
, *node
;
2848 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
2849 _BT_COMP_LOGE_NODE(ts_list
,
2850 "Unexpected node type: node-type=%d", ts_list
->type
);
2855 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
2856 struct ctf_node
, siblings
);
2857 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
2858 _BT_COMP_LOGE_NODE(first
,
2859 "Unexpected node type: node-type=%d", first
->type
);
2864 node
= first
->u
.field_class_specifier
.node
;
2866 switch (first
->u
.field_class_specifier
.type
) {
2867 case TYPESPEC_INTEGER
:
2868 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
2875 case TYPESPEC_FLOATING_POINT
:
2876 ret
= visit_floating_point_number_decl(ctx
,
2877 &node
->u
.floating_point
.expressions
, (void *) decl
);
2883 case TYPESPEC_STRING
:
2884 ret
= visit_string_decl(ctx
,
2885 &node
->u
.string
.expressions
, (void *) decl
);
2891 case TYPESPEC_STRUCT
:
2892 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
2893 &node
->u
._struct
.declaration_list
,
2894 node
->u
._struct
.has_body
,
2895 &node
->u
._struct
.min_align
, (void *) decl
);
2901 case TYPESPEC_VARIANT
:
2902 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
2903 node
->u
.variant
.choice
,
2904 &node
->u
.variant
.declaration_list
,
2905 node
->u
.variant
.has_body
, (void *) decl
);
2912 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
2913 node
->u
._enum
.container_field_class
,
2914 &node
->u
._enum
.enumerator_list
,
2915 node
->u
._enum
.has_body
, (void *) decl
);
2923 case TYPESPEC_SHORT
:
2926 case TYPESPEC_FLOAT
:
2927 case TYPESPEC_DOUBLE
:
2928 case TYPESPEC_SIGNED
:
2929 case TYPESPEC_UNSIGNED
:
2931 case TYPESPEC_COMPLEX
:
2932 case TYPESPEC_IMAGINARY
:
2933 case TYPESPEC_CONST
:
2934 case TYPESPEC_ID_TYPE
:
2935 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
2937 _BT_COMP_LOGE_NODE(first
,
2938 "Cannot visit field class specifier: ret=%d",
2945 _BT_COMP_LOGE_NODE(first
,
2946 "Unexpected field class specifier type: node-type=%d",
2947 first
->u
.field_class_specifier
.type
);
2956 ctf_field_class_destroy((void *) *decl
);
2962 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
2963 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
2969 switch (node
->type
) {
2971 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
2972 &node
->u
.field_class_def
.field_class_declarators
);
2974 _BT_COMP_LOGE_NODE(node
,
2975 "Cannot add field class found in event class.");
2979 case NODE_TYPEALIAS
:
2980 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
2981 node
->u
.field_class_alias
.alias
);
2983 _BT_COMP_LOGE_NODE(node
,
2984 "Cannot add field class alias found in event class.");
2988 case NODE_CTF_EXPRESSION
:
2990 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2992 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
2997 if (strcmp(left
, "name") == 0) {
2998 /* This is already known at this stage */
2999 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3000 _BT_COMP_LOGE_DUP_ATTR(node
, "name", "event class");
3005 _SET(set
, _EVENT_NAME_SET
);
3006 } else if (strcmp(left
, "id") == 0) {
3009 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3010 _BT_COMP_LOGE_DUP_ATTR(node
, "id", "event class");
3015 ret
= get_unary_unsigned(ctx
,
3016 &node
->u
.ctf_expression
.right
,
3018 /* Only read "id" if get_unary_unsigned() succeeded. */
3019 if (ret
|| (!ret
&& id
< 0)) {
3020 _BT_COMP_LOGE_NODE(node
,
3021 "Unexpected unary expression for event class's `id` attribute.");
3026 event_class
->id
= id
;
3027 _SET(set
, _EVENT_ID_SET
);
3028 } else if (strcmp(left
, "stream_id") == 0) {
3029 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3030 _BT_COMP_LOGE_DUP_ATTR(node
, "stream_id",
3036 ret
= get_unary_unsigned(ctx
,
3037 &node
->u
.ctf_expression
.right
, stream_id
);
3040 * Only read "stream_id" if get_unary_unsigned()
3044 _BT_COMP_LOGE_NODE(node
,
3045 "Unexpected unary expression for event class's `stream_id` attribute.");
3050 _SET(set
, _EVENT_STREAM_ID_SET
);
3051 } else if (strcmp(left
, "context") == 0) {
3052 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3053 _BT_COMP_LOGE_NODE(node
,
3054 "Duplicate `context` entry in event class.");
3059 ret
= visit_field_class_specifier_list(ctx
,
3060 _BT_LIST_FIRST_ENTRY(
3061 &node
->u
.ctf_expression
.right
,
3062 struct ctf_node
, siblings
),
3063 &event_class
->spec_context_fc
);
3065 _BT_COMP_LOGE_NODE(node
,
3066 "Cannot create event class's context field class.");
3070 BT_ASSERT(event_class
->spec_context_fc
);
3071 _SET(set
, _EVENT_CONTEXT_SET
);
3072 } else if (strcmp(left
, "fields") == 0) {
3073 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3074 _BT_COMP_LOGE_NODE(node
,
3075 "Duplicate `fields` entry in event class.");
3080 ret
= visit_field_class_specifier_list(ctx
,
3081 _BT_LIST_FIRST_ENTRY(
3082 &node
->u
.ctf_expression
.right
,
3083 struct ctf_node
, siblings
),
3084 &event_class
->payload_fc
);
3086 _BT_COMP_LOGE_NODE(node
,
3087 "Cannot create event class's payload field class.");
3091 BT_ASSERT(event_class
->payload_fc
);
3092 _SET(set
, _EVENT_FIELDS_SET
);
3093 } else if (strcmp(left
, "loglevel") == 0) {
3094 uint64_t loglevel_value
;
3095 bool is_log_level_known
= true;
3096 bt_event_class_log_level log_level
= -1;
3098 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3099 _BT_COMP_LOGE_DUP_ATTR(node
, "loglevel",
3105 ret
= get_unary_unsigned(ctx
,
3106 &node
->u
.ctf_expression
.right
, &loglevel_value
);
3108 _BT_COMP_LOGE_NODE(node
,
3109 "Unexpected unary expression for event class's `loglevel` attribute.");
3114 switch (loglevel_value
) {
3116 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3119 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3122 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3125 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3128 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3131 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3134 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3137 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3140 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3143 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3146 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3149 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3152 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3155 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3158 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3161 is_log_level_known
= false;
3162 _BT_COMP_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3163 "log-level=%" PRIu64
, loglevel_value
);
3166 if (is_log_level_known
) {
3167 ctf_event_class_set_log_level(event_class
, log_level
);
3170 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3171 } else if (strcmp(left
, "model.emf.uri") == 0) {
3174 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3175 _BT_COMP_LOGE_DUP_ATTR(node
, "model.emf.uri",
3181 right
= ctf_ast_concatenate_unary_strings(
3182 &node
->u
.ctf_expression
.right
);
3184 _BT_COMP_LOGE_NODE(node
,
3185 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3190 if (strlen(right
) == 0) {
3191 _BT_COMP_LOGW_NODE(node
,
3192 "Not setting event class's EMF URI because it's empty.");
3194 g_string_assign(event_class
->emf_uri
,
3199 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3201 _BT_COMP_LOGW_NODE(node
,
3202 "Unknown attribute in event class: "
3203 "attr-name=\"%s\"", left
);
3225 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3229 struct ctf_node
*iter
;
3230 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3232 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3233 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3237 left
= ctf_ast_concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3239 _BT_COMP_LOGE_NODE(iter
,
3240 "Cannot concatenate unary strings.");
3244 if (strcmp(left
, "name") == 0) {
3245 name
= ctf_ast_concatenate_unary_strings(
3246 &iter
->u
.ctf_expression
.right
);
3248 _BT_COMP_LOGE_NODE(iter
,
3249 "Unexpected unary expression for event class's `name` attribute.");
3270 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3274 struct ctf_node
*iter
;
3275 uint64_t stream_id
= 0;
3276 char *event_name
= NULL
;
3277 struct ctf_event_class
*event_class
= NULL
;
3278 struct ctf_stream_class
*stream_class
= NULL
;
3279 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3280 bool pop_scope
= false;
3282 if (node
->visited
) {
3286 node
->visited
= TRUE
;
3287 event_name
= get_event_decl_name(ctx
, node
);
3289 _BT_COMP_LOGE_NODE(node
,
3290 "Missing `name` attribute in event class.");
3295 event_class
= ctf_event_class_create();
3296 BT_ASSERT(event_class
);
3297 g_string_assign(event_class
->name
, event_name
);
3298 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3301 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3302 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3305 _BT_COMP_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3311 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3313 * Allow missing stream_id if there is only a single
3316 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3318 /* Create implicit stream class if there's none */
3320 stream_class
= ctf_stream_class_create();
3321 BT_ASSERT(stream_class
);
3322 stream_class
->id
= stream_id
;
3323 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3327 /* Single stream class: get its ID */
3328 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3329 stream_id
= stream_class
->id
;
3332 _BT_COMP_LOGE_NODE(node
,
3333 "Missing `stream_id` attribute in event class.");
3339 /* We have the stream ID now; get the stream class if found */
3340 if (!stream_class
) {
3341 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3342 ctx
->ctf_tc
, stream_id
);
3343 if (!stream_class
) {
3344 _BT_COMP_LOGE_NODE(node
,
3345 "Cannot find stream class at this point: "
3346 "id=%" PRId64
, stream_id
);
3352 BT_ASSERT(stream_class
);
3354 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3355 /* Allow only one event without ID per stream */
3356 if (stream_class
->event_classes
->len
!= 0) {
3357 _BT_COMP_LOGE_NODE(node
,
3358 "Missing `id` attribute in event class.");
3364 event_class
->id
= 0;
3367 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3369 _BT_COMP_LOGE_NODE(node
,
3370 "Duplicate event class (same ID) in the same stream class: "
3371 "id=%" PRId64
, event_class
->id
);
3376 ctf_stream_class_append_event_class(stream_class
, event_class
);
3381 ctf_event_class_destroy(event_class
);
3399 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3400 struct ctf_field_class
*fc
)
3402 struct ctf_clock_class
*clock_class_to_map_to
= NULL
;
3403 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3405 uint64_t clock_class_count
;
3411 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3412 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3416 if (int_fc
->mapped_clock_class
) {
3417 /* Already mapped */
3421 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3423 switch (clock_class_count
) {
3426 * No clock class exists in the trace at this point. Create an
3427 * implicit one at 1 GHz, named `default`, and use this clock
3430 clock_class_to_map_to
= ctf_clock_class_create();
3431 BT_ASSERT(clock_class_to_map_to
);
3432 clock_class_to_map_to
->frequency
= UINT64_C(1000000000);
3433 g_string_assign(clock_class_to_map_to
->name
, "default");
3434 BT_ASSERT(ret
== 0);
3435 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3436 clock_class_to_map_to
);
3440 * Only one clock class exists in the trace at this point: use
3443 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3447 * Timestamp field not mapped to a clock class and there's more
3448 * than one clock class in the trace: this is an error.
3450 BT_COMP_LOGE_STR("Timestamp field found with no mapped clock class, "
3451 "but there's more than one clock class in the trace at this point.");
3456 BT_ASSERT(clock_class_to_map_to
);
3457 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3464 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3465 struct ctf_field_class
*root_fc
, const char *field_name
)
3469 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3470 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3476 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3477 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3481 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3482 count
= struct_fc
->members
->len
;
3484 count
= var_fc
->options
->len
;
3487 for (i
= 0; i
< count
; i
++) {
3488 struct ctf_named_field_class
*named_fc
= NULL
;
3490 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3491 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3493 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3494 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3498 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3499 ret
= auto_map_field_to_trace_clock_class(ctx
,
3502 BT_COMP_LOGE("Cannot automatically map field to trace's clock class: "
3503 "field-name=\"%s\"", field_name
);
3508 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3511 BT_COMP_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3512 "field-name=\"%s\", root-field-name=\"%s\"",
3513 field_name
, named_fc
->name
->str
);
3523 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3524 struct ctf_stream_class
*stream_class
, int *set
)
3529 switch (node
->type
) {
3531 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3532 &node
->u
.field_class_def
.field_class_declarators
);
3534 _BT_COMP_LOGE_NODE(node
,
3535 "Cannot add field class found in stream class.");
3539 case NODE_TYPEALIAS
:
3540 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3541 node
->u
.field_class_alias
.alias
);
3543 _BT_COMP_LOGE_NODE(node
,
3544 "Cannot add field class alias found in stream class.");
3548 case NODE_CTF_EXPRESSION
:
3550 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3552 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3557 if (strcmp(left
, "id") == 0) {
3560 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3561 _BT_COMP_LOGE_DUP_ATTR(node
, "id",
3562 "stream declaration");
3567 ret
= get_unary_unsigned(ctx
,
3568 &node
->u
.ctf_expression
.right
,
3571 /* Only read "id" if get_unary_unsigned() succeeded. */
3572 if (ret
|| (!ret
&& id
< 0)) {
3573 _BT_COMP_LOGE_NODE(node
,
3574 "Unexpected unary expression for stream class's `id` attribute.");
3579 if (ctf_trace_class_borrow_stream_class_by_id(
3581 _BT_COMP_LOGE_NODE(node
,
3582 "Duplicate stream class (same ID): id=%" PRId64
,
3588 stream_class
->id
= id
;
3589 _SET(set
, _STREAM_ID_SET
);
3590 } else if (strcmp(left
, "event.header") == 0) {
3591 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3592 _BT_COMP_LOGE_NODE(node
,
3593 "Duplicate `event.header` entry in stream class.");
3598 ret
= visit_field_class_specifier_list(ctx
,
3599 _BT_LIST_FIRST_ENTRY(
3600 &node
->u
.ctf_expression
.right
,
3601 struct ctf_node
, siblings
),
3602 &stream_class
->event_header_fc
);
3604 _BT_COMP_LOGE_NODE(node
,
3605 "Cannot create stream class's event header field class.");
3609 BT_ASSERT(stream_class
->event_header_fc
);
3610 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3611 stream_class
->event_header_fc
, "timestamp");
3613 _BT_COMP_LOGE_NODE(node
,
3614 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3618 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3619 } else if (strcmp(left
, "event.context") == 0) {
3620 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3621 _BT_COMP_LOGE_NODE(node
,
3622 "Duplicate `event.context` entry in stream class.");
3627 ret
= visit_field_class_specifier_list(ctx
,
3628 _BT_LIST_FIRST_ENTRY(
3629 &node
->u
.ctf_expression
.right
,
3630 struct ctf_node
, siblings
),
3631 &stream_class
->event_common_context_fc
);
3633 _BT_COMP_LOGE_NODE(node
,
3634 "Cannot create stream class's event context field class.");
3638 BT_ASSERT(stream_class
->event_common_context_fc
);
3639 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3640 } else if (strcmp(left
, "packet.context") == 0) {
3641 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3642 _BT_COMP_LOGE_NODE(node
,
3643 "Duplicate `packet.context` entry in stream class.");
3648 ret
= visit_field_class_specifier_list(ctx
,
3649 _BT_LIST_FIRST_ENTRY(
3650 &node
->u
.ctf_expression
.right
,
3651 struct ctf_node
, siblings
),
3652 &stream_class
->packet_context_fc
);
3654 _BT_COMP_LOGE_NODE(node
,
3655 "Cannot create stream class's packet context field class.");
3659 BT_ASSERT(stream_class
->packet_context_fc
);
3660 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3661 stream_class
->packet_context_fc
,
3664 _BT_COMP_LOGE_NODE(node
,
3665 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3669 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3670 stream_class
->packet_context_fc
,
3673 _BT_COMP_LOGE_NODE(node
,
3674 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3678 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3680 _BT_COMP_LOGW_NODE(node
,
3681 "Unknown attribute in stream class: "
3682 "attr-name=\"%s\"", left
);
3703 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3707 struct ctf_node
*iter
;
3708 struct ctf_stream_class
*stream_class
= NULL
;
3709 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3711 if (node
->visited
) {
3715 node
->visited
= TRUE
;
3716 stream_class
= ctf_stream_class_create();
3717 BT_ASSERT(stream_class
);
3718 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3720 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3721 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3723 _BT_COMP_LOGE_NODE(iter
,
3724 "Cannot visit stream class's entry: "
3733 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3734 /* Check that packet header has `stream_id` field */
3735 struct ctf_named_field_class
*named_fc
= NULL
;
3737 if (!ctx
->ctf_tc
->packet_header_fc
) {
3738 _BT_COMP_LOGE_NODE(node
,
3739 "Stream class has a `id` attribute, "
3740 "but trace has no packet header field class.");
3744 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3745 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3747 _BT_COMP_LOGE_NODE(node
,
3748 "Stream class has a `id` attribute, "
3749 "but trace's packet header field class has no `stream_id` field.");
3753 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3754 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3755 _BT_COMP_LOGE_NODE(node
,
3756 "Stream class has a `id` attribute, "
3757 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3761 /* Allow only _one_ ID-less stream */
3762 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3763 _BT_COMP_LOGE_NODE(node
,
3764 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3769 /* Automatic ID: 0 */
3770 stream_class
->id
= 0;
3774 * Make sure that this stream class's ID is currently unique in
3777 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3778 stream_class
->id
)) {
3779 _BT_COMP_LOGE_NODE(node
,
3780 "Duplicate stream class (same ID): id=%" PRId64
,
3786 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3787 stream_class
= NULL
;
3791 ctf_stream_class_destroy(stream_class
);
3792 stream_class
= NULL
;
3799 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3805 switch (node
->type
) {
3807 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3808 &node
->u
.field_class_def
.field_class_declarators
);
3810 _BT_COMP_LOGE_NODE(node
,
3811 "Cannot add field class found in trace (`trace` block).");
3815 case NODE_TYPEALIAS
:
3816 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3817 node
->u
.field_class_alias
.alias
);
3819 _BT_COMP_LOGE_NODE(node
,
3820 "Cannot add field class alias found in trace (`trace` block).");
3824 case NODE_CTF_EXPRESSION
:
3826 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3828 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3833 if (strcmp(left
, "major") == 0) {
3834 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
3835 _BT_COMP_LOGE_DUP_ATTR(node
, "major", "trace");
3840 ret
= get_unary_unsigned(ctx
,
3841 &node
->u
.ctf_expression
.right
, &val
);
3843 _BT_COMP_LOGE_NODE(node
,
3844 "Unexpected unary expression for trace's `major` attribute.");
3850 _BT_COMP_LOGE_NODE(node
,
3851 "Invalid trace's `minor` attribute: expecting 1.");
3855 ctx
->ctf_tc
->major
= val
;
3856 _SET(set
, _TRACE_MAJOR_SET
);
3857 } else if (strcmp(left
, "minor") == 0) {
3858 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
3859 _BT_COMP_LOGE_DUP_ATTR(node
, "minor", "trace");
3864 ret
= get_unary_unsigned(ctx
,
3865 &node
->u
.ctf_expression
.right
, &val
);
3867 _BT_COMP_LOGE_NODE(node
,
3868 "Unexpected unary expression for trace's `minor` attribute.");
3874 _BT_COMP_LOGE_NODE(node
,
3875 "Invalid trace's `minor` attribute: expecting 8.");
3879 ctx
->ctf_tc
->minor
= val
;
3880 _SET(set
, _TRACE_MINOR_SET
);
3881 } else if (strcmp(left
, "uuid") == 0) {
3882 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
3883 _BT_COMP_LOGE_DUP_ATTR(node
, "uuid", "trace");
3888 ret
= get_unary_uuid(ctx
,
3889 &node
->u
.ctf_expression
.right
,
3892 _BT_COMP_LOGE_NODE(node
,
3893 "Invalid trace's `uuid` attribute.");
3897 ctx
->ctf_tc
->is_uuid_set
= true;
3898 _SET(set
, _TRACE_UUID_SET
);
3899 } else if (strcmp(left
, "byte_order") == 0) {
3900 /* Default byte order is already known at this stage */
3901 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
3902 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
3908 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= CTF_BYTE_ORDER_UNKNOWN
);
3909 _SET(set
, _TRACE_BYTE_ORDER_SET
);
3910 } else if (strcmp(left
, "packet.header") == 0) {
3911 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
3912 _BT_COMP_LOGE_NODE(node
,
3913 "Duplicate `packet.header` entry in trace.");
3918 ret
= visit_field_class_specifier_list(ctx
,
3919 _BT_LIST_FIRST_ENTRY(
3920 &node
->u
.ctf_expression
.right
,
3921 struct ctf_node
, siblings
),
3922 &ctx
->ctf_tc
->packet_header_fc
);
3924 _BT_COMP_LOGE_NODE(node
,
3925 "Cannot create trace's packet header field class.");
3929 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
3930 _SET(set
, _TRACE_PACKET_HEADER_SET
);
3932 _BT_COMP_LOGW_NODE(node
,
3933 "Unknown attribute in stream class: "
3934 "attr-name=\"%s\"", left
);
3942 _BT_COMP_LOGE_NODE(node
, "Unknown expression in trace.");
3955 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3959 struct ctf_node
*iter
;
3960 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
3962 if (node
->visited
) {
3966 node
->visited
= TRUE
;
3968 if (ctx
->is_trace_visited
) {
3969 _BT_COMP_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
3974 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3976 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3977 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
3979 _BT_COMP_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
3988 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
3989 _BT_COMP_LOGE_NODE(node
,
3990 "Missing `major` attribute in trace (`trace` block).");
3995 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
3996 _BT_COMP_LOGE_NODE(node
,
3997 "Missing `minor` attribute in trace (`trace` block).");
4002 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4003 _BT_COMP_LOGE_NODE(node
,
4004 "Missing `byte_order` attribute in trace (`trace` block).");
4009 ctx
->is_trace_visited
= true;
4019 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4023 struct ctf_node
*entry_node
;
4024 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4026 if (node
->visited
) {
4030 node
->visited
= TRUE
;
4032 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4033 struct bt_list_head
*right_head
=
4034 &entry_node
->u
.ctf_expression
.right
;
4036 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4037 _BT_COMP_LOGE_NODE(entry_node
,
4038 "Wrong expression in environment entry: "
4039 "node-type=%d", entry_node
->type
);
4044 left
= ctf_ast_concatenate_unary_strings(
4045 &entry_node
->u
.ctf_expression
.left
);
4047 _BT_COMP_LOGE_NODE(entry_node
,
4048 "Cannot get environment entry's name.");
4053 if (is_unary_string(right_head
)) {
4054 char *right
= ctf_ast_concatenate_unary_strings(right_head
);
4057 _BT_COMP_LOGE_NODE(entry_node
,
4058 "Unexpected unary expression for environment entry's value: "
4059 "name=\"%s\"", left
);
4064 if (strcmp(left
, "tracer_name") == 0) {
4065 if (strncmp(right
, "lttng", 5) == 0) {
4066 BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
4067 "tracer-name=\"%s\"",
4069 ctx
->is_lttng
= true;
4073 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4074 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4077 } else if (is_unary_unsigned(right_head
) ||
4078 is_unary_signed(right_head
)) {
4081 if (is_unary_unsigned(right_head
)) {
4082 ret
= get_unary_unsigned(ctx
, right_head
,
4085 ret
= get_unary_signed(right_head
, &v
);
4088 _BT_COMP_LOGE_NODE(entry_node
,
4089 "Unexpected unary expression for environment entry's value: "
4090 "name=\"%s\"", left
);
4095 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4096 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4099 _BT_COMP_LOGW_NODE(entry_node
,
4100 "Environment entry has unknown type: "
4101 "name=\"%s\"", left
);
4117 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4122 struct ctf_node
*node
;
4123 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4125 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4126 if (node
->type
== NODE_CTF_EXPRESSION
) {
4127 struct ctf_node
*right_node
;
4129 left
= ctf_ast_concatenate_unary_strings(
4130 &node
->u
.ctf_expression
.left
);
4132 _BT_COMP_LOGE_NODE(node
,
4133 "Cannot concatenate unary strings.");
4138 if (strcmp(left
, "byte_order") == 0) {
4139 enum ctf_byte_order bo
;
4141 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4142 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
4148 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4149 right_node
= _BT_LIST_FIRST_ENTRY(
4150 &node
->u
.ctf_expression
.right
,
4151 struct ctf_node
, siblings
);
4152 bo
= byte_order_from_unary_expr(ctx
,
4154 if (bo
== CTF_BYTE_ORDER_UNKNOWN
) {
4155 _BT_COMP_LOGE_NODE(node
,
4156 "Invalid `byte_order` attribute in trace (`trace` block): "
4157 "expecting `le`, `be`, or `network`.");
4160 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4161 _BT_COMP_LOGE_NODE(node
,
4162 "Invalid `byte_order` attribute in trace (`trace` block): "
4163 "cannot be set to `native` here.");
4168 ctx
->ctf_tc
->default_byte_order
= bo
;
4176 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4177 _BT_COMP_LOGE_NODE(trace_node
,
4178 "Missing `byte_order` attribute in trace (`trace` block).");
4191 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4192 struct ctf_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4193 uint64_t *offset_cycles
)
4198 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4199 _BT_COMP_LOGE_NODE(entry_node
,
4200 "Unexpected node type: node-type=%d",
4206 left
= ctf_ast_concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4208 _BT_COMP_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4213 if (strcmp(left
, "name") == 0) {
4216 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4217 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4222 right
= ctf_ast_concatenate_unary_strings(
4223 &entry_node
->u
.ctf_expression
.right
);
4225 _BT_COMP_LOGE_NODE(entry_node
,
4226 "Unexpected unary expression for clock class's `name` attribute.");
4231 g_string_assign(clock
->name
, right
);
4233 _SET(set
, _CLOCK_NAME_SET
);
4234 } else if (strcmp(left
, "uuid") == 0) {
4237 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4238 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4243 ret
= get_unary_uuid(ctx
, &entry_node
->u
.ctf_expression
.right
,
4246 _BT_COMP_LOGE_NODE(entry_node
,
4247 "Invalid clock class's `uuid` attribute.");
4251 clock
->has_uuid
= true;
4252 bt_uuid_copy(clock
->uuid
, uuid
);
4253 _SET(set
, _CLOCK_UUID_SET
);
4254 } else if (strcmp(left
, "description") == 0) {
4257 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4258 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "description",
4264 right
= ctf_ast_concatenate_unary_strings(
4265 &entry_node
->u
.ctf_expression
.right
);
4267 _BT_COMP_LOGE_NODE(entry_node
,
4268 "Unexpected unary expression for clock class's `description` attribute.");
4273 g_string_assign(clock
->description
, right
);
4275 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4276 } else if (strcmp(left
, "freq") == 0) {
4277 uint64_t freq
= UINT64_C(-1);
4279 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4280 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4285 ret
= get_unary_unsigned(ctx
,
4286 &entry_node
->u
.ctf_expression
.right
, &freq
);
4288 _BT_COMP_LOGE_NODE(entry_node
,
4289 "Unexpected unary expression for clock class's `freq` attribute.");
4294 if (freq
== UINT64_C(-1) || freq
== 0) {
4295 _BT_COMP_LOGE_NODE(entry_node
,
4296 "Invalid clock class frequency: freq=%" PRIu64
,
4302 clock
->frequency
= freq
;
4303 _SET(set
, _CLOCK_FREQ_SET
);
4304 } else if (strcmp(left
, "precision") == 0) {
4307 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4308 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "precision",
4314 ret
= get_unary_unsigned(ctx
,
4315 &entry_node
->u
.ctf_expression
.right
, &precision
);
4317 _BT_COMP_LOGE_NODE(entry_node
,
4318 "Unexpected unary expression for clock class's `precision` attribute.");
4323 clock
->precision
= precision
;
4324 _SET(set
, _CLOCK_PRECISION_SET
);
4325 } else if (strcmp(left
, "offset_s") == 0) {
4326 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4327 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset_s",
4333 ret
= get_unary_signed(
4334 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4336 _BT_COMP_LOGE_NODE(entry_node
,
4337 "Unexpected unary expression for clock class's `offset_s` attribute.");
4342 _SET(set
, _CLOCK_OFFSET_S_SET
);
4343 } else if (strcmp(left
, "offset") == 0) {
4344 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4345 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4350 ret
= get_unary_unsigned(ctx
,
4351 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4353 _BT_COMP_LOGE_NODE(entry_node
,
4354 "Unexpected unary expression for clock class's `offset` attribute.");
4359 _SET(set
, _CLOCK_OFFSET_SET
);
4360 } else if (strcmp(left
, "absolute") == 0) {
4361 struct ctf_node
*right
;
4363 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4364 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "absolute",
4370 right
= _BT_LIST_FIRST_ENTRY(
4371 &entry_node
->u
.ctf_expression
.right
,
4372 struct ctf_node
, siblings
);
4373 ret
= get_boolean(ctx
, right
);
4375 _BT_COMP_LOGE_NODE(entry_node
,
4376 "Unexpected unary expression for clock class's `absolute` attribute.");
4381 clock
->is_absolute
= ret
;
4382 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4384 _BT_COMP_LOGW_NODE(entry_node
,
4385 "Unknown attribute in clock class: attr-name=\"%s\"",
4399 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4404 if (frequency
== UINT64_C(1000000000)) {
4407 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4414 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4415 uint64_t *offset_cycles
, uint64_t freq
)
4417 if (*offset_cycles
>= freq
) {
4418 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4420 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4421 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4426 void apply_clock_class_is_absolute(struct ctx
*ctx
,
4427 struct ctf_clock_class
*clock
)
4429 if (ctx
->decoder_config
.force_clock_class_origin_unix_epoch
) {
4430 clock
->is_absolute
= true;
4437 void apply_clock_class_offset(struct ctx
*ctx
,
4438 struct ctf_clock_class
*clock
)
4441 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4442 uint64_t offset_ns_to_apply
;
4443 int64_t cur_offset_s
;
4444 uint64_t cur_offset_cycles
;
4446 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4447 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4451 /* Transfer nanoseconds to seconds as much as possible */
4452 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4453 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4454 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4455 const int64_t extra_s
= -abs_extra_s
;
4456 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4457 (extra_s
* INT64_C(1000000000));
4459 BT_ASSERT(offset_ns
> 0);
4460 offset_ns_to_apply
= (uint64_t) offset_ns
;
4461 offset_s_to_apply
+= extra_s
;
4463 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4464 INT64_C(1000000000);
4465 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4466 (extra_s
* INT64_C(1000000000));
4468 BT_ASSERT(offset_ns
>= 0);
4469 offset_ns_to_apply
= (uint64_t) offset_ns
;
4470 offset_s_to_apply
+= extra_s
;
4473 freq
= clock
->frequency
;
4474 cur_offset_s
= clock
->offset_seconds
;
4475 cur_offset_cycles
= clock
->offset_cycles
;
4478 cur_offset_s
+= offset_s_to_apply
;
4479 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4482 * Recalibrate offsets because the part in cycles can be greater
4483 * than the frequency at this point.
4485 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4487 /* Set final offsets */
4488 clock
->offset_seconds
= cur_offset_s
;
4489 clock
->offset_cycles
= cur_offset_cycles
;
4496 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4500 struct ctf_clock_class
*clock
;
4501 struct ctf_node
*entry_node
;
4502 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4503 const char *clock_class_name
;
4504 int64_t offset_seconds
= 0;
4505 uint64_t offset_cycles
= 0;
4508 if (clock_node
->visited
) {
4512 clock_node
->visited
= TRUE
;
4514 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4515 clock
= ctf_clock_class_create();
4517 _BT_COMP_LOGE_NODE(clock_node
,
4518 "Cannot create default clock class.");
4523 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4524 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4525 &offset_seconds
, &offset_cycles
);
4527 _BT_COMP_LOGE_NODE(entry_node
,
4528 "Cannot visit clock class's entry: ret=%d",
4534 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4535 _BT_COMP_LOGE_NODE(clock_node
,
4536 "Missing `name` attribute in clock class.");
4541 clock_class_name
= clock
->name
->str
;
4542 BT_ASSERT(clock_class_name
);
4543 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4545 * Old versions of LTTng forgot to set its clock class
4546 * as absolute, even if it is. This is important because
4547 * it's a condition to be able to sort messages
4548 * from different sources.
4550 clock
->is_absolute
= true;
4554 * Adjust offsets so that the part in cycles is less than the
4555 * frequency (move to the part in seconds).
4557 freq
= clock
->frequency
;
4558 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4559 BT_ASSERT(offset_cycles
< clock
->frequency
);
4560 clock
->offset_seconds
= offset_seconds
;
4561 clock
->offset_cycles
= offset_cycles
;
4562 apply_clock_class_offset(ctx
, clock
);
4563 apply_clock_class_is_absolute(ctx
, clock
);
4564 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4569 ctf_clock_class_destroy(clock
);
4576 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4580 if (root_decl_node
->visited
) {
4584 root_decl_node
->visited
= TRUE
;
4586 switch (root_decl_node
->type
) {
4588 ret
= visit_field_class_def(ctx
,
4589 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4590 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4592 _BT_COMP_LOGE_NODE(root_decl_node
,
4593 "Cannot add field class found in root scope.");
4597 case NODE_TYPEALIAS
:
4598 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4599 root_decl_node
->u
.field_class_alias
.alias
);
4601 _BT_COMP_LOGE_NODE(root_decl_node
,
4602 "Cannot add field class alias found in root scope.");
4606 case NODE_TYPE_SPECIFIER_LIST
:
4608 struct ctf_field_class
*decl
= NULL
;
4611 * Just add the field class specifier to the root
4612 * declaration scope. Put local reference.
4614 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4616 _BT_COMP_LOGE_NODE(root_decl_node
,
4617 "Cannot visit root scope's field class: "
4623 ctf_field_class_destroy(decl
);
4628 _BT_COMP_LOGE_NODE(root_decl_node
,
4629 "Unexpected node type: node-type=%d",
4630 root_decl_node
->type
);
4640 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4641 const struct ctf_metadata_decoder_config
*decoder_config
)
4643 struct ctx
*ctx
= NULL
;
4645 /* Create visitor's context */
4646 ctx
= ctx_create(decoder_config
);
4648 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
4649 decoder_config
->self_comp
,
4650 "Cannot create visitor's context.");
4661 return (void *) ctx
;
4665 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4667 ctx_destroy((void *) visitor
);
4671 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4672 struct ctf_visitor_generate_ir
*visitor
)
4674 struct ctx
*ctx
= (void *) visitor
;
4678 if (ctx
->trace_class
) {
4679 bt_trace_class_get_ref(ctx
->trace_class
);
4682 return ctx
->trace_class
;
4686 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4687 struct ctf_visitor_generate_ir
*visitor
)
4689 struct ctx
*ctx
= (void *) visitor
;
4692 BT_ASSERT_DBG(ctx
->ctf_tc
);
4697 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4698 struct ctf_node
*node
)
4701 struct ctx
*ctx
= (void *) visitor
;
4703 BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4705 switch (node
->type
) {
4708 struct ctf_node
*iter
;
4709 bool got_trace_decl
= false;
4712 * The first thing we need is the native byte order of
4713 * the trace block, because early class aliases can have
4714 * a `byte_order` attribute set to `native`. If we don't
4715 * have the native byte order yet, and we don't have any
4716 * trace block yet, then fail with EINCOMPLETE.
4718 if (ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
4719 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4720 if (got_trace_decl
) {
4721 _BT_COMP_LOGE_NODE(node
,
4722 "Duplicate trace (`trace` block).");
4727 ret
= set_trace_byte_order(ctx
, iter
);
4729 _BT_COMP_LOGE_NODE(node
,
4730 "Cannot set trace's native byte order: "
4735 got_trace_decl
= true;
4738 if (!got_trace_decl
) {
4739 BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4745 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4746 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4747 BT_ASSERT(ctx
->current_scope
&&
4748 !ctx
->current_scope
->parent_scope
);
4751 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4752 ret
= visit_env(ctx
, iter
);
4754 _BT_COMP_LOGE_NODE(iter
,
4755 "Cannot visit trace's environment (`env` block) entry: "
4761 BT_ASSERT(ctx
->current_scope
&&
4762 !ctx
->current_scope
->parent_scope
);
4765 * Visit clock blocks.
4767 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4768 ret
= visit_clock_decl(ctx
, iter
);
4770 _BT_COMP_LOGE_NODE(iter
,
4771 "Cannot visit clock class: ret=%d",
4777 BT_ASSERT(ctx
->current_scope
&&
4778 !ctx
->current_scope
->parent_scope
);
4781 * Visit root declarations next, as they can be used by any
4784 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4786 ret
= visit_root_decl(ctx
, iter
);
4788 _BT_COMP_LOGE_NODE(iter
,
4789 "Cannot visit root entry: ret=%d",
4795 BT_ASSERT(ctx
->current_scope
&&
4796 !ctx
->current_scope
->parent_scope
);
4798 /* Callsite blocks are not supported */
4799 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4800 _BT_COMP_LOGW_NODE(iter
,
4801 "\"callsite\" blocks are not supported as of this version.");
4804 BT_ASSERT(ctx
->current_scope
&&
4805 !ctx
->current_scope
->parent_scope
);
4808 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4809 ret
= visit_trace_decl(ctx
, iter
);
4811 _BT_COMP_LOGE_NODE(iter
,
4812 "Cannot visit trace (`trace` block): "
4818 BT_ASSERT(ctx
->current_scope
&&
4819 !ctx
->current_scope
->parent_scope
);
4822 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4823 ret
= visit_stream_decl(ctx
, iter
);
4825 _BT_COMP_LOGE_NODE(iter
,
4826 "Cannot visit stream class: ret=%d",
4832 BT_ASSERT(ctx
->current_scope
&&
4833 !ctx
->current_scope
->parent_scope
);
4836 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4837 ret
= visit_event_decl(ctx
, iter
);
4839 _BT_COMP_LOGE_NODE(iter
,
4840 "Cannot visit event class: ret=%d",
4846 BT_ASSERT(ctx
->current_scope
&&
4847 !ctx
->current_scope
->parent_scope
);
4851 _BT_COMP_LOGE_NODE(node
,
4852 "Unexpected node type: node-type=%d",
4858 /* Update default clock classes */
4859 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
,
4866 /* Update trace class meanings */
4867 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
4873 /* Update stream class configuration */
4874 ret
= ctf_trace_class_update_stream_class_config(ctx
->ctf_tc
);
4880 /* Update text arrays and sequences */
4881 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
4887 /* Resolve sequence lengths and variant tags */
4888 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
, &ctx
->log_cfg
);
4894 if (ctx
->trace_class
) {
4896 * Update "in IR" for field classes.
4898 * If we have no IR trace class, then we'll have no way
4899 * to create IR fields anyway, so we leave all the
4900 * `in_ir` members false.
4902 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
4909 /* Update saved value indexes */
4910 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
4916 /* Validate what we have so far */
4917 ret
= ctf_trace_class_validate(ctx
->ctf_tc
, &ctx
->log_cfg
);
4924 * If there are fields which are not related to the CTF format
4925 * itself in the packet header and in event header field
4926 * classes, warn about it because they are never translated.
4928 ctf_trace_class_warn_meaningless_header_fields(ctx
->ctf_tc
,
4931 if (ctx
->trace_class
) {
4932 /* Copy new CTF metadata -> new IR metadata */
4933 ret
= ctf_trace_class_translate(ctx
->log_cfg
.self_comp
,
4934 ctx
->trace_class
, ctx
->ctf_tc
);