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>
56 #include "ctf-meta-visitors.h"
58 /* Bit value (left shift) */
59 #define _BV(_val) (1 << (_val))
61 /* Bit is set in a set of bits */
62 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
64 /* Set bit in a set of bits */
65 #define _SET(_set, _mask) (*(_set) |= (_mask))
67 /* Try to push scope, or go to the `error` label */
68 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
70 ret = ctx_push_scope(ctx); \
72 BT_COMP_LOGE_STR("Cannot push scope."); \
77 /* Bits for verifying existing attributes in various declarations */
79 _CLOCK_NAME_SET
= _BV(0),
80 _CLOCK_UUID_SET
= _BV(1),
81 _CLOCK_FREQ_SET
= _BV(2),
82 _CLOCK_PRECISION_SET
= _BV(3),
83 _CLOCK_OFFSET_S_SET
= _BV(4),
84 _CLOCK_OFFSET_SET
= _BV(5),
85 _CLOCK_ABSOLUTE_SET
= _BV(6),
86 _CLOCK_DESCRIPTION_SET
= _BV(7),
90 _INTEGER_ALIGN_SET
= _BV(0),
91 _INTEGER_SIZE_SET
= _BV(1),
92 _INTEGER_BASE_SET
= _BV(2),
93 _INTEGER_ENCODING_SET
= _BV(3),
94 _INTEGER_BYTE_ORDER_SET
= _BV(4),
95 _INTEGER_SIGNED_SET
= _BV(5),
96 _INTEGER_MAP_SET
= _BV(6),
100 _FLOAT_ALIGN_SET
= _BV(0),
101 _FLOAT_MANT_DIG_SET
= _BV(1),
102 _FLOAT_EXP_DIG_SET
= _BV(2),
103 _FLOAT_BYTE_ORDER_SET
= _BV(3),
107 _STRING_ENCODING_SET
= _BV(0),
111 _TRACE_MINOR_SET
= _BV(0),
112 _TRACE_MAJOR_SET
= _BV(1),
113 _TRACE_BYTE_ORDER_SET
= _BV(2),
114 _TRACE_UUID_SET
= _BV(3),
115 _TRACE_PACKET_HEADER_SET
= _BV(4),
119 _STREAM_ID_SET
= _BV(0),
120 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
121 _STREAM_EVENT_HEADER_SET
= _BV(2),
122 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
126 _EVENT_NAME_SET
= _BV(0),
127 _EVENT_ID_SET
= _BV(1),
128 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
129 _EVENT_STREAM_ID_SET
= _BV(3),
130 _EVENT_LOG_LEVEL_SET
= _BV(4),
131 _EVENT_CONTEXT_SET
= _BV(5),
132 _EVENT_FIELDS_SET
= _BV(6),
140 LOG_LEVEL_WARNING
= 4,
141 LOG_LEVEL_NOTICE
= 5,
143 LOG_LEVEL_DEBUG_SYSTEM
= 7,
144 LOG_LEVEL_DEBUG_PROGRAM
= 8,
145 LOG_LEVEL_DEBUG_PROCESS
= 9,
146 LOG_LEVEL_DEBUG_MODULE
= 10,
147 LOG_LEVEL_DEBUG_UNIT
= 11,
148 LOG_LEVEL_DEBUG_FUNCTION
= 12,
149 LOG_LEVEL_DEBUG_LINE
= 13,
150 LOG_LEVEL_DEBUG
= 14,
154 /* Prefixes of class aliases */
155 #define _PREFIX_ALIAS 'a'
156 #define _PREFIX_ENUM 'e'
157 #define _PREFIX_STRUCT 's'
158 #define _PREFIX_VARIANT 'v'
160 /* First entry in a BT list */
161 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
162 bt_list_entry((_ptr)->next, _class, _member)
164 #define _BT_COMP_LOGE_DUP_ATTR(_node, _attr, _entity) \
165 _BT_COMP_LOGE_LINENO((_node)->lineno, \
166 "Duplicate attribute in %s: attr-name=\"%s\"", \
169 #define _BT_COMP_LOGE_NODE(_node, _msg, args...) \
170 _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args)
172 #define _BT_COMP_LOGW_NODE(_node, _msg, args...) \
173 _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args)
175 #define _BT_COMP_LOGT_NODE(_node, _msg, args...) \
176 _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args)
179 * Declaration scope of a visitor context. This represents a TSDL
180 * lexical scope, so that aliases and named structures, variants,
181 * and enumerations may be registered and looked up hierarchically.
183 struct ctx_decl_scope
{
185 * Alias name to field class.
187 * GQuark -> struct ctf_field_class * (owned by this)
189 GHashTable
*decl_map
;
191 /* Parent scope; NULL if this is the root declaration scope */
192 struct ctx_decl_scope
*parent_scope
;
196 * Visitor context (private).
199 struct meta_log_config log_cfg
;
201 /* Trace IR trace class being filled (owned by this) */
202 bt_trace_class
*trace_class
;
204 /* CTF meta trace being filled (owned by this) */
205 struct ctf_trace_class
*ctf_tc
;
207 /* Current declaration scope (top of the stack) (owned by this) */
208 struct ctx_decl_scope
*current_scope
;
210 /* True if trace declaration is visited */
211 bool is_trace_visited
;
213 /* True if this is an LTTng trace */
216 /* Config passed by the user */
217 struct ctf_metadata_decoder_config decoder_config
;
223 struct ctf_visitor_generate_ir
;
226 * Creates a new declaration scope.
228 * @param par_scope Parent scope (NULL if creating a root scope)
229 * @returns New declaration scope, or NULL on error
232 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx
*ctx
,
233 struct ctx_decl_scope
*par_scope
)
235 struct ctx_decl_scope
*scope
;
237 scope
= g_new(struct ctx_decl_scope
, 1);
239 BT_COMP_LOGE_STR("Failed to allocate one declaration scope.");
243 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
244 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
245 scope
->parent_scope
= par_scope
;
252 * Destroys a declaration scope.
254 * This function does not destroy the parent scope.
256 * @param scope Scope to destroy
259 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
265 g_hash_table_destroy(scope
->decl_map
);
273 * Returns the GQuark of a prefixed alias.
275 * @param prefix Prefix character
277 * @returns Associated GQuark, or 0 on error
280 GQuark
get_prefixed_named_quark(struct ctx
*ctx
, char prefix
, const char *name
)
286 /* Prefix character + original string + '\0' */
287 char *prname
= g_new(char, strlen(name
) + 2);
289 BT_COMP_LOGE_STR("Failed to allocate a string.");
293 sprintf(prname
, "%c%s", prefix
, name
);
294 qname
= g_quark_from_string(prname
);
302 * Looks up a prefixed class alias within a declaration scope.
304 * @param scope Declaration scope
305 * @param prefix Prefix character
306 * @param name Alias name
307 * @param levels Number of levels to dig into (-1 means infinite)
308 * @param copy True to return a copy
309 * @returns Declaration (owned by caller if \p copy is true),
310 * or NULL if not found
313 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
314 struct ctx
*ctx
, struct ctx_decl_scope
*scope
, char prefix
,
315 const char *name
, int levels
, bool copy
)
319 struct ctf_field_class
*decl
= NULL
;
320 struct ctx_decl_scope
*cur_scope
= scope
;
324 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
333 while (cur_scope
&& cur_levels
< levels
) {
334 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
335 (gconstpointer
) GUINT_TO_POINTER(qname
));
337 /* Caller's reference */
339 decl
= ctf_field_class_copy(decl
);
346 cur_scope
= cur_scope
->parent_scope
;
355 * Looks up a class alias within a declaration scope.
357 * @param scope Declaration scope
358 * @param name Alias name
359 * @param levels Number of levels to dig into (-1 means infinite)
360 * @param copy True to return a copy
361 * @returns Declaration (owned by caller if \p copy is true),
362 * or NULL if not found
365 struct ctf_field_class
*ctx_decl_scope_lookup_alias(struct ctx
*ctx
,
366 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
369 return ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
374 * Looks up an enumeration within a declaration scope.
376 * @param scope Declaration scope
377 * @param name Enumeration name
378 * @param levels Number of levels to dig into (-1 means infinite)
379 * @param copy True to return a copy
380 * @returns Declaration (owned by caller if \p copy is true),
381 * or NULL if not found
384 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(struct ctx
*ctx
,
385 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
388 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
389 _PREFIX_ENUM
, name
, levels
, copy
);
393 * Looks up a structure within a declaration scope.
395 * @param scope Declaration scope
396 * @param name Structure name
397 * @param levels Number of levels to dig into (-1 means infinite)
398 * @param copy True to return a copy
399 * @returns Declaration (owned by caller if \p copy is true),
400 * or NULL if not found
403 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(struct ctx
*ctx
,
404 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
407 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
408 _PREFIX_STRUCT
, name
, levels
, copy
);
412 * Looks up a variant within a declaration scope.
414 * @param scope Declaration scope
415 * @param name Variant name
416 * @param levels Number of levels to dig into (-1 means infinite)
417 * @param copy True to return a copy
418 * @returns Declaration (owned by caller if \p copy is true),
419 * or NULL if not found
422 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(struct ctx
*ctx
,
423 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
426 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
427 _PREFIX_VARIANT
, name
, levels
, copy
);
431 * Registers a prefixed class alias within a declaration scope.
433 * @param scope Declaration scope
434 * @param prefix Prefix character
435 * @param name Alias name (non-NULL)
436 * @param decl Field class to register (copied)
437 * @returns 0 if registration went okay, negative value otherwise
440 int ctx_decl_scope_register_prefix_alias(struct ctx
*ctx
,
441 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
442 struct ctf_field_class
*decl
)
450 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
456 /* Make sure alias does not exist in local scope */
457 if (ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, prefix
, name
, 1,
463 decl
= ctf_field_class_copy(decl
);
465 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
472 * Registers a class alias within a declaration scope.
474 * @param scope Declaration scope
475 * @param name Alias name (non-NULL)
476 * @param decl Field class to register (copied)
477 * @returns 0 if registration went okay, negative value otherwise
480 int ctx_decl_scope_register_alias(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
481 const char *name
, struct ctf_field_class
*decl
)
483 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
484 name
, (void *) decl
);
488 * Registers an enumeration declaration within a declaration scope.
490 * @param scope Declaration scope
491 * @param name Enumeration name (non-NULL)
492 * @param decl Enumeration field class to register (copied)
493 * @returns 0 if registration went okay, negative value otherwise
496 int ctx_decl_scope_register_enum(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
497 const char *name
, struct ctf_field_class_enum
*decl
)
499 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ENUM
,
500 name
, (void *) decl
);
504 * Registers a structure declaration within a declaration scope.
506 * @param scope Declaration scope
507 * @param name Structure name (non-NULL)
508 * @param decl Structure field class to register (copied)
509 * @returns 0 if registration went okay, negative value otherwise
512 int ctx_decl_scope_register_struct(struct ctx
*ctx
,
513 struct ctx_decl_scope
*scope
, const char *name
,
514 struct ctf_field_class_struct
*decl
)
516 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_STRUCT
,
517 name
, (void *) decl
);
521 * Registers a variant declaration within a declaration scope.
523 * @param scope Declaration scope
524 * @param name Variant name (non-NULL)
525 * @param decl Variant field class to register
526 * @returns 0 if registration went okay, negative value otherwise
529 int ctx_decl_scope_register_variant(struct ctx
*ctx
,
530 struct ctx_decl_scope
*scope
, const char *name
,
531 struct ctf_field_class_variant
*decl
)
533 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_VARIANT
,
534 name
, (void *) decl
);
538 * Destroys a visitor context.
540 * @param ctx Visitor context to destroy
543 void ctx_destroy(struct ctx
*ctx
)
545 struct ctx_decl_scope
*scope
;
551 scope
= ctx
->current_scope
;
554 * Destroy all scopes, from current one to the root scope.
557 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
559 ctx_decl_scope_destroy(scope
);
560 scope
= parent_scope
;
563 bt_trace_class_put_ref(ctx
->trace_class
);
566 ctf_trace_class_destroy(ctx
->ctf_tc
);
576 * Creates a new visitor context.
578 * @param trace Associated trace
579 * @returns New visitor context, or NULL on error
582 struct ctx
*ctx_create(const struct ctf_metadata_decoder_config
*decoder_config
)
584 struct ctx
*ctx
= NULL
;
586 BT_ASSERT(decoder_config
);
588 ctx
= g_new0(struct ctx
, 1);
590 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
591 decoder_config
->self_comp
,
592 "Failed to allocate one visitor context.");
596 ctx
->log_cfg
.log_level
= decoder_config
->log_level
;
597 ctx
->log_cfg
.self_comp
= decoder_config
->self_comp
;
599 if (decoder_config
->self_comp
) {
600 ctx
->trace_class
= bt_trace_class_create(
601 decoder_config
->self_comp
);
602 if (!ctx
->trace_class
) {
603 BT_COMP_LOGE_STR("Cannot create empty trace class.");
608 ctx
->ctf_tc
= ctf_trace_class_create();
610 BT_COMP_LOGE_STR("Cannot create CTF trace class.");
614 /* Root declaration scope */
615 ctx
->current_scope
= ctx_decl_scope_create(ctx
, NULL
);
616 if (!ctx
->current_scope
) {
617 BT_COMP_LOGE_STR("Cannot create declaration scope.");
621 ctx
->decoder_config
= *decoder_config
;
633 * Pushes a new declaration scope on top of a visitor context's
634 * declaration scope stack.
636 * @param ctx Visitor context
637 * @returns 0 on success, or a negative value on error
640 int ctx_push_scope(struct ctx
*ctx
)
643 struct ctx_decl_scope
*new_scope
;
646 new_scope
= ctx_decl_scope_create(ctx
, ctx
->current_scope
);
648 BT_COMP_LOGE_STR("Cannot create declaration scope.");
653 ctx
->current_scope
= new_scope
;
660 void ctx_pop_scope(struct ctx
*ctx
)
662 struct ctx_decl_scope
*parent_scope
= NULL
;
666 if (!ctx
->current_scope
) {
670 parent_scope
= ctx
->current_scope
->parent_scope
;
671 ctx_decl_scope_destroy(ctx
->current_scope
);
672 ctx
->current_scope
= parent_scope
;
679 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
680 struct ctf_field_class
**decl
);
683 int is_unary_string(struct bt_list_head
*head
)
686 struct ctf_node
*node
;
688 bt_list_for_each_entry(node
, head
, siblings
) {
689 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
693 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
702 char *concatenate_unary_strings(struct bt_list_head
*head
)
706 struct ctf_node
*node
;
708 str
= g_string_new(NULL
);
711 bt_list_for_each_entry(node
, head
, siblings
) {
715 node
->type
!= NODE_UNARY_EXPRESSION
||
716 node
->u
.unary_expression
.type
!= UNARY_STRING
||
719 node
->u
.unary_expression
.link
!=
727 switch (node
->u
.unary_expression
.link
) {
729 g_string_append(str
, ".");
731 case UNARY_ARROWLINK
:
732 g_string_append(str
, "->");
734 case UNARY_DOTDOTDOT
:
735 g_string_append(str
, "...");
741 src_string
= node
->u
.unary_expression
.u
.string
;
742 g_string_append(str
, src_string
);
746 /* Destroys the container, returns the underlying string */
747 return g_string_free(str
, FALSE
);
750 /* This always returns NULL */
751 return g_string_free(str
, TRUE
);
755 const char *get_map_clock_name_value(struct bt_list_head
*head
)
758 struct ctf_node
*node
;
759 const char *name
= NULL
;
761 bt_list_for_each_entry(node
, head
, siblings
) {
763 int uexpr_type
= node
->u
.unary_expression
.type
;
764 int uexpr_link
= node
->u
.unary_expression
.link
;
765 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
766 uexpr_type
!= UNARY_STRING
||
767 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
772 /* Needs to be chained with . */
773 switch (node
->u
.unary_expression
.link
) {
776 case UNARY_ARROWLINK
:
777 case UNARY_DOTDOTDOT
:
783 src_string
= node
->u
.unary_expression
.u
.string
;
787 if (strcmp("clock", src_string
)) {
795 if (strcmp("value", src_string
)) {
800 /* Extra identifier, unknown */
814 int is_unary_unsigned(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_UNSIGNED_CONSTANT
) {
833 int get_unary_unsigned(struct ctx
*ctx
, struct bt_list_head
*head
,
838 struct ctf_node
*node
;
842 if (bt_list_empty(head
)) {
847 bt_list_for_each_entry(node
, head
, siblings
) {
848 int uexpr_type
= node
->u
.unary_expression
.type
;
849 int uexpr_link
= node
->u
.unary_expression
.link
;
850 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
851 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
852 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
854 _BT_COMP_LOGE_NODE(node
, "Invalid constant unsigned integer.");
859 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
868 int is_unary_signed(struct bt_list_head
*head
)
871 struct ctf_node
*node
;
873 bt_list_for_each_entry(node
, head
, siblings
) {
874 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
878 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
887 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
891 struct ctf_node
*node
;
893 bt_list_for_each_entry(node
, head
, siblings
) {
894 int uexpr_type
= node
->u
.unary_expression
.type
;
895 int uexpr_link
= node
->u
.unary_expression
.link
;
896 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
897 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
898 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
899 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
905 switch (uexpr_type
) {
906 case UNARY_UNSIGNED_CONSTANT
:
908 node
->u
.unary_expression
.u
.unsigned_constant
;
910 case UNARY_SIGNED_CONSTANT
:
911 *value
= node
->u
.unary_expression
.u
.signed_constant
;
926 int get_unary_uuid(struct ctx
*ctx
, struct bt_list_head
*head
,
931 struct ctf_node
*node
;
933 bt_list_for_each_entry(node
, head
, siblings
) {
934 int uexpr_type
= node
->u
.unary_expression
.type
;
935 int uexpr_link
= node
->u
.unary_expression
.link
;
936 const char *src_string
;
938 if (node
->type
!= NODE_UNARY_EXPRESSION
||
939 uexpr_type
!= UNARY_STRING
||
940 uexpr_link
!= UNARY_LINK_UNKNOWN
||
946 src_string
= node
->u
.unary_expression
.u
.string
;
947 ret
= bt_uuid_from_str(src_string
, uuid
);
949 _BT_COMP_LOGE_NODE(node
,
950 "Cannot parse UUID: uuid=\"%s\"", src_string
);
960 int get_boolean(struct ctx
*ctx
, struct ctf_node
*unary_expr
)
964 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
965 _BT_COMP_LOGE_NODE(unary_expr
,
966 "Expecting unary expression: node-type=%d",
972 switch (unary_expr
->u
.unary_expression
.type
) {
973 case UNARY_UNSIGNED_CONSTANT
:
974 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
976 case UNARY_SIGNED_CONSTANT
:
977 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
981 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
983 if (strcmp(str
, "true") == 0 || strcmp(str
, "TRUE") == 0) {
985 } else if (strcmp(str
, "false") == 0 || strcmp(str
, "FALSE") == 0) {
988 _BT_COMP_LOGE_NODE(unary_expr
,
989 "Unexpected boolean value: value=\"%s\"", str
);
996 _BT_COMP_LOGE_NODE(unary_expr
,
997 "Unexpected unary expression type: node-type=%d",
998 unary_expr
->u
.unary_expression
.type
);
1008 enum ctf_byte_order
byte_order_from_unary_expr(struct ctx
*ctx
,
1009 struct ctf_node
*unary_expr
)
1012 enum ctf_byte_order bo
= -1;
1014 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1015 _BT_COMP_LOGE_NODE(unary_expr
,
1016 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1020 str
= unary_expr
->u
.unary_expression
.u
.string
;
1022 if (strcmp(str
, "be") == 0 || strcmp(str
, "network") == 0) {
1023 bo
= CTF_BYTE_ORDER_BIG
;
1024 } else if (strcmp(str
, "le") == 0) {
1025 bo
= CTF_BYTE_ORDER_LITTLE
;
1026 } else if (strcmp(str
, "native") == 0) {
1027 bo
= CTF_BYTE_ORDER_DEFAULT
;
1029 _BT_COMP_LOGE_NODE(unary_expr
,
1030 "Unexpected \"byte_order\" attribute value: "
1031 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1041 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1042 struct ctf_node
*uexpr
)
1044 enum ctf_byte_order bo
= byte_order_from_unary_expr(ctx
, uexpr
);
1046 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
1047 bo
= ctx
->ctf_tc
->default_byte_order
;
1054 int is_align_valid(uint64_t align
)
1056 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
1060 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
1065 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1066 _BT_COMP_LOGE_NODE(cls_specifier
,
1067 "Unexpected node type: node-type=%d",
1068 cls_specifier
->type
);
1073 switch (cls_specifier
->u
.field_class_specifier
.type
) {
1075 g_string_append(str
, "void");
1078 g_string_append(str
, "char");
1080 case TYPESPEC_SHORT
:
1081 g_string_append(str
, "short");
1084 g_string_append(str
, "int");
1087 g_string_append(str
, "long");
1089 case TYPESPEC_FLOAT
:
1090 g_string_append(str
, "float");
1092 case TYPESPEC_DOUBLE
:
1093 g_string_append(str
, "double");
1095 case TYPESPEC_SIGNED
:
1096 g_string_append(str
, "signed");
1098 case TYPESPEC_UNSIGNED
:
1099 g_string_append(str
, "unsigned");
1102 g_string_append(str
, "bool");
1104 case TYPESPEC_COMPLEX
:
1105 g_string_append(str
, "_Complex");
1107 case TYPESPEC_IMAGINARY
:
1108 g_string_append(str
, "_Imaginary");
1110 case TYPESPEC_CONST
:
1111 g_string_append(str
, "const");
1113 case TYPESPEC_ID_TYPE
:
1114 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1115 g_string_append(str
,
1116 cls_specifier
->u
.field_class_specifier
.id_type
);
1119 case TYPESPEC_STRUCT
:
1121 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1123 if (!node
->u
._struct
.name
) {
1124 _BT_COMP_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1129 g_string_append(str
, "struct ");
1130 g_string_append(str
, node
->u
._struct
.name
);
1133 case TYPESPEC_VARIANT
:
1135 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1137 if (!node
->u
.variant
.name
) {
1138 _BT_COMP_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1143 g_string_append(str
, "variant ");
1144 g_string_append(str
, node
->u
.variant
.name
);
1149 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1151 if (!node
->u
._enum
.enum_id
) {
1152 _BT_COMP_LOGE_NODE(node
,
1153 "Unexpected empty enumeration field class (`enum`) name.");
1158 g_string_append(str
, "enum ");
1159 g_string_append(str
, node
->u
._enum
.enum_id
);
1162 case TYPESPEC_FLOATING_POINT
:
1163 case TYPESPEC_INTEGER
:
1164 case TYPESPEC_STRING
:
1166 _BT_COMP_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1167 "Unexpected field class specifier type: %d",
1168 cls_specifier
->u
.field_class_specifier
.type
);
1178 int get_class_specifier_list_name(struct ctx
*ctx
,
1179 struct ctf_node
*cls_specifier_list
, GString
*str
)
1182 struct ctf_node
*iter
;
1183 int alias_item_nr
= 0;
1184 struct bt_list_head
*head
=
1185 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1187 bt_list_for_each_entry(iter
, head
, siblings
) {
1188 if (alias_item_nr
!= 0) {
1189 g_string_append(str
, " ");
1193 ret
= get_class_specifier_name(ctx
, iter
, str
);
1204 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1205 struct ctf_node
*cls_specifier_list
,
1206 struct ctf_node
*node_field_class_declarator
)
1212 struct ctf_node
*iter
;
1213 struct bt_list_head
*pointers
=
1214 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1216 str
= g_string_new("");
1217 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1219 g_string_free(str
, TRUE
);
1223 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1224 g_string_append(str
, " *");
1226 if (iter
->u
.pointer
.const_qualifier
) {
1227 g_string_append(str
, " const");
1231 str_c
= g_string_free(str
, FALSE
);
1232 qalias
= g_quark_from_string(str_c
);
1240 int visit_field_class_declarator(struct ctx
*ctx
,
1241 struct ctf_node
*cls_specifier_list
,
1242 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1243 struct ctf_field_class
**field_decl
,
1244 struct ctf_field_class
*nested_decl
)
1247 * During this whole function, nested_decl is always OURS,
1248 * whereas field_decl is an output which we create, but
1249 * belongs to the caller (it is moved).
1254 /* Validate field class declarator node */
1255 if (node_field_class_declarator
) {
1256 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1258 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1259 "Unexpected field class declarator type: type=%d",
1260 node_field_class_declarator
->u
.field_class_declarator
.type
);
1265 /* TODO: GCC bitfields not supported yet */
1266 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1268 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1269 "GCC bitfields are not supported as of this version.");
1275 /* Find the right nested declaration if not provided */
1277 struct bt_list_head
*pointers
=
1278 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1280 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1284 * If we have a pointer declarator, it HAS to
1285 * be present in the field class aliases (else
1288 qalias
= create_class_alias_identifier(ctx
,
1289 cls_specifier_list
, node_field_class_declarator
);
1291 ctx_decl_scope_lookup_alias(ctx
,
1293 g_quark_to_string(qalias
), -1, true);
1295 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1296 "Cannot find class alias: name=\"%s\"",
1297 g_quark_to_string(qalias
));
1302 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1303 /* Pointer: force integer's base to 16 */
1304 struct ctf_field_class_int
*int_fc
=
1305 (void *) nested_decl
;
1308 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1311 ret
= visit_field_class_specifier_list(ctx
,
1312 cls_specifier_list
, &nested_decl
);
1314 BT_ASSERT(!nested_decl
);
1320 BT_ASSERT(nested_decl
);
1322 if (!node_field_class_declarator
) {
1323 *field_decl
= nested_decl
;
1328 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1329 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1331 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1333 *field_name
= g_quark_from_string(id
);
1338 *field_decl
= nested_decl
;
1342 struct ctf_node
*first
;
1343 struct ctf_field_class
*decl
= NULL
;
1344 struct ctf_field_class
*outer_field_decl
= NULL
;
1345 struct bt_list_head
*length
=
1346 &node_field_class_declarator
->
1347 u
.field_class_declarator
.u
.nested
.length
;
1349 /* Create array/sequence, pass nested_decl as child */
1350 if (bt_list_empty(length
)) {
1351 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1352 "Expecting length field reference or value.");
1357 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1358 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1359 _BT_COMP_LOGE_NODE(first
,
1360 "Unexpected node type: node-type=%d",
1366 switch (first
->u
.unary_expression
.type
) {
1367 case UNARY_UNSIGNED_CONSTANT
:
1369 struct ctf_field_class_array
*array_decl
= NULL
;
1371 array_decl
= ctf_field_class_array_create();
1372 BT_ASSERT(array_decl
);
1373 array_decl
->length
=
1374 first
->u
.unary_expression
.u
.unsigned_constant
;
1375 array_decl
->base
.elem_fc
= nested_decl
;
1377 decl
= (void *) array_decl
;
1382 /* Lookup unsigned integer definition, create seq. */
1383 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1384 char *length_name
= concatenate_unary_strings(length
);
1387 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1388 "Cannot concatenate unary strings.");
1393 if (strncmp(length_name
, "env.", 4) == 0) {
1394 /* This is, in fact, an array */
1395 const char *env_entry_name
= &length_name
[4];
1396 struct ctf_trace_class_env_entry
*env_entry
=
1397 ctf_trace_class_borrow_env_entry_by_name(
1398 ctx
->ctf_tc
, env_entry_name
);
1399 struct ctf_field_class_array
*array_decl
;
1402 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1403 "Cannot find environment entry: "
1404 "name=\"%s\"", env_entry_name
);
1409 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1410 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1411 "Wrong environment entry type "
1412 "(expecting integer): "
1413 "name=\"%s\"", env_entry_name
);
1418 if (env_entry
->value
.i
< 0) {
1419 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1420 "Invalid, negative array length: "
1421 "env-entry-name=\"%s\", "
1424 env_entry
->value
.i
);
1429 array_decl
= ctf_field_class_array_create();
1430 BT_ASSERT(array_decl
);
1431 array_decl
->length
=
1432 (uint64_t) env_entry
->value
.i
;
1433 array_decl
->base
.elem_fc
= nested_decl
;
1435 decl
= (void *) array_decl
;
1437 seq_decl
= ctf_field_class_sequence_create();
1438 BT_ASSERT(seq_decl
);
1439 seq_decl
->base
.elem_fc
= nested_decl
;
1441 g_string_assign(seq_decl
->length_ref
,
1443 decl
= (void *) seq_decl
;
1446 g_free(length_name
);
1454 BT_ASSERT(!nested_decl
);
1456 BT_ASSERT(!*field_decl
);
1459 * At this point, we found the next nested declaration.
1460 * We currently own this (and lost the ownership of
1461 * nested_decl in the meantime). Pass this next
1462 * nested declaration as the content of the outer
1463 * container, MOVING its ownership.
1465 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1467 node_field_class_declarator
->
1468 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1469 &outer_field_decl
, decl
);
1472 BT_ASSERT(!outer_field_decl
);
1477 BT_ASSERT(outer_field_decl
);
1478 *field_decl
= outer_field_decl
;
1479 outer_field_decl
= NULL
;
1482 BT_ASSERT(*field_decl
);
1486 ctf_field_class_destroy(*field_decl
);
1494 ctf_field_class_destroy(nested_decl
);
1500 int visit_struct_decl_field(struct ctx
*ctx
,
1501 struct ctf_field_class_struct
*struct_decl
,
1502 struct ctf_node
*cls_specifier_list
,
1503 struct bt_list_head
*field_class_declarators
)
1506 struct ctf_node
*iter
;
1507 struct ctf_field_class
*field_decl
= NULL
;
1509 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1512 const char *field_name
;
1514 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1515 &qfield_name
, iter
, &field_decl
, NULL
);
1517 BT_ASSERT(!field_decl
);
1518 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1519 "Cannot visit field class declarator: ret=%d", ret
);
1523 BT_ASSERT(field_decl
);
1524 field_name
= g_quark_to_string(qfield_name
);
1526 /* Check if field with same name already exists */
1527 if (ctf_field_class_struct_borrow_member_by_name(
1528 struct_decl
, field_name
)) {
1529 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1530 "Duplicate field in structure field class: "
1531 "field-name=\"%s\"", field_name
);
1536 /* Add field to structure */
1537 ctf_field_class_struct_append_member(struct_decl
,
1538 field_name
, field_decl
);
1545 ctf_field_class_destroy(field_decl
);
1551 int visit_variant_decl_field(struct ctx
*ctx
,
1552 struct ctf_field_class_variant
*variant_decl
,
1553 struct ctf_node
*cls_specifier_list
,
1554 struct bt_list_head
*field_class_declarators
)
1557 struct ctf_node
*iter
;
1558 struct ctf_field_class
*field_decl
= NULL
;
1560 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1563 const char *field_name
;
1565 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1566 &qfield_name
, iter
, &field_decl
, NULL
);
1568 BT_ASSERT(!field_decl
);
1569 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1570 "Cannot visit field class declarator: ret=%d", ret
);
1574 BT_ASSERT(field_decl
);
1575 field_name
= g_quark_to_string(qfield_name
);
1577 /* Check if field with same name already exists */
1578 if (ctf_field_class_variant_borrow_option_by_name(
1579 variant_decl
, field_name
)) {
1580 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1581 "Duplicate field in variant field class: "
1582 "field-name=\"%s\"", field_name
);
1587 /* Add field to structure */
1588 ctf_field_class_variant_append_option(variant_decl
,
1589 field_name
, field_decl
);
1596 ctf_field_class_destroy(field_decl
);
1602 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1603 struct bt_list_head
*field_class_declarators
)
1607 struct ctf_node
*iter
;
1608 struct ctf_field_class
*class_decl
= NULL
;
1610 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1611 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1612 &qidentifier
, iter
, &class_decl
, NULL
);
1614 _BT_COMP_LOGE_NODE(iter
,
1615 "Cannot visit field class declarator: ret=%d", ret
);
1620 /* Do not allow field class def and alias of untagged variants */
1621 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1622 struct ctf_field_class_variant
*var_fc
=
1623 (void *) class_decl
;
1625 if (var_fc
->tag_path
.path
->len
== 0) {
1626 _BT_COMP_LOGE_NODE(iter
,
1627 "Type definition of untagged variant field class is not allowed.");
1633 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1634 g_quark_to_string(qidentifier
), class_decl
);
1636 _BT_COMP_LOGE_NODE(iter
,
1637 "Cannot register field class alias: name=\"%s\"",
1638 g_quark_to_string(qidentifier
));
1644 ctf_field_class_destroy(class_decl
);
1650 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1651 struct ctf_node
*alias
)
1655 struct ctf_node
*node
;
1656 GQuark qdummy_field_name
;
1657 struct ctf_field_class
*class_decl
= NULL
;
1659 /* Create target field class */
1660 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1663 node
= _BT_LIST_FIRST_ENTRY(
1664 &target
->u
.field_class_alias_target
.field_class_declarators
,
1665 struct ctf_node
, siblings
);
1668 ret
= visit_field_class_declarator(ctx
,
1669 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1670 &qdummy_field_name
, node
, &class_decl
, NULL
);
1672 BT_ASSERT(!class_decl
);
1673 _BT_COMP_LOGE_NODE(node
,
1674 "Cannot visit field class declarator: ret=%d", ret
);
1678 /* Do not allow field class def and alias of untagged variants */
1679 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1680 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1682 if (var_fc
->tag_path
.path
->len
== 0) {
1683 _BT_COMP_LOGE_NODE(target
,
1684 "Type definition of untagged variant field class is not allowed.");
1691 * The semantic validator does not check whether the target is
1692 * abstract or not (if it has an identifier). Check it here.
1694 if (qdummy_field_name
!= 0) {
1695 _BT_COMP_LOGE_NODE(target
,
1696 "Expecting empty identifier: id=\"%s\"",
1697 g_quark_to_string(qdummy_field_name
));
1702 /* Create alias identifier */
1703 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1704 struct ctf_node
, siblings
);
1705 qalias
= create_class_alias_identifier(ctx
,
1706 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1707 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1708 g_quark_to_string(qalias
), class_decl
);
1710 _BT_COMP_LOGE_NODE(node
,
1711 "Cannot register class alias: name=\"%s\"",
1712 g_quark_to_string(qalias
));
1717 ctf_field_class_destroy(class_decl
);
1723 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1724 struct ctf_field_class_struct
*struct_decl
)
1728 switch (entry_node
->type
) {
1730 ret
= visit_field_class_def(ctx
,
1731 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1732 &entry_node
->u
.field_class_def
.field_class_declarators
);
1734 _BT_COMP_LOGE_NODE(entry_node
,
1735 "Cannot add field class found in structure field class: ret=%d",
1740 case NODE_TYPEALIAS
:
1741 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1742 entry_node
->u
.field_class_alias
.alias
);
1744 _BT_COMP_LOGE_NODE(entry_node
,
1745 "Cannot add field class alias found in structure field class: ret=%d",
1750 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1752 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1753 entry_node
->u
.struct_or_variant_declaration
.
1754 field_class_specifier_list
,
1755 &entry_node
->u
.struct_or_variant_declaration
.
1756 field_class_declarators
);
1762 _BT_COMP_LOGE_NODE(entry_node
,
1763 "Unexpected node type: node-type=%d", entry_node
->type
);
1773 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1774 struct ctf_field_class_variant
*variant_decl
)
1778 switch (entry_node
->type
) {
1780 ret
= visit_field_class_def(ctx
,
1781 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1782 &entry_node
->u
.field_class_def
.field_class_declarators
);
1784 _BT_COMP_LOGE_NODE(entry_node
,
1785 "Cannot add field class found in variant field class: ret=%d",
1790 case NODE_TYPEALIAS
:
1791 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1792 entry_node
->u
.field_class_alias
.alias
);
1794 _BT_COMP_LOGE_NODE(entry_node
,
1795 "Cannot add field class alias found in variant field class: ret=%d",
1800 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1802 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1803 entry_node
->u
.struct_or_variant_declaration
.
1804 field_class_specifier_list
,
1805 &entry_node
->u
.struct_or_variant_declaration
.
1806 field_class_declarators
);
1812 _BT_COMP_LOGE_NODE(entry_node
,
1813 "Unexpected node type: node-type=%d",
1824 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1825 struct bt_list_head
*decl_list
, int has_body
,
1826 struct bt_list_head
*min_align
,
1827 struct ctf_field_class_struct
**struct_decl
)
1831 BT_ASSERT(struct_decl
);
1832 *struct_decl
= NULL
;
1834 /* For named struct (without body), lookup in declaration scope */
1837 BT_COMP_LOGE_STR("Bodyless structure field class: missing name.");
1842 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
, ctx
->current_scope
,
1844 if (!*struct_decl
) {
1845 BT_COMP_LOGE("Cannot find structure field class: name=\"struct %s\"",
1851 struct ctf_node
*entry_node
;
1852 uint64_t min_align_value
= 0;
1855 if (ctx_decl_scope_lookup_struct(ctx
,
1856 ctx
->current_scope
, name
, 1, false)) {
1857 BT_COMP_LOGE("Structure field class already declared in local scope: "
1858 "name=\"struct %s\"", name
);
1864 if (!bt_list_empty(min_align
)) {
1865 ret
= get_unary_unsigned(ctx
, min_align
,
1868 BT_COMP_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1874 *struct_decl
= ctf_field_class_struct_create();
1875 BT_ASSERT(*struct_decl
);
1877 if (min_align_value
!= 0) {
1878 (*struct_decl
)->base
.alignment
= min_align_value
;
1881 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1883 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1884 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1887 _BT_COMP_LOGE_NODE(entry_node
,
1888 "Cannot visit structure field class entry: "
1898 ret
= ctx_decl_scope_register_struct(ctx
,
1899 ctx
->current_scope
, name
, *struct_decl
);
1901 BT_COMP_LOGE("Cannot register structure field class in declaration scope: "
1902 "name=\"struct %s\", ret=%d", name
, ret
);
1911 ctf_field_class_destroy((void *) *struct_decl
);
1912 *struct_decl
= NULL
;
1917 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1918 const char *tag
, struct bt_list_head
*decl_list
,
1919 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1922 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1924 BT_ASSERT(variant_decl
);
1925 *variant_decl
= NULL
;
1927 /* For named variant (without body), lookup in declaration scope */
1930 BT_COMP_LOGE_STR("Bodyless variant field class: missing name.");
1935 untagged_variant_decl
=
1936 ctx_decl_scope_lookup_variant(ctx
, ctx
->current_scope
,
1938 if (!untagged_variant_decl
) {
1939 BT_COMP_LOGE("Cannot find variant field class: name=\"variant %s\"",
1945 struct ctf_node
*entry_node
;
1948 if (ctx_decl_scope_lookup_variant(ctx
,
1949 ctx
->current_scope
, name
, 1, false)) {
1950 BT_COMP_LOGE("Variant field class already declared in local scope: "
1951 "name=\"variant %s\"", name
);
1957 untagged_variant_decl
= ctf_field_class_variant_create();
1958 BT_ASSERT(untagged_variant_decl
);
1959 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1961 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1962 ret
= visit_variant_decl_entry(ctx
, entry_node
,
1963 untagged_variant_decl
);
1965 _BT_COMP_LOGE_NODE(entry_node
,
1966 "Cannot visit variant field class entry: "
1976 ret
= ctx_decl_scope_register_variant(ctx
,
1977 ctx
->current_scope
, name
,
1978 untagged_variant_decl
);
1980 BT_COMP_LOGE("Cannot register variant field class in declaration scope: "
1981 "name=\"variant %s\", ret=%d", name
, ret
);
1988 * If tagged, create tagged variant and return; otherwise
1989 * return untagged variant.
1992 *variant_decl
= untagged_variant_decl
;
1993 untagged_variant_decl
= NULL
;
1996 * At this point, we have a fresh untagged variant; nobody
1997 * else owns it. Set its tag now.
1999 g_string_assign(untagged_variant_decl
->tag_ref
, tag
);
2000 *variant_decl
= untagged_variant_decl
;
2001 untagged_variant_decl
= NULL
;
2004 BT_ASSERT(!untagged_variant_decl
);
2005 BT_ASSERT(*variant_decl
);
2009 ctf_field_class_destroy((void *) untagged_variant_decl
);
2010 untagged_variant_decl
= NULL
;
2011 ctf_field_class_destroy((void *) *variant_decl
);
2012 *variant_decl
= NULL
;
2025 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
2026 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
2030 struct ctf_node
*iter
;
2031 struct uori start
= {
2039 const char *label
= enumerator
->u
.enumerator
.id
;
2040 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2042 bt_list_for_each_entry(iter
, values
, siblings
) {
2043 struct uori
*target
;
2045 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2046 _BT_COMP_LOGE_NODE(iter
,
2047 "Wrong expression for enumeration field class label: "
2048 "node-type=%d, label=\"%s\"", iter
->type
,
2060 switch (iter
->u
.unary_expression
.type
) {
2061 case UNARY_SIGNED_CONSTANT
:
2062 target
->is_signed
= true;
2064 iter
->u
.unary_expression
.u
.signed_constant
;
2066 case UNARY_UNSIGNED_CONSTANT
:
2067 target
->is_signed
= false;
2069 iter
->u
.unary_expression
.u
.unsigned_constant
;
2072 _BT_COMP_LOGE_NODE(iter
,
2073 "Invalid enumeration field class entry: "
2074 "expecting constant signed or unsigned integer: "
2075 "node-type=%d, label=\"%s\"",
2076 iter
->u
.unary_expression
.type
, label
);
2082 _BT_COMP_LOGE_NODE(iter
,
2083 "Invalid enumeration field class entry: label=\"%s\"",
2100 if (end
.is_signed
) {
2101 last
->value
.i
= end
.value
.i
+ 1;
2103 last
->value
.u
= end
.value
.u
+ 1;
2106 ctf_field_class_enum_map_range(enum_decl
, label
,
2107 start
.value
.u
, end
.value
.u
);
2115 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2116 struct ctf_node
*container_cls
,
2117 struct bt_list_head
*enumerator_list
,
2118 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2122 struct ctf_field_class_int
*integer_decl
= NULL
;
2124 BT_ASSERT(enum_decl
);
2127 /* For named enum (without body), lookup in declaration scope */
2130 BT_COMP_LOGE_STR("Bodyless enumeration field class: missing name.");
2135 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2138 BT_COMP_LOGE("Cannot find enumeration field class: "
2139 "name=\"enum %s\"", name
);
2144 struct ctf_node
*iter
;
2145 struct uori last_value
= {
2151 if (ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2153 BT_COMP_LOGE("Enumeration field class already declared in local scope: "
2154 "name=\"enum %s\"", name
);
2160 if (!container_cls
) {
2161 integer_decl
= (void *) ctx_decl_scope_lookup_alias(ctx
,
2162 ctx
->current_scope
, "int", -1, true);
2163 if (!integer_decl
) {
2164 BT_COMP_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2169 ret
= visit_field_class_declarator(ctx
, container_cls
,
2170 &qdummy_id
, NULL
, (void *) &integer_decl
,
2173 BT_ASSERT(!integer_decl
);
2179 BT_ASSERT(integer_decl
);
2181 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2182 BT_COMP_LOGE("Container field class for enumeration field class is not an integer field class: "
2183 "fc-type=%d", integer_decl
->base
.base
.type
);
2188 *enum_decl
= ctf_field_class_enum_create();
2189 BT_ASSERT(*enum_decl
);
2190 (*enum_decl
)->base
.base
.base
.alignment
=
2191 integer_decl
->base
.base
.alignment
;
2192 ctf_field_class_int_copy_content((void *) *enum_decl
,
2193 (void *) integer_decl
);
2194 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2196 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2197 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2200 _BT_COMP_LOGE_NODE(iter
,
2201 "Cannot visit enumeration field class entry: "
2208 ret
= ctx_decl_scope_register_enum(ctx
,
2209 ctx
->current_scope
, name
, *enum_decl
);
2211 BT_COMP_LOGE("Cannot register enumeration field class in declaration scope: "
2221 ctf_field_class_destroy((void *) *enum_decl
);
2225 ctf_field_class_destroy((void *) integer_decl
);
2226 integer_decl
= NULL
;
2231 int visit_field_class_specifier(struct ctx
*ctx
,
2232 struct ctf_node
*cls_specifier_list
,
2233 struct ctf_field_class
**decl
)
2236 GString
*str
= NULL
;
2239 str
= g_string_new("");
2240 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2242 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2243 "Cannot get field class specifier list's name: ret=%d", ret
);
2247 *decl
= ctx_decl_scope_lookup_alias(ctx
, ctx
->current_scope
, str
->str
,
2250 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2251 "Cannot find field class alias: name=\"%s\"", str
->str
);
2259 ctf_field_class_destroy(*decl
);
2264 g_string_free(str
, TRUE
);
2271 int visit_integer_decl(struct ctx
*ctx
,
2272 struct bt_list_head
*expressions
,
2273 struct ctf_field_class_int
**integer_decl
)
2278 struct ctf_node
*expression
;
2279 uint64_t alignment
= 0, size
= 0;
2280 struct ctf_clock_class
*mapped_clock_class
= NULL
;
2281 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2282 bt_field_class_integer_preferred_display_base base
=
2283 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2284 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2286 *integer_decl
= NULL
;
2288 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2289 struct ctf_node
*left
, *right
;
2291 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2292 struct ctf_node
, siblings
);
2293 right
= _BT_LIST_FIRST_ENTRY(
2294 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2297 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2298 _BT_COMP_LOGE_NODE(left
,
2299 "Unexpected unary expression type: type=%d",
2300 left
->u
.unary_expression
.type
);
2305 if (strcmp(left
->u
.unary_expression
.u
.string
, "signed") == 0) {
2306 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2307 _BT_COMP_LOGE_DUP_ATTR(left
, "signed",
2308 "integer field class");
2313 signedness
= get_boolean(ctx
, right
);
2314 if (signedness
< 0) {
2315 _BT_COMP_LOGE_NODE(right
,
2316 "Invalid boolean value for integer field class's `signed` attribute: "
2322 _SET(&set
, _INTEGER_SIGNED_SET
);
2323 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2324 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2325 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2326 "integer field class");
2331 byte_order
= get_real_byte_order(ctx
, right
);
2332 if (byte_order
== -1) {
2333 _BT_COMP_LOGE_NODE(right
,
2334 "Invalid `byte_order` attribute in integer field class: "
2340 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2341 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "size") == 0) {
2342 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2343 _BT_COMP_LOGE_DUP_ATTR(left
, "size",
2344 "integer field class");
2349 if (right
->u
.unary_expression
.type
!=
2350 UNARY_UNSIGNED_CONSTANT
) {
2351 _BT_COMP_LOGE_NODE(right
,
2352 "Invalid `size` attribute in integer field class: "
2353 "expecting unsigned constant integer: "
2355 right
->u
.unary_expression
.type
);
2360 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2362 _BT_COMP_LOGE_NODE(right
,
2363 "Invalid `size` attribute in integer field class: "
2364 "expecting positive constant integer: "
2365 "size=%" PRIu64
, size
);
2368 } else if (size
> 64) {
2369 _BT_COMP_LOGE_NODE(right
,
2370 "Invalid `size` attribute in integer field class: "
2371 "integer fields over 64 bits are not supported as of this version: "
2372 "size=%" PRIu64
, size
);
2377 _SET(&set
, _INTEGER_SIZE_SET
);
2378 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2379 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2380 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2381 "integer field class");
2386 if (right
->u
.unary_expression
.type
!=
2387 UNARY_UNSIGNED_CONSTANT
) {
2388 _BT_COMP_LOGE_NODE(right
,
2389 "Invalid `align` attribute in integer field class: "
2390 "expecting unsigned constant integer: "
2392 right
->u
.unary_expression
.type
);
2398 right
->u
.unary_expression
.u
.unsigned_constant
;
2399 if (!is_align_valid(alignment
)) {
2400 _BT_COMP_LOGE_NODE(right
,
2401 "Invalid `align` attribute in integer field class: "
2402 "expecting power of two: "
2403 "align=%" PRIu64
, alignment
);
2408 _SET(&set
, _INTEGER_ALIGN_SET
);
2409 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "base") == 0) {
2410 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2411 _BT_COMP_LOGE_DUP_ATTR(left
, "base",
2412 "integer field class");
2417 switch (right
->u
.unary_expression
.type
) {
2418 case UNARY_UNSIGNED_CONSTANT
:
2420 uint64_t constant
= right
->u
.unary_expression
.
2421 u
.unsigned_constant
;
2425 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2428 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2431 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2434 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2437 _BT_COMP_LOGE_NODE(right
,
2438 "Invalid `base` attribute in integer field class: "
2440 right
->u
.unary_expression
.u
.unsigned_constant
);
2448 char *s_right
= concatenate_unary_strings(
2449 &expression
->u
.ctf_expression
.right
);
2451 _BT_COMP_LOGE_NODE(right
,
2452 "Unexpected unary expression for integer field class's `base` attribute.");
2457 if (strcmp(s_right
, "decimal") == 0 ||
2458 strcmp(s_right
, "dec") == 0 ||
2459 strcmp(s_right
, "d") == 0 ||
2460 strcmp(s_right
, "i") == 0 ||
2461 strcmp(s_right
, "u") == 0) {
2462 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2463 } else if (strcmp(s_right
, "hexadecimal") == 0 ||
2464 strcmp(s_right
, "hex") == 0 ||
2465 strcmp(s_right
, "x") == 0 ||
2466 strcmp(s_right
, "X") == 0 ||
2467 strcmp(s_right
, "p") == 0) {
2468 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2469 } else if (strcmp(s_right
, "octal") == 0 ||
2470 strcmp(s_right
, "oct") == 0 ||
2471 strcmp(s_right
, "o") == 0) {
2472 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2473 } else if (strcmp(s_right
, "binary") == 0 ||
2474 strcmp(s_right
, "b") == 0) {
2475 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2477 _BT_COMP_LOGE_NODE(right
,
2478 "Unexpected unary expression for integer field class's `base` attribute: "
2479 "base=\"%s\"", s_right
);
2489 _BT_COMP_LOGE_NODE(right
,
2490 "Invalid `base` attribute in integer field class: "
2491 "expecting unsigned constant integer or unary string.");
2496 _SET(&set
, _INTEGER_BASE_SET
);
2497 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2500 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2501 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2502 "integer field class");
2507 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2508 _BT_COMP_LOGE_NODE(right
,
2509 "Invalid `encoding` attribute in integer field class: "
2510 "expecting unary string.");
2515 s_right
= concatenate_unary_strings(
2516 &expression
->u
.ctf_expression
.right
);
2518 _BT_COMP_LOGE_NODE(right
,
2519 "Unexpected unary expression for integer field class's `encoding` attribute.");
2524 if (strcmp(s_right
, "UTF8") == 0 ||
2525 strcmp(s_right
, "utf8") == 0 ||
2526 strcmp(s_right
, "utf-8") == 0 ||
2527 strcmp(s_right
, "UTF-8") == 0 ||
2528 strcmp(s_right
, "ASCII") == 0 ||
2529 strcmp(s_right
, "ascii") == 0) {
2530 encoding
= CTF_ENCODING_UTF8
;
2531 } else if (strcmp(s_right
, "none") == 0) {
2532 encoding
= CTF_ENCODING_NONE
;
2534 _BT_COMP_LOGE_NODE(right
,
2535 "Invalid `encoding` attribute in integer field class: "
2536 "unknown encoding: encoding=\"%s\"",
2544 _SET(&set
, _INTEGER_ENCODING_SET
);
2545 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "map") == 0) {
2546 const char *clock_name
;
2548 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2549 _BT_COMP_LOGE_DUP_ATTR(left
, "map",
2550 "integer field class");
2555 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2556 _BT_COMP_LOGE_NODE(right
,
2557 "Invalid `map` attribute in integer field class: "
2558 "expecting unary string.");
2564 get_map_clock_name_value(
2565 &expression
->u
.ctf_expression
.right
);
2567 char *s_right
= concatenate_unary_strings(
2568 &expression
->u
.ctf_expression
.right
);
2571 _BT_COMP_LOGE_NODE(right
,
2572 "Unexpected unary expression for integer field class's `map` attribute.");
2577 _BT_COMP_LOGE_NODE(right
,
2578 "Invalid `map` attribute in integer field class: "
2579 "cannot find clock class at this point: name=\"%s\"",
2581 _SET(&set
, _INTEGER_MAP_SET
);
2586 mapped_clock_class
=
2587 ctf_trace_class_borrow_clock_class_by_name(
2588 ctx
->ctf_tc
, clock_name
);
2589 if (!mapped_clock_class
) {
2590 _BT_COMP_LOGE_NODE(right
,
2591 "Invalid `map` attribute in integer field class: "
2592 "cannot find clock class at this point: name=\"%s\"",
2598 _SET(&set
, _INTEGER_MAP_SET
);
2600 _BT_COMP_LOGW_NODE(left
,
2601 "Unknown attribute in integer field class: "
2603 left
->u
.unary_expression
.u
.string
);
2607 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2608 BT_COMP_LOGE_STR("Missing `size` attribute in integer field class.");
2613 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2614 if (size
% CHAR_BIT
) {
2615 /* Bit-packed alignment */
2618 /* Byte-packed alignment */
2619 alignment
= CHAR_BIT
;
2623 *integer_decl
= ctf_field_class_int_create();
2624 BT_ASSERT(*integer_decl
);
2625 (*integer_decl
)->base
.base
.alignment
= alignment
;
2626 (*integer_decl
)->base
.byte_order
= byte_order
;
2627 (*integer_decl
)->base
.size
= size
;
2628 (*integer_decl
)->is_signed
= (signedness
> 0);
2629 (*integer_decl
)->disp_base
= base
;
2630 (*integer_decl
)->encoding
= encoding
;
2631 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2635 ctf_field_class_destroy((void *) *integer_decl
);
2636 *integer_decl
= NULL
;
2641 int visit_floating_point_number_decl(struct ctx
*ctx
,
2642 struct bt_list_head
*expressions
,
2643 struct ctf_field_class_float
**float_decl
)
2647 struct ctf_node
*expression
;
2648 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2649 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2653 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2654 struct ctf_node
*left
, *right
;
2656 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2657 struct ctf_node
, siblings
);
2658 right
= _BT_LIST_FIRST_ENTRY(
2659 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2662 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2663 _BT_COMP_LOGE_NODE(left
,
2664 "Unexpected unary expression type: type=%d",
2665 left
->u
.unary_expression
.type
);
2670 if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2671 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2672 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2673 "floating point number field class");
2678 byte_order
= get_real_byte_order(ctx
, right
);
2679 if (byte_order
== -1) {
2680 _BT_COMP_LOGE_NODE(right
,
2681 "Invalid `byte_order` attribute in floating point number field class: "
2687 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2688 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig") == 0) {
2689 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2690 _BT_COMP_LOGE_DUP_ATTR(left
, "exp_dig",
2691 "floating point number field class");
2696 if (right
->u
.unary_expression
.type
!=
2697 UNARY_UNSIGNED_CONSTANT
) {
2698 _BT_COMP_LOGE_NODE(right
,
2699 "Invalid `exp_dig` attribute in floating point number field class: "
2700 "expecting unsigned constant integer: "
2702 right
->u
.unary_expression
.type
);
2707 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2708 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2709 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig") == 0) {
2710 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2711 _BT_COMP_LOGE_DUP_ATTR(left
, "mant_dig",
2712 "floating point number field class");
2717 if (right
->u
.unary_expression
.type
!=
2718 UNARY_UNSIGNED_CONSTANT
) {
2719 _BT_COMP_LOGE_NODE(right
,
2720 "Invalid `mant_dig` attribute in floating point number field class: "
2721 "expecting unsigned constant integer: "
2723 right
->u
.unary_expression
.type
);
2728 mant_dig
= right
->u
.unary_expression
.u
.
2730 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2731 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2732 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2733 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2734 "floating point number field class");
2739 if (right
->u
.unary_expression
.type
!=
2740 UNARY_UNSIGNED_CONSTANT
) {
2741 _BT_COMP_LOGE_NODE(right
,
2742 "Invalid `align` attribute in floating point number field class: "
2743 "expecting unsigned constant integer: "
2745 right
->u
.unary_expression
.type
);
2750 alignment
= right
->u
.unary_expression
.u
.
2753 if (!is_align_valid(alignment
)) {
2754 _BT_COMP_LOGE_NODE(right
,
2755 "Invalid `align` attribute in floating point number field class: "
2756 "expecting power of two: "
2757 "align=%" PRIu64
, alignment
);
2762 _SET(&set
, _FLOAT_ALIGN_SET
);
2764 _BT_COMP_LOGW_NODE(left
,
2765 "Unknown attribute in floating point number field class: "
2767 left
->u
.unary_expression
.u
.string
);
2771 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2772 BT_COMP_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2777 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2778 BT_COMP_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2783 if (mant_dig
!= 24 && mant_dig
!= 53) {
2784 BT_COMP_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2789 if (mant_dig
== 24 && exp_dig
!= 8) {
2790 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2795 if (mant_dig
== 53 && exp_dig
!= 11) {
2796 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2801 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2802 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2803 /* Bit-packed alignment */
2806 /* Byte-packed alignment */
2807 alignment
= CHAR_BIT
;
2811 *float_decl
= ctf_field_class_float_create();
2812 BT_ASSERT(*float_decl
);
2813 (*float_decl
)->base
.base
.alignment
= alignment
;
2814 (*float_decl
)->base
.byte_order
= byte_order
;
2815 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2819 ctf_field_class_destroy((void *) *float_decl
);
2825 int visit_string_decl(struct ctx
*ctx
,
2826 struct bt_list_head
*expressions
,
2827 struct ctf_field_class_string
**string_decl
)
2831 struct ctf_node
*expression
;
2832 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2834 *string_decl
= NULL
;
2836 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2837 struct ctf_node
*left
, *right
;
2839 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2840 struct ctf_node
, siblings
);
2841 right
= _BT_LIST_FIRST_ENTRY(
2842 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2845 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2846 _BT_COMP_LOGE_NODE(left
,
2847 "Unexpected unary expression type: type=%d",
2848 left
->u
.unary_expression
.type
);
2853 if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2856 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2857 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2858 "string field class");
2863 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2864 _BT_COMP_LOGE_NODE(right
,
2865 "Invalid `encoding` attribute in string field class: "
2866 "expecting unary string.");
2871 s_right
= concatenate_unary_strings(
2872 &expression
->u
.ctf_expression
.right
);
2874 _BT_COMP_LOGE_NODE(right
,
2875 "Unexpected unary expression for string field class's `encoding` attribute.");
2880 if (strcmp(s_right
, "UTF8") == 0 ||
2881 strcmp(s_right
, "utf8") == 0 ||
2882 strcmp(s_right
, "utf-8") == 0 ||
2883 strcmp(s_right
, "UTF-8") == 0 ||
2884 strcmp(s_right
, "ASCII") == 0 ||
2885 strcmp(s_right
, "ascii") == 0) {
2886 encoding
= CTF_ENCODING_UTF8
;
2887 } else if (strcmp(s_right
, "none") == 0) {
2888 encoding
= CTF_ENCODING_NONE
;
2890 _BT_COMP_LOGE_NODE(right
,
2891 "Invalid `encoding` attribute in string field class: "
2892 "unknown encoding: encoding=\"%s\"",
2900 _SET(&set
, _STRING_ENCODING_SET
);
2902 _BT_COMP_LOGW_NODE(left
,
2903 "Unknown attribute in string field class: "
2905 left
->u
.unary_expression
.u
.string
);
2909 *string_decl
= ctf_field_class_string_create();
2910 BT_ASSERT(*string_decl
);
2911 (*string_decl
)->encoding
= encoding
;
2915 ctf_field_class_destroy((void *) *string_decl
);
2916 *string_decl
= NULL
;
2921 int visit_field_class_specifier_list(struct ctx
*ctx
,
2922 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
2925 struct ctf_node
*first
, *node
;
2929 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
2930 _BT_COMP_LOGE_NODE(ts_list
,
2931 "Unexpected node type: node-type=%d", ts_list
->type
);
2936 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
2937 struct ctf_node
, siblings
);
2938 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
2939 _BT_COMP_LOGE_NODE(first
,
2940 "Unexpected node type: node-type=%d", first
->type
);
2945 node
= first
->u
.field_class_specifier
.node
;
2947 switch (first
->u
.field_class_specifier
.type
) {
2948 case TYPESPEC_INTEGER
:
2949 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
2956 case TYPESPEC_FLOATING_POINT
:
2957 ret
= visit_floating_point_number_decl(ctx
,
2958 &node
->u
.floating_point
.expressions
, (void *) decl
);
2964 case TYPESPEC_STRING
:
2965 ret
= visit_string_decl(ctx
,
2966 &node
->u
.string
.expressions
, (void *) decl
);
2972 case TYPESPEC_STRUCT
:
2973 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
2974 &node
->u
._struct
.declaration_list
,
2975 node
->u
._struct
.has_body
,
2976 &node
->u
._struct
.min_align
, (void *) decl
);
2982 case TYPESPEC_VARIANT
:
2983 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
2984 node
->u
.variant
.choice
,
2985 &node
->u
.variant
.declaration_list
,
2986 node
->u
.variant
.has_body
, (void *) decl
);
2993 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
2994 node
->u
._enum
.container_field_class
,
2995 &node
->u
._enum
.enumerator_list
,
2996 node
->u
._enum
.has_body
, (void *) decl
);
3004 case TYPESPEC_SHORT
:
3007 case TYPESPEC_FLOAT
:
3008 case TYPESPEC_DOUBLE
:
3009 case TYPESPEC_SIGNED
:
3010 case TYPESPEC_UNSIGNED
:
3012 case TYPESPEC_COMPLEX
:
3013 case TYPESPEC_IMAGINARY
:
3014 case TYPESPEC_CONST
:
3015 case TYPESPEC_ID_TYPE
:
3016 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
3018 _BT_COMP_LOGE_NODE(first
,
3019 "Cannot visit field class specifier: ret=%d",
3026 _BT_COMP_LOGE_NODE(first
,
3027 "Unexpected field class specifier type: node-type=%d",
3028 first
->u
.field_class_specifier
.type
);
3037 ctf_field_class_destroy((void *) *decl
);
3043 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3044 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
3050 switch (node
->type
) {
3052 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3053 &node
->u
.field_class_def
.field_class_declarators
);
3055 _BT_COMP_LOGE_NODE(node
,
3056 "Cannot add field class found in event class.");
3060 case NODE_TYPEALIAS
:
3061 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3062 node
->u
.field_class_alias
.alias
);
3064 _BT_COMP_LOGE_NODE(node
,
3065 "Cannot add field class alias found in event class.");
3069 case NODE_CTF_EXPRESSION
:
3071 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3073 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3078 if (strcmp(left
, "name") == 0) {
3079 /* This is already known at this stage */
3080 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3081 _BT_COMP_LOGE_DUP_ATTR(node
, "name", "event class");
3086 _SET(set
, _EVENT_NAME_SET
);
3087 } else if (strcmp(left
, "id") == 0) {
3090 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3091 _BT_COMP_LOGE_DUP_ATTR(node
, "id", "event class");
3096 ret
= get_unary_unsigned(ctx
,
3097 &node
->u
.ctf_expression
.right
,
3099 /* Only read "id" if get_unary_unsigned() succeeded. */
3100 if (ret
|| (!ret
&& id
< 0)) {
3101 _BT_COMP_LOGE_NODE(node
,
3102 "Unexpected unary expression for event class's `id` attribute.");
3107 event_class
->id
= id
;
3108 _SET(set
, _EVENT_ID_SET
);
3109 } else if (strcmp(left
, "stream_id") == 0) {
3110 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3111 _BT_COMP_LOGE_DUP_ATTR(node
, "stream_id",
3117 ret
= get_unary_unsigned(ctx
,
3118 &node
->u
.ctf_expression
.right
, stream_id
);
3121 * Only read "stream_id" if get_unary_unsigned()
3125 _BT_COMP_LOGE_NODE(node
,
3126 "Unexpected unary expression for event class's `stream_id` attribute.");
3131 _SET(set
, _EVENT_STREAM_ID_SET
);
3132 } else if (strcmp(left
, "context") == 0) {
3133 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3134 _BT_COMP_LOGE_NODE(node
,
3135 "Duplicate `context` entry in event class.");
3140 ret
= visit_field_class_specifier_list(ctx
,
3141 _BT_LIST_FIRST_ENTRY(
3142 &node
->u
.ctf_expression
.right
,
3143 struct ctf_node
, siblings
),
3144 &event_class
->spec_context_fc
);
3146 _BT_COMP_LOGE_NODE(node
,
3147 "Cannot create event class's context field class.");
3151 BT_ASSERT(event_class
->spec_context_fc
);
3152 _SET(set
, _EVENT_CONTEXT_SET
);
3153 } else if (strcmp(left
, "fields") == 0) {
3154 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3155 _BT_COMP_LOGE_NODE(node
,
3156 "Duplicate `fields` entry in event class.");
3161 ret
= visit_field_class_specifier_list(ctx
,
3162 _BT_LIST_FIRST_ENTRY(
3163 &node
->u
.ctf_expression
.right
,
3164 struct ctf_node
, siblings
),
3165 &event_class
->payload_fc
);
3167 _BT_COMP_LOGE_NODE(node
,
3168 "Cannot create event class's payload field class.");
3172 BT_ASSERT(event_class
->payload_fc
);
3173 _SET(set
, _EVENT_FIELDS_SET
);
3174 } else if (strcmp(left
, "loglevel") == 0) {
3175 uint64_t loglevel_value
;
3176 bt_event_class_log_level log_level
= -1;
3178 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3179 _BT_COMP_LOGE_DUP_ATTR(node
, "loglevel",
3185 ret
= get_unary_unsigned(ctx
,
3186 &node
->u
.ctf_expression
.right
, &loglevel_value
);
3188 _BT_COMP_LOGE_NODE(node
,
3189 "Unexpected unary expression for event class's `loglevel` attribute.");
3194 switch (loglevel_value
) {
3196 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3199 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3202 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3205 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3208 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3211 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3214 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3217 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3220 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3223 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3226 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3229 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3232 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3235 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3238 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3241 _BT_COMP_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3242 "log-level=%" PRIu64
, loglevel_value
);
3245 if (log_level
!= -1) {
3246 event_class
->log_level
= log_level
;
3249 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3250 } else if (strcmp(left
, "model.emf.uri") == 0) {
3253 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3254 _BT_COMP_LOGE_DUP_ATTR(node
, "model.emf.uri",
3260 right
= concatenate_unary_strings(
3261 &node
->u
.ctf_expression
.right
);
3263 _BT_COMP_LOGE_NODE(node
,
3264 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3269 if (strlen(right
) == 0) {
3270 _BT_COMP_LOGW_NODE(node
,
3271 "Not setting event class's EMF URI because it's empty.");
3273 g_string_assign(event_class
->emf_uri
,
3278 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3280 _BT_COMP_LOGW_NODE(node
,
3281 "Unknown attribute in event class: "
3282 "attr-name=\"%s\"", left
);
3304 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3308 struct ctf_node
*iter
;
3309 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3311 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3312 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3316 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3318 _BT_COMP_LOGE_NODE(iter
,
3319 "Cannot concatenate unary strings.");
3323 if (strcmp(left
, "name") == 0) {
3324 name
= concatenate_unary_strings(
3325 &iter
->u
.ctf_expression
.right
);
3327 _BT_COMP_LOGE_NODE(iter
,
3328 "Unexpected unary expression for event class's `name` attribute.");
3349 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3353 struct ctf_node
*iter
;
3354 uint64_t stream_id
= 0;
3355 char *event_name
= NULL
;
3356 struct ctf_event_class
*event_class
= NULL
;
3357 struct ctf_stream_class
*stream_class
= NULL
;
3358 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3359 bool pop_scope
= false;
3361 if (node
->visited
) {
3365 node
->visited
= TRUE
;
3366 event_name
= get_event_decl_name(ctx
, node
);
3368 _BT_COMP_LOGE_NODE(node
,
3369 "Missing `name` attribute in event class.");
3374 event_class
= ctf_event_class_create();
3375 BT_ASSERT(event_class
);
3376 g_string_assign(event_class
->name
, event_name
);
3377 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3380 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3381 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3384 _BT_COMP_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3390 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3392 * Allow missing stream_id if there is only a single
3395 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3397 /* Create implicit stream class if there's none */
3399 stream_class
= ctf_stream_class_create();
3400 BT_ASSERT(stream_class
);
3401 stream_class
->id
= stream_id
;
3402 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3406 /* Single stream class: get its ID */
3407 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3408 stream_id
= stream_class
->id
;
3411 _BT_COMP_LOGE_NODE(node
,
3412 "Missing `stream_id` attribute in event class.");
3418 /* We have the stream ID now; get the stream class if found */
3419 if (!stream_class
) {
3420 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3421 ctx
->ctf_tc
, stream_id
);
3422 if (!stream_class
) {
3423 _BT_COMP_LOGE_NODE(node
,
3424 "Cannot find stream class at this point: "
3425 "id=%" PRId64
, stream_id
);
3431 BT_ASSERT(stream_class
);
3433 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3434 /* Allow only one event without ID per stream */
3435 if (stream_class
->event_classes
->len
!= 0) {
3436 _BT_COMP_LOGE_NODE(node
,
3437 "Missing `id` attribute in event class.");
3443 event_class
->id
= 0;
3446 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3448 _BT_COMP_LOGE_NODE(node
,
3449 "Duplicate event class (same ID) in the same stream class: "
3450 "id=%" PRId64
, event_class
->id
);
3455 ctf_stream_class_append_event_class(stream_class
, event_class
);
3460 ctf_event_class_destroy(event_class
);
3478 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3479 struct ctf_field_class
*fc
)
3481 struct ctf_clock_class
*clock_class_to_map_to
= NULL
;
3482 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3484 uint64_t clock_class_count
;
3490 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3491 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3495 if (int_fc
->mapped_clock_class
) {
3496 /* Already mapped */
3500 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3502 switch (clock_class_count
) {
3505 * No clock class exists in the trace at this point. Create an
3506 * implicit one at 1 GHz, named `default`, and use this clock
3509 clock_class_to_map_to
= ctf_clock_class_create();
3510 BT_ASSERT(clock_class_to_map_to
);
3511 clock_class_to_map_to
->frequency
= UINT64_C(1000000000);
3512 g_string_assign(clock_class_to_map_to
->name
, "default");
3513 BT_ASSERT(ret
== 0);
3514 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3515 clock_class_to_map_to
);
3519 * Only one clock class exists in the trace at this point: use
3522 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3526 * Timestamp field not mapped to a clock class and there's more
3527 * than one clock class in the trace: this is an error.
3529 BT_COMP_LOGE_STR("Timestamp field found with no mapped clock class, "
3530 "but there's more than one clock class in the trace at this point.");
3535 BT_ASSERT(clock_class_to_map_to
);
3536 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3543 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3544 struct ctf_field_class
*root_fc
, const char *field_name
)
3548 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3549 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3555 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3556 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3560 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3561 count
= struct_fc
->members
->len
;
3563 count
= var_fc
->options
->len
;
3566 for (i
= 0; i
< count
; i
++) {
3567 struct ctf_named_field_class
*named_fc
= NULL
;
3569 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3570 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3572 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3573 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3577 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3578 ret
= auto_map_field_to_trace_clock_class(ctx
,
3581 BT_COMP_LOGE("Cannot automatically map field to trace's clock class: "
3582 "field-name=\"%s\"", field_name
);
3587 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3590 BT_COMP_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3591 "field-name=\"%s\", root-field-name=\"%s\"",
3592 field_name
, named_fc
->name
->str
);
3602 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3603 struct ctf_stream_class
*stream_class
, int *set
)
3608 switch (node
->type
) {
3610 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3611 &node
->u
.field_class_def
.field_class_declarators
);
3613 _BT_COMP_LOGE_NODE(node
,
3614 "Cannot add field class found in stream class.");
3618 case NODE_TYPEALIAS
:
3619 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3620 node
->u
.field_class_alias
.alias
);
3622 _BT_COMP_LOGE_NODE(node
,
3623 "Cannot add field class alias found in stream class.");
3627 case NODE_CTF_EXPRESSION
:
3629 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3631 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3636 if (strcmp(left
, "id") == 0) {
3639 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3640 _BT_COMP_LOGE_DUP_ATTR(node
, "id",
3641 "stream declaration");
3646 ret
= get_unary_unsigned(ctx
,
3647 &node
->u
.ctf_expression
.right
,
3650 /* Only read "id" if get_unary_unsigned() succeeded. */
3651 if (ret
|| (!ret
&& id
< 0)) {
3652 _BT_COMP_LOGE_NODE(node
,
3653 "Unexpected unary expression for stream class's `id` attribute.");
3658 if (ctf_trace_class_borrow_stream_class_by_id(
3660 _BT_COMP_LOGE_NODE(node
,
3661 "Duplicate stream class (same ID): id=%" PRId64
,
3667 stream_class
->id
= id
;
3668 _SET(set
, _STREAM_ID_SET
);
3669 } else if (strcmp(left
, "event.header") == 0) {
3670 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3671 _BT_COMP_LOGE_NODE(node
,
3672 "Duplicate `event.header` entry in stream class.");
3677 ret
= visit_field_class_specifier_list(ctx
,
3678 _BT_LIST_FIRST_ENTRY(
3679 &node
->u
.ctf_expression
.right
,
3680 struct ctf_node
, siblings
),
3681 &stream_class
->event_header_fc
);
3683 _BT_COMP_LOGE_NODE(node
,
3684 "Cannot create stream class's event header field class.");
3688 BT_ASSERT(stream_class
->event_header_fc
);
3689 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3690 stream_class
->event_header_fc
, "timestamp");
3692 _BT_COMP_LOGE_NODE(node
,
3693 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3697 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3698 } else if (strcmp(left
, "event.context") == 0) {
3699 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3700 _BT_COMP_LOGE_NODE(node
,
3701 "Duplicate `event.context` entry in stream class.");
3706 ret
= visit_field_class_specifier_list(ctx
,
3707 _BT_LIST_FIRST_ENTRY(
3708 &node
->u
.ctf_expression
.right
,
3709 struct ctf_node
, siblings
),
3710 &stream_class
->event_common_context_fc
);
3712 _BT_COMP_LOGE_NODE(node
,
3713 "Cannot create stream class's event context field class.");
3717 BT_ASSERT(stream_class
->event_common_context_fc
);
3718 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3719 } else if (strcmp(left
, "packet.context") == 0) {
3720 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3721 _BT_COMP_LOGE_NODE(node
,
3722 "Duplicate `packet.context` entry in stream class.");
3727 ret
= visit_field_class_specifier_list(ctx
,
3728 _BT_LIST_FIRST_ENTRY(
3729 &node
->u
.ctf_expression
.right
,
3730 struct ctf_node
, siblings
),
3731 &stream_class
->packet_context_fc
);
3733 _BT_COMP_LOGE_NODE(node
,
3734 "Cannot create stream class's packet context field class.");
3738 BT_ASSERT(stream_class
->packet_context_fc
);
3739 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3740 stream_class
->packet_context_fc
,
3743 _BT_COMP_LOGE_NODE(node
,
3744 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3748 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3749 stream_class
->packet_context_fc
,
3752 _BT_COMP_LOGE_NODE(node
,
3753 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3757 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3759 _BT_COMP_LOGW_NODE(node
,
3760 "Unknown attribute in stream class: "
3761 "attr-name=\"%s\"", left
);
3782 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3786 struct ctf_node
*iter
;
3787 struct ctf_stream_class
*stream_class
= NULL
;
3788 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3790 if (node
->visited
) {
3794 node
->visited
= TRUE
;
3795 stream_class
= ctf_stream_class_create();
3796 BT_ASSERT(stream_class
);
3797 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3799 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3800 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3802 _BT_COMP_LOGE_NODE(iter
,
3803 "Cannot visit stream class's entry: "
3812 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3813 /* Check that packet header has `stream_id` field */
3814 struct ctf_named_field_class
*named_fc
= NULL
;
3816 if (!ctx
->ctf_tc
->packet_header_fc
) {
3817 _BT_COMP_LOGE_NODE(node
,
3818 "Stream class has a `id` attribute, "
3819 "but trace has no packet header field class.");
3823 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3824 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3826 _BT_COMP_LOGE_NODE(node
,
3827 "Stream class has a `id` attribute, "
3828 "but trace's packet header field class has no `stream_id` field.");
3832 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3833 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3834 _BT_COMP_LOGE_NODE(node
,
3835 "Stream class has a `id` attribute, "
3836 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3840 /* Allow only _one_ ID-less stream */
3841 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3842 _BT_COMP_LOGE_NODE(node
,
3843 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3848 /* Automatic ID: 0 */
3849 stream_class
->id
= 0;
3853 * Make sure that this stream class's ID is currently unique in
3856 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3857 stream_class
->id
)) {
3858 _BT_COMP_LOGE_NODE(node
,
3859 "Duplicate stream class (same ID): id=%" PRId64
,
3865 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3866 stream_class
= NULL
;
3870 ctf_stream_class_destroy(stream_class
);
3871 stream_class
= NULL
;
3878 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3884 switch (node
->type
) {
3886 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3887 &node
->u
.field_class_def
.field_class_declarators
);
3889 _BT_COMP_LOGE_NODE(node
,
3890 "Cannot add field class found in trace (`trace` block).");
3894 case NODE_TYPEALIAS
:
3895 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3896 node
->u
.field_class_alias
.alias
);
3898 _BT_COMP_LOGE_NODE(node
,
3899 "Cannot add field class alias found in trace (`trace` block).");
3903 case NODE_CTF_EXPRESSION
:
3905 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3907 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3912 if (strcmp(left
, "major") == 0) {
3913 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
3914 _BT_COMP_LOGE_DUP_ATTR(node
, "major", "trace");
3919 ret
= get_unary_unsigned(ctx
,
3920 &node
->u
.ctf_expression
.right
, &val
);
3922 _BT_COMP_LOGE_NODE(node
,
3923 "Unexpected unary expression for trace's `major` attribute.");
3929 _BT_COMP_LOGE_NODE(node
,
3930 "Invalid trace's `minor` attribute: expecting 1.");
3934 ctx
->ctf_tc
->major
= val
;
3935 _SET(set
, _TRACE_MAJOR_SET
);
3936 } else if (strcmp(left
, "minor") == 0) {
3937 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
3938 _BT_COMP_LOGE_DUP_ATTR(node
, "minor", "trace");
3943 ret
= get_unary_unsigned(ctx
,
3944 &node
->u
.ctf_expression
.right
, &val
);
3946 _BT_COMP_LOGE_NODE(node
,
3947 "Unexpected unary expression for trace's `minor` attribute.");
3953 _BT_COMP_LOGE_NODE(node
,
3954 "Invalid trace's `minor` attribute: expecting 8.");
3958 ctx
->ctf_tc
->minor
= val
;
3959 _SET(set
, _TRACE_MINOR_SET
);
3960 } else if (strcmp(left
, "uuid") == 0) {
3961 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
3962 _BT_COMP_LOGE_DUP_ATTR(node
, "uuid", "trace");
3967 ret
= get_unary_uuid(ctx
,
3968 &node
->u
.ctf_expression
.right
,
3971 _BT_COMP_LOGE_NODE(node
,
3972 "Invalid trace's `uuid` attribute.");
3976 ctx
->ctf_tc
->is_uuid_set
= true;
3977 _SET(set
, _TRACE_UUID_SET
);
3978 } else if (strcmp(left
, "byte_order") == 0) {
3979 /* Default byte order is already known at this stage */
3980 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
3981 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
3987 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= -1);
3988 _SET(set
, _TRACE_BYTE_ORDER_SET
);
3989 } else if (strcmp(left
, "packet.header") == 0) {
3990 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
3991 _BT_COMP_LOGE_NODE(node
,
3992 "Duplicate `packet.header` entry in trace.");
3997 ret
= visit_field_class_specifier_list(ctx
,
3998 _BT_LIST_FIRST_ENTRY(
3999 &node
->u
.ctf_expression
.right
,
4000 struct ctf_node
, siblings
),
4001 &ctx
->ctf_tc
->packet_header_fc
);
4003 _BT_COMP_LOGE_NODE(node
,
4004 "Cannot create trace's packet header field class.");
4008 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
4009 _SET(set
, _TRACE_PACKET_HEADER_SET
);
4011 _BT_COMP_LOGW_NODE(node
,
4012 "Unknown attribute in stream class: "
4013 "attr-name=\"%s\"", left
);
4021 _BT_COMP_LOGE_NODE(node
, "Unknown expression in trace.");
4034 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
4038 struct ctf_node
*iter
;
4039 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
4041 if (node
->visited
) {
4045 node
->visited
= TRUE
;
4047 if (ctx
->is_trace_visited
) {
4048 _BT_COMP_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
4053 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4055 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
4056 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
4058 _BT_COMP_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
4067 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
4068 _BT_COMP_LOGE_NODE(node
,
4069 "Missing `major` attribute in trace (`trace` block).");
4074 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
4075 _BT_COMP_LOGE_NODE(node
,
4076 "Missing `minor` attribute in trace (`trace` block).");
4081 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4082 _BT_COMP_LOGE_NODE(node
,
4083 "Missing `byte_order` attribute in trace (`trace` block).");
4088 ctx
->is_trace_visited
= true;
4098 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4102 struct ctf_node
*entry_node
;
4103 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4105 if (node
->visited
) {
4109 node
->visited
= TRUE
;
4111 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4112 struct bt_list_head
*right_head
=
4113 &entry_node
->u
.ctf_expression
.right
;
4115 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4116 _BT_COMP_LOGE_NODE(entry_node
,
4117 "Wrong expression in environment entry: "
4118 "node-type=%d", entry_node
->type
);
4123 left
= concatenate_unary_strings(
4124 &entry_node
->u
.ctf_expression
.left
);
4126 _BT_COMP_LOGE_NODE(entry_node
,
4127 "Cannot get environment entry's name.");
4132 if (is_unary_string(right_head
)) {
4133 char *right
= concatenate_unary_strings(right_head
);
4136 _BT_COMP_LOGE_NODE(entry_node
,
4137 "Unexpected unary expression for environment entry's value: "
4138 "name=\"%s\"", left
);
4143 if (strcmp(left
, "tracer_name") == 0) {
4144 if (strncmp(right
, "lttng", 5) == 0) {
4145 BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
4146 "tracer-name=\"%s\"",
4148 ctx
->is_lttng
= true;
4152 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4153 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4156 } else if (is_unary_unsigned(right_head
) ||
4157 is_unary_signed(right_head
)) {
4160 if (is_unary_unsigned(right_head
)) {
4161 ret
= get_unary_unsigned(ctx
, right_head
,
4164 ret
= get_unary_signed(right_head
, &v
);
4167 _BT_COMP_LOGE_NODE(entry_node
,
4168 "Unexpected unary expression for environment entry's value: "
4169 "name=\"%s\"", left
);
4174 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4175 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4178 _BT_COMP_LOGW_NODE(entry_node
,
4179 "Environment entry has unknown type: "
4180 "name=\"%s\"", left
);
4196 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4201 struct ctf_node
*node
;
4202 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4204 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4205 if (node
->type
== NODE_CTF_EXPRESSION
) {
4206 struct ctf_node
*right_node
;
4208 left
= concatenate_unary_strings(
4209 &node
->u
.ctf_expression
.left
);
4211 _BT_COMP_LOGE_NODE(node
,
4212 "Cannot concatenate unary strings.");
4217 if (strcmp(left
, "byte_order") == 0) {
4218 enum ctf_byte_order bo
;
4220 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4221 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
4227 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4228 right_node
= _BT_LIST_FIRST_ENTRY(
4229 &node
->u
.ctf_expression
.right
,
4230 struct ctf_node
, siblings
);
4231 bo
= byte_order_from_unary_expr(ctx
,
4234 _BT_COMP_LOGE_NODE(node
,
4235 "Invalid `byte_order` attribute in trace (`trace` block): "
4236 "expecting `le`, `be`, or `network`.");
4239 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4240 _BT_COMP_LOGE_NODE(node
,
4241 "Invalid `byte_order` attribute in trace (`trace` block): "
4242 "cannot be set to `native` here.");
4247 ctx
->ctf_tc
->default_byte_order
= bo
;
4255 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4256 _BT_COMP_LOGE_NODE(trace_node
,
4257 "Missing `byte_order` attribute in trace (`trace` block).");
4270 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4271 struct ctf_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4272 uint64_t *offset_cycles
)
4277 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4278 _BT_COMP_LOGE_NODE(entry_node
,
4279 "Unexpected node type: node-type=%d",
4285 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4287 _BT_COMP_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4292 if (strcmp(left
, "name") == 0) {
4295 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4296 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4301 right
= concatenate_unary_strings(
4302 &entry_node
->u
.ctf_expression
.right
);
4304 _BT_COMP_LOGE_NODE(entry_node
,
4305 "Unexpected unary expression for clock class's `name` attribute.");
4310 g_string_assign(clock
->name
, right
);
4312 _SET(set
, _CLOCK_NAME_SET
);
4313 } else if (strcmp(left
, "uuid") == 0) {
4316 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4317 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4322 ret
= get_unary_uuid(ctx
, &entry_node
->u
.ctf_expression
.right
,
4325 _BT_COMP_LOGE_NODE(entry_node
,
4326 "Invalid clock class's `uuid` attribute.");
4330 clock
->has_uuid
= true;
4331 bt_uuid_copy(clock
->uuid
, uuid
);
4332 _SET(set
, _CLOCK_UUID_SET
);
4333 } else if (strcmp(left
, "description") == 0) {
4336 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4337 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "description",
4343 right
= concatenate_unary_strings(
4344 &entry_node
->u
.ctf_expression
.right
);
4346 _BT_COMP_LOGE_NODE(entry_node
,
4347 "Unexpected unary expression for clock class's `description` attribute.");
4352 g_string_assign(clock
->description
, right
);
4354 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4355 } else if (strcmp(left
, "freq") == 0) {
4356 uint64_t freq
= UINT64_C(-1);
4358 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4359 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4364 ret
= get_unary_unsigned(ctx
,
4365 &entry_node
->u
.ctf_expression
.right
, &freq
);
4367 _BT_COMP_LOGE_NODE(entry_node
,
4368 "Unexpected unary expression for clock class's `freq` attribute.");
4373 if (freq
== UINT64_C(-1) || freq
== 0) {
4374 _BT_COMP_LOGE_NODE(entry_node
,
4375 "Invalid clock class frequency: freq=%" PRIu64
,
4381 clock
->frequency
= freq
;
4382 _SET(set
, _CLOCK_FREQ_SET
);
4383 } else if (strcmp(left
, "precision") == 0) {
4386 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4387 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "precision",
4393 ret
= get_unary_unsigned(ctx
,
4394 &entry_node
->u
.ctf_expression
.right
, &precision
);
4396 _BT_COMP_LOGE_NODE(entry_node
,
4397 "Unexpected unary expression for clock class's `precision` attribute.");
4402 clock
->precision
= precision
;
4403 _SET(set
, _CLOCK_PRECISION_SET
);
4404 } else if (strcmp(left
, "offset_s") == 0) {
4405 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4406 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset_s",
4412 ret
= get_unary_signed(
4413 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4415 _BT_COMP_LOGE_NODE(entry_node
,
4416 "Unexpected unary expression for clock class's `offset_s` attribute.");
4421 _SET(set
, _CLOCK_OFFSET_S_SET
);
4422 } else if (strcmp(left
, "offset") == 0) {
4423 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4424 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4429 ret
= get_unary_unsigned(ctx
,
4430 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4432 _BT_COMP_LOGE_NODE(entry_node
,
4433 "Unexpected unary expression for clock class's `offset` attribute.");
4438 _SET(set
, _CLOCK_OFFSET_SET
);
4439 } else if (strcmp(left
, "absolute") == 0) {
4440 struct ctf_node
*right
;
4442 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4443 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "absolute",
4449 right
= _BT_LIST_FIRST_ENTRY(
4450 &entry_node
->u
.ctf_expression
.right
,
4451 struct ctf_node
, siblings
);
4452 ret
= get_boolean(ctx
, right
);
4454 _BT_COMP_LOGE_NODE(entry_node
,
4455 "Unexpected unary expression for clock class's `absolute` attribute.");
4460 clock
->is_absolute
= ret
;
4461 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4463 _BT_COMP_LOGW_NODE(entry_node
,
4464 "Unknown attribute in clock class: attr-name=\"%s\"",
4478 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4483 if (frequency
== UINT64_C(1000000000)) {
4486 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4493 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4494 uint64_t *offset_cycles
, uint64_t freq
)
4496 if (*offset_cycles
>= freq
) {
4497 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4499 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4500 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4505 void apply_clock_class_offset(struct ctx
*ctx
,
4506 struct ctf_clock_class
*clock
)
4509 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4510 uint64_t offset_ns_to_apply
;
4511 int64_t cur_offset_s
;
4512 uint64_t cur_offset_cycles
;
4514 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4515 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4519 /* Transfer nanoseconds to seconds as much as possible */
4520 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4521 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4522 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4523 const int64_t extra_s
= -abs_extra_s
;
4524 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4525 (extra_s
* INT64_C(1000000000));
4527 BT_ASSERT(offset_ns
> 0);
4528 offset_ns_to_apply
= (uint64_t) offset_ns
;
4529 offset_s_to_apply
+= extra_s
;
4531 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4532 INT64_C(1000000000);
4533 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4534 (extra_s
* INT64_C(1000000000));
4536 BT_ASSERT(offset_ns
>= 0);
4537 offset_ns_to_apply
= (uint64_t) offset_ns
;
4538 offset_s_to_apply
+= extra_s
;
4541 freq
= clock
->frequency
;
4542 cur_offset_s
= clock
->offset_seconds
;
4543 cur_offset_cycles
= clock
->offset_cycles
;
4546 cur_offset_s
+= offset_s_to_apply
;
4547 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4550 * Recalibrate offsets because the part in cycles can be greater
4551 * than the frequency at this point.
4553 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4555 /* Set final offsets */
4556 clock
->offset_seconds
= cur_offset_s
;
4557 clock
->offset_cycles
= cur_offset_cycles
;
4564 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4568 struct ctf_clock_class
*clock
;
4569 struct ctf_node
*entry_node
;
4570 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4571 const char *clock_class_name
;
4572 int64_t offset_seconds
= 0;
4573 uint64_t offset_cycles
= 0;
4576 if (clock_node
->visited
) {
4580 clock_node
->visited
= TRUE
;
4582 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4583 clock
= ctf_clock_class_create();
4585 _BT_COMP_LOGE_NODE(clock_node
,
4586 "Cannot create default clock class.");
4591 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4592 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4593 &offset_seconds
, &offset_cycles
);
4595 _BT_COMP_LOGE_NODE(entry_node
,
4596 "Cannot visit clock class's entry: ret=%d",
4602 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4603 _BT_COMP_LOGE_NODE(clock_node
,
4604 "Missing `name` attribute in clock class.");
4609 clock_class_name
= clock
->name
->str
;
4610 BT_ASSERT(clock_class_name
);
4611 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4613 * Old versions of LTTng forgot to set its clock class
4614 * as absolute, even if it is. This is important because
4615 * it's a condition to be able to sort messages
4616 * from different sources.
4618 clock
->is_absolute
= true;
4622 * Adjust offsets so that the part in cycles is less than the
4623 * frequency (move to the part in seconds).
4625 freq
= clock
->frequency
;
4626 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4627 BT_ASSERT(offset_cycles
< clock
->frequency
);
4628 clock
->offset_seconds
= offset_seconds
;
4629 clock
->offset_cycles
= offset_cycles
;
4630 apply_clock_class_offset(ctx
, clock
);
4631 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4636 ctf_clock_class_destroy(clock
);
4643 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4647 if (root_decl_node
->visited
) {
4651 root_decl_node
->visited
= TRUE
;
4653 switch (root_decl_node
->type
) {
4655 ret
= visit_field_class_def(ctx
,
4656 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4657 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4659 _BT_COMP_LOGE_NODE(root_decl_node
,
4660 "Cannot add field class found in root scope.");
4664 case NODE_TYPEALIAS
:
4665 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4666 root_decl_node
->u
.field_class_alias
.alias
);
4668 _BT_COMP_LOGE_NODE(root_decl_node
,
4669 "Cannot add field class alias found in root scope.");
4673 case NODE_TYPE_SPECIFIER_LIST
:
4675 struct ctf_field_class
*decl
= NULL
;
4678 * Just add the field class specifier to the root
4679 * declaration scope. Put local reference.
4681 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4683 _BT_COMP_LOGE_NODE(root_decl_node
,
4684 "Cannot visit root scope's field class: "
4690 ctf_field_class_destroy(decl
);
4695 _BT_COMP_LOGE_NODE(root_decl_node
,
4696 "Unexpected node type: node-type=%d",
4697 root_decl_node
->type
);
4707 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4708 const struct ctf_metadata_decoder_config
*decoder_config
)
4710 struct ctx
*ctx
= NULL
;
4712 /* Create visitor's context */
4713 ctx
= ctx_create(decoder_config
);
4715 BT_COMP_LOGE_STR("Cannot create visitor's context.");
4726 return (void *) ctx
;
4730 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4732 ctx_destroy((void *) visitor
);
4736 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4737 struct ctf_visitor_generate_ir
*visitor
)
4739 struct ctx
*ctx
= (void *) visitor
;
4743 if (ctx
->trace_class
) {
4744 bt_trace_class_get_ref(ctx
->trace_class
);
4747 return ctx
->trace_class
;
4751 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4752 struct ctf_visitor_generate_ir
*visitor
)
4754 struct ctx
*ctx
= (void *) visitor
;
4757 BT_ASSERT(ctx
->ctf_tc
);
4762 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4763 struct ctf_node
*node
)
4766 struct ctx
*ctx
= (void *) visitor
;
4768 BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4770 switch (node
->type
) {
4773 struct ctf_node
*iter
;
4774 bool got_trace_decl
= false;
4777 * The first thing we need is the native byte order of
4778 * the trace block, because early class aliases can have
4779 * a `byte_order` attribute set to `native`. If we don't
4780 * have the native byte order yet, and we don't have any
4781 * trace block yet, then fail with EINCOMPLETE.
4783 if (ctx
->ctf_tc
->default_byte_order
== -1) {
4784 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4785 if (got_trace_decl
) {
4786 _BT_COMP_LOGE_NODE(node
,
4787 "Duplicate trace (`trace` block).");
4792 ret
= set_trace_byte_order(ctx
, iter
);
4794 _BT_COMP_LOGE_NODE(node
,
4795 "Cannot set trace's native byte order: "
4800 got_trace_decl
= true;
4803 if (!got_trace_decl
) {
4804 BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4810 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4811 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4812 BT_ASSERT(ctx
->current_scope
&&
4813 !ctx
->current_scope
->parent_scope
);
4816 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4817 ret
= visit_env(ctx
, iter
);
4819 _BT_COMP_LOGE_NODE(iter
,
4820 "Cannot visit trace's environment (`env` block) entry: "
4826 BT_ASSERT(ctx
->current_scope
&&
4827 !ctx
->current_scope
->parent_scope
);
4830 * Visit clock blocks.
4832 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4833 ret
= visit_clock_decl(ctx
, iter
);
4835 _BT_COMP_LOGE_NODE(iter
,
4836 "Cannot visit clock class: ret=%d",
4842 BT_ASSERT(ctx
->current_scope
&&
4843 !ctx
->current_scope
->parent_scope
);
4846 * Visit root declarations next, as they can be used by any
4849 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4851 ret
= visit_root_decl(ctx
, iter
);
4853 _BT_COMP_LOGE_NODE(iter
,
4854 "Cannot visit root entry: ret=%d",
4860 BT_ASSERT(ctx
->current_scope
&&
4861 !ctx
->current_scope
->parent_scope
);
4863 /* Callsite blocks are not supported */
4864 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4865 _BT_COMP_LOGW_NODE(iter
,
4866 "\"callsite\" blocks are not supported as of this version.");
4869 BT_ASSERT(ctx
->current_scope
&&
4870 !ctx
->current_scope
->parent_scope
);
4873 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4874 ret
= visit_trace_decl(ctx
, iter
);
4876 _BT_COMP_LOGE_NODE(iter
,
4877 "Cannot visit trace (`trace` block): "
4883 BT_ASSERT(ctx
->current_scope
&&
4884 !ctx
->current_scope
->parent_scope
);
4887 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4888 ret
= visit_stream_decl(ctx
, iter
);
4890 _BT_COMP_LOGE_NODE(iter
,
4891 "Cannot visit stream class: ret=%d",
4897 BT_ASSERT(ctx
->current_scope
&&
4898 !ctx
->current_scope
->parent_scope
);
4901 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4902 ret
= visit_event_decl(ctx
, iter
);
4904 _BT_COMP_LOGE_NODE(iter
,
4905 "Cannot visit event class: ret=%d",
4911 BT_ASSERT(ctx
->current_scope
&&
4912 !ctx
->current_scope
->parent_scope
);
4916 _BT_COMP_LOGE_NODE(node
,
4917 "Unexpected node type: node-type=%d",
4923 /* Update default clock classes */
4924 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
,
4931 /* Update trace class meanings */
4932 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
4938 /* Update stream class configuration */
4939 ret
= ctf_trace_class_update_stream_class_config(ctx
->ctf_tc
);
4945 /* Update text arrays and sequences */
4946 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
4952 /* Resolve sequence lengths and variant tags */
4953 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
, &ctx
->log_cfg
);
4959 if (ctx
->trace_class
) {
4961 * Update "in IR" for field classes.
4963 * If we have no IR trace class, then we'll have no way
4964 * to create IR fields anyway, so we leave all the
4965 * `in_ir` members false.
4967 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
4974 /* Update saved value indexes */
4975 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
4981 /* Validate what we have so far */
4982 ret
= ctf_trace_class_validate(ctx
->ctf_tc
, &ctx
->log_cfg
);
4989 * If there are fields which are not related to the CTF format
4990 * itself in the packet header and in event header field
4991 * classes, warn about it because they are never translated.
4993 ctf_trace_class_warn_meaningless_header_fields(ctx
->ctf_tc
,
4996 if (ctx
->trace_class
) {
4997 /* Copy new CTF metadata -> new IR metadata */
4998 ret
= ctf_trace_class_translate(ctx
->log_cfg
.self_comp
,
4999 ctx
->trace_class
, ctx
->ctf_tc
);