2 * SPDX-License-Identifier: MIT
4 * Copyright 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * Copyright 2015-2018 Philippe Proulx <philippe.proulx@efficios.com>
7 * Common Trace Format metadata visitor (generates CTF IR objects).
10 #define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp)
11 #define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level)
12 #define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
13 #include "logging/comp-logging.h"
21 #include "common/assert.h"
25 #include "common/common.h"
26 #include "common/uuid.h"
27 #include "compat/endian.h"
28 #include <babeltrace2/babeltrace.h>
35 #include "ctf-meta-visitors.h"
37 /* Bit value (left shift) */
38 #define _BV(_val) (1 << (_val))
40 /* Bit is set in a set of bits */
41 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
43 /* Set bit in a set of bits */
44 #define _SET(_set, _mask) (*(_set) |= (_mask))
46 /* Try to push scope, or go to the `error` label */
47 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
49 ret = ctx_push_scope(ctx); \
51 BT_COMP_LOGE_STR("Cannot push scope."); \
56 /* Bits for verifying existing attributes in various declarations */
58 _CLOCK_NAME_SET
= _BV(0),
59 _CLOCK_UUID_SET
= _BV(1),
60 _CLOCK_FREQ_SET
= _BV(2),
61 _CLOCK_PRECISION_SET
= _BV(3),
62 _CLOCK_OFFSET_S_SET
= _BV(4),
63 _CLOCK_OFFSET_SET
= _BV(5),
64 _CLOCK_ABSOLUTE_SET
= _BV(6),
65 _CLOCK_DESCRIPTION_SET
= _BV(7),
69 _INTEGER_ALIGN_SET
= _BV(0),
70 _INTEGER_SIZE_SET
= _BV(1),
71 _INTEGER_BASE_SET
= _BV(2),
72 _INTEGER_ENCODING_SET
= _BV(3),
73 _INTEGER_BYTE_ORDER_SET
= _BV(4),
74 _INTEGER_SIGNED_SET
= _BV(5),
75 _INTEGER_MAP_SET
= _BV(6),
79 _FLOAT_ALIGN_SET
= _BV(0),
80 _FLOAT_MANT_DIG_SET
= _BV(1),
81 _FLOAT_EXP_DIG_SET
= _BV(2),
82 _FLOAT_BYTE_ORDER_SET
= _BV(3),
86 _STRING_ENCODING_SET
= _BV(0),
90 _TRACE_MINOR_SET
= _BV(0),
91 _TRACE_MAJOR_SET
= _BV(1),
92 _TRACE_BYTE_ORDER_SET
= _BV(2),
93 _TRACE_UUID_SET
= _BV(3),
94 _TRACE_PACKET_HEADER_SET
= _BV(4),
98 _STREAM_ID_SET
= _BV(0),
99 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
100 _STREAM_EVENT_HEADER_SET
= _BV(2),
101 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
105 _EVENT_NAME_SET
= _BV(0),
106 _EVENT_ID_SET
= _BV(1),
107 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
108 _EVENT_STREAM_ID_SET
= _BV(3),
109 _EVENT_LOG_LEVEL_SET
= _BV(4),
110 _EVENT_CONTEXT_SET
= _BV(5),
111 _EVENT_FIELDS_SET
= _BV(6),
119 LOG_LEVEL_WARNING
= 4,
120 LOG_LEVEL_NOTICE
= 5,
122 LOG_LEVEL_DEBUG_SYSTEM
= 7,
123 LOG_LEVEL_DEBUG_PROGRAM
= 8,
124 LOG_LEVEL_DEBUG_PROCESS
= 9,
125 LOG_LEVEL_DEBUG_MODULE
= 10,
126 LOG_LEVEL_DEBUG_UNIT
= 11,
127 LOG_LEVEL_DEBUG_FUNCTION
= 12,
128 LOG_LEVEL_DEBUG_LINE
= 13,
129 LOG_LEVEL_DEBUG
= 14,
133 /* Prefixes of class aliases */
134 #define _PREFIX_ALIAS 'a'
135 #define _PREFIX_ENUM 'e'
136 #define _PREFIX_STRUCT 's'
137 #define _PREFIX_VARIANT 'v'
139 /* First entry in a BT list */
140 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
141 bt_list_entry((_ptr)->next, _class, _member)
143 #define _BT_COMP_LOGE_DUP_ATTR(_node, _attr, _entity) \
144 _BT_COMP_LOGE_LINENO((_node)->lineno, \
145 "Duplicate attribute in %s: attr-name=\"%s\"", \
148 #define _BT_COMP_LOGE_NODE(_node, _msg, args...) \
149 _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args)
151 #define _BT_COMP_LOGW_NODE(_node, _msg, args...) \
152 _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args)
154 #define _BT_COMP_LOGT_NODE(_node, _msg, args...) \
155 _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args)
158 * Declaration scope of a visitor context. This represents a TSDL
159 * lexical scope, so that aliases and named structures, variants,
160 * and enumerations may be registered and looked up hierarchically.
162 struct ctx_decl_scope
{
164 * Alias name to field class.
166 * GQuark -> struct ctf_field_class * (owned by this)
168 GHashTable
*decl_map
;
170 /* Parent scope; NULL if this is the root declaration scope */
171 struct ctx_decl_scope
*parent_scope
;
175 * Visitor context (private).
178 struct meta_log_config log_cfg
;
180 /* Trace IR trace class being filled (owned by this) */
181 bt_trace_class
*trace_class
;
183 /* CTF meta trace being filled (owned by this) */
184 struct ctf_trace_class
*ctf_tc
;
186 /* Current declaration scope (top of the stack) (owned by this) */
187 struct ctx_decl_scope
*current_scope
;
189 /* True if trace declaration is visited */
190 bool is_trace_visited
;
192 /* True if this is an LTTng trace */
195 /* Config passed by the user */
196 struct ctf_metadata_decoder_config decoder_config
;
202 struct ctf_visitor_generate_ir
;
205 * Creates a new declaration scope.
207 * @param par_scope Parent scope (NULL if creating a root scope)
208 * @returns New declaration scope, or NULL on error
211 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx
*ctx
,
212 struct ctx_decl_scope
*par_scope
)
214 struct ctx_decl_scope
*scope
;
216 scope
= g_new(struct ctx_decl_scope
, 1);
218 BT_COMP_LOGE_STR("Failed to allocate one declaration scope.");
222 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
223 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
224 scope
->parent_scope
= par_scope
;
231 * Destroys a declaration scope.
233 * This function does not destroy the parent scope.
235 * @param scope Scope to destroy
238 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
244 g_hash_table_destroy(scope
->decl_map
);
252 * Returns the GQuark of a prefixed alias.
254 * @param prefix Prefix character
256 * @returns Associated GQuark, or 0 on error
259 GQuark
get_prefixed_named_quark(struct ctx
*ctx
, char prefix
, const char *name
)
265 /* Prefix character + original string + '\0' */
266 char *prname
= g_new(char, strlen(name
) + 2);
268 BT_COMP_LOGE_STR("Failed to allocate a string.");
272 sprintf(prname
, "%c%s", prefix
, name
);
273 qname
= g_quark_from_string(prname
);
281 * Looks up a prefixed class alias within a declaration scope.
283 * @param scope Declaration scope
284 * @param prefix Prefix character
285 * @param name Alias name
286 * @param levels Number of levels to dig into (-1 means infinite)
287 * @param copy True to return a copy
288 * @returns Declaration (owned by caller if \p copy is true),
289 * or NULL if not found
292 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
293 struct ctx
*ctx
, struct ctx_decl_scope
*scope
, char prefix
,
294 const char *name
, int levels
, bool copy
)
298 struct ctf_field_class
*decl
= NULL
;
299 struct ctx_decl_scope
*cur_scope
= scope
;
303 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
312 while (cur_scope
&& cur_levels
< levels
) {
313 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
314 (gconstpointer
) GUINT_TO_POINTER(qname
));
316 /* Caller's reference */
318 decl
= ctf_field_class_copy(decl
);
325 cur_scope
= cur_scope
->parent_scope
;
334 * Looks up a class alias within a declaration scope.
336 * @param scope Declaration scope
337 * @param name Alias name
338 * @param levels Number of levels to dig into (-1 means infinite)
339 * @param copy True to return a copy
340 * @returns Declaration (owned by caller if \p copy is true),
341 * or NULL if not found
344 struct ctf_field_class
*ctx_decl_scope_lookup_alias(struct ctx
*ctx
,
345 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
348 return ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
353 * Looks up an enumeration within a declaration scope.
355 * @param scope Declaration scope
356 * @param name Enumeration name
357 * @param levels Number of levels to dig into (-1 means infinite)
358 * @param copy True to return a copy
359 * @returns Declaration (owned by caller if \p copy is true),
360 * or NULL if not found
363 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(struct ctx
*ctx
,
364 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
367 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
368 _PREFIX_ENUM
, name
, levels
, copy
);
372 * Looks up a structure within a declaration scope.
374 * @param scope Declaration scope
375 * @param name Structure name
376 * @param levels Number of levels to dig into (-1 means infinite)
377 * @param copy True to return a copy
378 * @returns Declaration (owned by caller if \p copy is true),
379 * or NULL if not found
382 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(struct ctx
*ctx
,
383 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
386 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
387 _PREFIX_STRUCT
, name
, levels
, copy
);
391 * Looks up a variant within a declaration scope.
393 * @param scope Declaration scope
394 * @param name Variant name
395 * @param levels Number of levels to dig into (-1 means infinite)
396 * @param copy True to return a copy
397 * @returns Declaration (owned by caller if \p copy is true),
398 * or NULL if not found
401 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(struct ctx
*ctx
,
402 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
405 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
406 _PREFIX_VARIANT
, name
, levels
, copy
);
410 * Registers a prefixed class alias within a declaration scope.
412 * @param scope Declaration scope
413 * @param prefix Prefix character
414 * @param name Alias name (non-NULL)
415 * @param decl Field class to register (copied)
416 * @returns 0 if registration went okay, negative value otherwise
419 int ctx_decl_scope_register_prefix_alias(struct ctx
*ctx
,
420 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
421 struct ctf_field_class
*decl
)
429 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
435 /* Make sure alias does not exist in local scope */
436 if (ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, prefix
, name
, 1,
442 decl
= ctf_field_class_copy(decl
);
444 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
451 * Registers a class alias within a declaration scope.
453 * @param scope Declaration scope
454 * @param name Alias name (non-NULL)
455 * @param decl Field class to register (copied)
456 * @returns 0 if registration went okay, negative value otherwise
459 int ctx_decl_scope_register_alias(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
460 const char *name
, struct ctf_field_class
*decl
)
462 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
463 name
, (void *) decl
);
467 * Registers an enumeration declaration within a declaration scope.
469 * @param scope Declaration scope
470 * @param name Enumeration name (non-NULL)
471 * @param decl Enumeration field class to register (copied)
472 * @returns 0 if registration went okay, negative value otherwise
475 int ctx_decl_scope_register_enum(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
476 const char *name
, struct ctf_field_class_enum
*decl
)
478 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ENUM
,
479 name
, (void *) decl
);
483 * Registers a structure declaration within a declaration scope.
485 * @param scope Declaration scope
486 * @param name Structure name (non-NULL)
487 * @param decl Structure field class to register (copied)
488 * @returns 0 if registration went okay, negative value otherwise
491 int ctx_decl_scope_register_struct(struct ctx
*ctx
,
492 struct ctx_decl_scope
*scope
, const char *name
,
493 struct ctf_field_class_struct
*decl
)
495 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_STRUCT
,
496 name
, (void *) decl
);
500 * Registers a variant declaration within a declaration scope.
502 * @param scope Declaration scope
503 * @param name Variant name (non-NULL)
504 * @param decl Variant field class to register
505 * @returns 0 if registration went okay, negative value otherwise
508 int ctx_decl_scope_register_variant(struct ctx
*ctx
,
509 struct ctx_decl_scope
*scope
, const char *name
,
510 struct ctf_field_class_variant
*decl
)
512 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_VARIANT
,
513 name
, (void *) decl
);
517 * Destroys a visitor context.
519 * @param ctx Visitor context to destroy
522 void ctx_destroy(struct ctx
*ctx
)
524 struct ctx_decl_scope
*scope
;
530 scope
= ctx
->current_scope
;
533 * Destroy all scopes, from current one to the root scope.
536 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
538 ctx_decl_scope_destroy(scope
);
539 scope
= parent_scope
;
542 bt_trace_class_put_ref(ctx
->trace_class
);
545 ctf_trace_class_destroy(ctx
->ctf_tc
);
555 * Creates a new visitor context.
557 * @param trace Associated trace
558 * @returns New visitor context, or NULL on error
561 struct ctx
*ctx_create(const struct ctf_metadata_decoder_config
*decoder_config
)
563 struct ctx
*ctx
= NULL
;
565 BT_ASSERT(decoder_config
);
567 ctx
= g_new0(struct ctx
, 1);
569 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
570 decoder_config
->self_comp
,
571 "Failed to allocate one visitor context.");
575 ctx
->log_cfg
.log_level
= decoder_config
->log_level
;
576 ctx
->log_cfg
.self_comp
= decoder_config
->self_comp
;
578 if (decoder_config
->self_comp
) {
579 ctx
->trace_class
= bt_trace_class_create(
580 decoder_config
->self_comp
);
581 if (!ctx
->trace_class
) {
582 BT_COMP_LOGE_STR("Cannot create empty trace class.");
587 ctx
->ctf_tc
= ctf_trace_class_create();
589 BT_COMP_LOGE_STR("Cannot create CTF trace class.");
593 /* Root declaration scope */
594 ctx
->current_scope
= ctx_decl_scope_create(ctx
, NULL
);
595 if (!ctx
->current_scope
) {
596 BT_COMP_LOGE_STR("Cannot create declaration scope.");
600 ctx
->decoder_config
= *decoder_config
;
612 * Pushes a new declaration scope on top of a visitor context's
613 * declaration scope stack.
615 * @param ctx Visitor context
616 * @returns 0 on success, or a negative value on error
619 int ctx_push_scope(struct ctx
*ctx
)
622 struct ctx_decl_scope
*new_scope
;
625 new_scope
= ctx_decl_scope_create(ctx
, ctx
->current_scope
);
627 BT_COMP_LOGE_STR("Cannot create declaration scope.");
632 ctx
->current_scope
= new_scope
;
639 void ctx_pop_scope(struct ctx
*ctx
)
641 struct ctx_decl_scope
*parent_scope
= NULL
;
645 if (!ctx
->current_scope
) {
649 parent_scope
= ctx
->current_scope
->parent_scope
;
650 ctx_decl_scope_destroy(ctx
->current_scope
);
651 ctx
->current_scope
= parent_scope
;
658 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
659 struct ctf_field_class
**decl
);
662 int is_unary_string(struct bt_list_head
*head
)
665 struct ctf_node
*node
;
667 bt_list_for_each_entry(node
, head
, siblings
) {
668 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
672 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
681 const char *get_map_clock_name_value(struct bt_list_head
*head
)
684 struct ctf_node
*node
;
685 const char *name
= NULL
;
687 bt_list_for_each_entry(node
, head
, siblings
) {
689 int uexpr_type
= node
->u
.unary_expression
.type
;
690 int uexpr_link
= node
->u
.unary_expression
.link
;
691 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
692 uexpr_type
!= UNARY_STRING
||
693 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
698 /* Needs to be chained with . */
699 switch (node
->u
.unary_expression
.link
) {
702 case UNARY_ARROWLINK
:
703 case UNARY_DOTDOTDOT
:
709 src_string
= node
->u
.unary_expression
.u
.string
;
713 if (strcmp("clock", src_string
)) {
721 if (strcmp("value", src_string
)) {
726 /* Extra identifier, unknown */
740 int is_unary_unsigned(struct bt_list_head
*head
)
743 struct ctf_node
*node
;
745 bt_list_for_each_entry(node
, head
, siblings
) {
746 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
750 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
759 int get_unary_unsigned(struct ctx
*ctx
, struct bt_list_head
*head
,
764 struct ctf_node
*node
;
768 if (bt_list_empty(head
)) {
773 bt_list_for_each_entry(node
, head
, siblings
) {
774 int uexpr_type
= node
->u
.unary_expression
.type
;
775 int uexpr_link
= node
->u
.unary_expression
.link
;
776 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
777 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
778 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
780 _BT_COMP_LOGE_NODE(node
, "Invalid constant unsigned integer.");
785 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
794 int is_unary_signed(struct bt_list_head
*head
)
797 struct ctf_node
*node
;
799 bt_list_for_each_entry(node
, head
, siblings
) {
800 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
804 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
813 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
817 struct ctf_node
*node
;
819 bt_list_for_each_entry(node
, head
, siblings
) {
820 int uexpr_type
= node
->u
.unary_expression
.type
;
821 int uexpr_link
= node
->u
.unary_expression
.link
;
822 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
823 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
824 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
825 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
831 switch (uexpr_type
) {
832 case UNARY_UNSIGNED_CONSTANT
:
834 node
->u
.unary_expression
.u
.unsigned_constant
;
836 case UNARY_SIGNED_CONSTANT
:
837 *value
= node
->u
.unary_expression
.u
.signed_constant
;
852 int get_unary_uuid(struct ctx
*ctx
, struct bt_list_head
*head
,
855 return ctf_ast_get_unary_uuid(head
, uuid
, ctx
->log_cfg
.log_level
,
856 ctx
->log_cfg
.self_comp
);
860 int get_boolean(struct ctx
*ctx
, struct ctf_node
*unary_expr
)
864 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
865 _BT_COMP_LOGE_NODE(unary_expr
,
866 "Expecting unary expression: node-type=%d",
872 switch (unary_expr
->u
.unary_expression
.type
) {
873 case UNARY_UNSIGNED_CONSTANT
:
874 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
876 case UNARY_SIGNED_CONSTANT
:
877 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
881 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
883 if (strcmp(str
, "true") == 0 || strcmp(str
, "TRUE") == 0) {
885 } else if (strcmp(str
, "false") == 0 || strcmp(str
, "FALSE") == 0) {
888 _BT_COMP_LOGE_NODE(unary_expr
,
889 "Unexpected boolean value: value=\"%s\"", str
);
896 _BT_COMP_LOGE_NODE(unary_expr
,
897 "Unexpected unary expression type: node-type=%d",
898 unary_expr
->u
.unary_expression
.type
);
908 enum ctf_byte_order
byte_order_from_unary_expr(struct ctx
*ctx
,
909 struct ctf_node
*unary_expr
)
912 enum ctf_byte_order bo
= CTF_BYTE_ORDER_UNKNOWN
;
914 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
915 _BT_COMP_LOGE_NODE(unary_expr
,
916 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
920 str
= unary_expr
->u
.unary_expression
.u
.string
;
922 if (strcmp(str
, "be") == 0 || strcmp(str
, "network") == 0) {
923 bo
= CTF_BYTE_ORDER_BIG
;
924 } else if (strcmp(str
, "le") == 0) {
925 bo
= CTF_BYTE_ORDER_LITTLE
;
926 } else if (strcmp(str
, "native") == 0) {
927 bo
= CTF_BYTE_ORDER_DEFAULT
;
929 _BT_COMP_LOGE_NODE(unary_expr
,
930 "Unexpected \"byte_order\" attribute value: "
931 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
941 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
942 struct ctf_node
*uexpr
)
944 enum ctf_byte_order bo
= byte_order_from_unary_expr(ctx
, uexpr
);
946 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
947 bo
= ctx
->ctf_tc
->default_byte_order
;
954 int is_align_valid(uint64_t align
)
956 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
960 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
965 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
966 _BT_COMP_LOGE_NODE(cls_specifier
,
967 "Unexpected node type: node-type=%d",
968 cls_specifier
->type
);
973 switch (cls_specifier
->u
.field_class_specifier
.type
) {
975 g_string_append(str
, "void");
978 g_string_append(str
, "char");
981 g_string_append(str
, "short");
984 g_string_append(str
, "int");
987 g_string_append(str
, "long");
990 g_string_append(str
, "float");
992 case TYPESPEC_DOUBLE
:
993 g_string_append(str
, "double");
995 case TYPESPEC_SIGNED
:
996 g_string_append(str
, "signed");
998 case TYPESPEC_UNSIGNED
:
999 g_string_append(str
, "unsigned");
1002 g_string_append(str
, "bool");
1004 case TYPESPEC_COMPLEX
:
1005 g_string_append(str
, "_Complex");
1007 case TYPESPEC_IMAGINARY
:
1008 g_string_append(str
, "_Imaginary");
1010 case TYPESPEC_CONST
:
1011 g_string_append(str
, "const");
1013 case TYPESPEC_ID_TYPE
:
1014 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1015 g_string_append(str
,
1016 cls_specifier
->u
.field_class_specifier
.id_type
);
1019 case TYPESPEC_STRUCT
:
1021 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1023 if (!node
->u
._struct
.name
) {
1024 _BT_COMP_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1029 g_string_append(str
, "struct ");
1030 g_string_append(str
, node
->u
._struct
.name
);
1033 case TYPESPEC_VARIANT
:
1035 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1037 if (!node
->u
.variant
.name
) {
1038 _BT_COMP_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1043 g_string_append(str
, "variant ");
1044 g_string_append(str
, node
->u
.variant
.name
);
1049 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1051 if (!node
->u
._enum
.enum_id
) {
1052 _BT_COMP_LOGE_NODE(node
,
1053 "Unexpected empty enumeration field class (`enum`) name.");
1058 g_string_append(str
, "enum ");
1059 g_string_append(str
, node
->u
._enum
.enum_id
);
1062 case TYPESPEC_FLOATING_POINT
:
1063 case TYPESPEC_INTEGER
:
1064 case TYPESPEC_STRING
:
1066 _BT_COMP_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1067 "Unexpected field class specifier type: %d",
1068 cls_specifier
->u
.field_class_specifier
.type
);
1078 int get_class_specifier_list_name(struct ctx
*ctx
,
1079 struct ctf_node
*cls_specifier_list
, GString
*str
)
1082 struct ctf_node
*iter
;
1083 int alias_item_nr
= 0;
1084 struct bt_list_head
*head
=
1085 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1087 bt_list_for_each_entry(iter
, head
, siblings
) {
1088 if (alias_item_nr
!= 0) {
1089 g_string_append(str
, " ");
1093 ret
= get_class_specifier_name(ctx
, iter
, str
);
1104 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1105 struct ctf_node
*cls_specifier_list
,
1106 struct ctf_node
*node_field_class_declarator
)
1112 struct ctf_node
*iter
;
1113 struct bt_list_head
*pointers
=
1114 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1116 str
= g_string_new("");
1117 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1119 g_string_free(str
, TRUE
);
1123 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1124 g_string_append(str
, " *");
1126 if (iter
->u
.pointer
.const_qualifier
) {
1127 g_string_append(str
, " const");
1131 str_c
= g_string_free(str
, FALSE
);
1132 qalias
= g_quark_from_string(str_c
);
1140 int visit_field_class_declarator(struct ctx
*ctx
,
1141 struct ctf_node
*cls_specifier_list
,
1142 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1143 struct ctf_field_class
**field_decl
,
1144 struct ctf_field_class
*nested_decl
)
1147 * During this whole function, nested_decl is always OURS,
1148 * whereas field_decl is an output which we create, but
1149 * belongs to the caller (it is moved).
1154 /* Validate field class declarator node */
1155 if (node_field_class_declarator
) {
1156 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1158 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1159 "Unexpected field class declarator type: type=%d",
1160 node_field_class_declarator
->u
.field_class_declarator
.type
);
1165 /* TODO: GCC bitfields not supported yet */
1166 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1168 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1169 "GCC bitfields are not supported as of this version.");
1175 /* Find the right nested declaration if not provided */
1177 struct bt_list_head
*pointers
=
1178 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1180 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1184 * If we have a pointer declarator, it HAS to
1185 * be present in the field class aliases (else
1188 qalias
= create_class_alias_identifier(ctx
,
1189 cls_specifier_list
, node_field_class_declarator
);
1191 ctx_decl_scope_lookup_alias(ctx
,
1193 g_quark_to_string(qalias
), -1, true);
1195 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1196 "Cannot find class alias: name=\"%s\"",
1197 g_quark_to_string(qalias
));
1202 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1203 /* Pointer: force integer's base to 16 */
1204 struct ctf_field_class_int
*int_fc
=
1205 (void *) nested_decl
;
1208 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1211 ret
= visit_field_class_specifier_list(ctx
,
1212 cls_specifier_list
, &nested_decl
);
1214 BT_ASSERT(!nested_decl
);
1220 BT_ASSERT(nested_decl
);
1222 if (!node_field_class_declarator
) {
1223 *field_decl
= nested_decl
;
1228 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1229 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1231 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1233 *field_name
= g_quark_from_string(id
);
1238 *field_decl
= nested_decl
;
1242 struct ctf_node
*first
;
1243 struct ctf_field_class
*decl
= NULL
;
1244 struct ctf_field_class
*outer_field_decl
= NULL
;
1245 struct bt_list_head
*length
=
1246 &node_field_class_declarator
->
1247 u
.field_class_declarator
.u
.nested
.length
;
1249 /* Create array/sequence, pass nested_decl as child */
1250 if (bt_list_empty(length
)) {
1251 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1252 "Expecting length field reference or value.");
1257 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1258 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1259 _BT_COMP_LOGE_NODE(first
,
1260 "Unexpected node type: node-type=%d",
1266 switch (first
->u
.unary_expression
.type
) {
1267 case UNARY_UNSIGNED_CONSTANT
:
1269 struct ctf_field_class_array
*array_decl
= NULL
;
1271 array_decl
= ctf_field_class_array_create();
1272 BT_ASSERT(array_decl
);
1273 array_decl
->length
=
1274 first
->u
.unary_expression
.u
.unsigned_constant
;
1275 array_decl
->base
.elem_fc
= nested_decl
;
1277 decl
= (void *) array_decl
;
1282 /* Lookup unsigned integer definition, create seq. */
1283 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1284 char *length_name
= ctf_ast_concatenate_unary_strings(length
);
1287 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1288 "Cannot concatenate unary strings.");
1293 if (strncmp(length_name
, "env.", 4) == 0) {
1294 /* This is, in fact, an array */
1295 const char *env_entry_name
= &length_name
[4];
1296 struct ctf_trace_class_env_entry
*env_entry
=
1297 ctf_trace_class_borrow_env_entry_by_name(
1298 ctx
->ctf_tc
, env_entry_name
);
1299 struct ctf_field_class_array
*array_decl
;
1302 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1303 "Cannot find environment entry: "
1304 "name=\"%s\"", env_entry_name
);
1309 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1310 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1311 "Wrong environment entry type "
1312 "(expecting integer): "
1313 "name=\"%s\"", env_entry_name
);
1318 if (env_entry
->value
.i
< 0) {
1319 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1320 "Invalid, negative array length: "
1321 "env-entry-name=\"%s\", "
1324 env_entry
->value
.i
);
1329 array_decl
= ctf_field_class_array_create();
1330 BT_ASSERT(array_decl
);
1331 array_decl
->length
=
1332 (uint64_t) env_entry
->value
.i
;
1333 array_decl
->base
.elem_fc
= nested_decl
;
1335 decl
= (void *) array_decl
;
1337 seq_decl
= ctf_field_class_sequence_create();
1338 BT_ASSERT(seq_decl
);
1339 seq_decl
->base
.elem_fc
= nested_decl
;
1341 g_string_assign(seq_decl
->length_ref
,
1343 decl
= (void *) seq_decl
;
1346 g_free(length_name
);
1354 BT_ASSERT(!nested_decl
);
1356 BT_ASSERT(!*field_decl
);
1359 * At this point, we found the next nested declaration.
1360 * We currently own this (and lost the ownership of
1361 * nested_decl in the meantime). Pass this next
1362 * nested declaration as the content of the outer
1363 * container, MOVING its ownership.
1365 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1367 node_field_class_declarator
->
1368 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1369 &outer_field_decl
, decl
);
1372 BT_ASSERT(!outer_field_decl
);
1377 BT_ASSERT(outer_field_decl
);
1378 *field_decl
= outer_field_decl
;
1379 outer_field_decl
= NULL
;
1382 BT_ASSERT(*field_decl
);
1386 ctf_field_class_destroy(*field_decl
);
1394 ctf_field_class_destroy(nested_decl
);
1400 int visit_struct_decl_field(struct ctx
*ctx
,
1401 struct ctf_field_class_struct
*struct_decl
,
1402 struct ctf_node
*cls_specifier_list
,
1403 struct bt_list_head
*field_class_declarators
)
1406 struct ctf_node
*iter
;
1407 struct ctf_field_class
*field_decl
= NULL
;
1409 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1412 const char *field_name
;
1414 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1415 &qfield_name
, iter
, &field_decl
, NULL
);
1417 BT_ASSERT(!field_decl
);
1418 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1419 "Cannot visit field class declarator: ret=%d", ret
);
1423 BT_ASSERT(field_decl
);
1424 field_name
= g_quark_to_string(qfield_name
);
1426 /* Check if field with same name already exists */
1427 if (ctf_field_class_struct_borrow_member_by_name(
1428 struct_decl
, field_name
)) {
1429 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1430 "Duplicate field in structure field class: "
1431 "field-name=\"%s\"", field_name
);
1436 /* Add field to structure */
1437 ctf_field_class_struct_append_member(struct_decl
,
1438 field_name
, field_decl
);
1445 ctf_field_class_destroy(field_decl
);
1451 int visit_variant_decl_field(struct ctx
*ctx
,
1452 struct ctf_field_class_variant
*variant_decl
,
1453 struct ctf_node
*cls_specifier_list
,
1454 struct bt_list_head
*field_class_declarators
)
1457 struct ctf_node
*iter
;
1458 struct ctf_field_class
*field_decl
= NULL
;
1460 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1463 const char *field_name
;
1465 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1466 &qfield_name
, iter
, &field_decl
, NULL
);
1468 BT_ASSERT(!field_decl
);
1469 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1470 "Cannot visit field class declarator: ret=%d", ret
);
1474 BT_ASSERT(field_decl
);
1475 field_name
= g_quark_to_string(qfield_name
);
1477 /* Check if field with same name already exists */
1478 if (ctf_field_class_variant_borrow_option_by_name(
1479 variant_decl
, field_name
)) {
1480 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1481 "Duplicate field in variant field class: "
1482 "field-name=\"%s\"", field_name
);
1487 /* Add field to structure */
1488 ctf_field_class_variant_append_option(variant_decl
,
1489 field_name
, field_decl
);
1496 ctf_field_class_destroy(field_decl
);
1502 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1503 struct bt_list_head
*field_class_declarators
)
1507 struct ctf_node
*iter
;
1508 struct ctf_field_class
*class_decl
= NULL
;
1510 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1511 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1512 &qidentifier
, iter
, &class_decl
, NULL
);
1514 _BT_COMP_LOGE_NODE(iter
,
1515 "Cannot visit field class declarator: ret=%d", ret
);
1520 /* Do not allow field class def and alias of untagged variants */
1521 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1522 struct ctf_field_class_variant
*var_fc
=
1523 (void *) class_decl
;
1525 if (var_fc
->tag_path
.path
->len
== 0) {
1526 _BT_COMP_LOGE_NODE(iter
,
1527 "Type definition of untagged variant field class is not allowed.");
1533 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1534 g_quark_to_string(qidentifier
), class_decl
);
1536 _BT_COMP_LOGE_NODE(iter
,
1537 "Cannot register field class alias: name=\"%s\"",
1538 g_quark_to_string(qidentifier
));
1544 ctf_field_class_destroy(class_decl
);
1550 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1551 struct ctf_node
*alias
)
1555 struct ctf_node
*node
;
1556 GQuark qdummy_field_name
;
1557 struct ctf_field_class
*class_decl
= NULL
;
1559 /* Create target field class */
1560 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1563 node
= _BT_LIST_FIRST_ENTRY(
1564 &target
->u
.field_class_alias_target
.field_class_declarators
,
1565 struct ctf_node
, siblings
);
1568 ret
= visit_field_class_declarator(ctx
,
1569 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1570 &qdummy_field_name
, node
, &class_decl
, NULL
);
1572 BT_ASSERT(!class_decl
);
1573 _BT_COMP_LOGE_NODE(node
,
1574 "Cannot visit field class declarator: ret=%d", ret
);
1578 /* Do not allow field class def and alias of untagged variants */
1579 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1580 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1582 if (var_fc
->tag_path
.path
->len
== 0) {
1583 _BT_COMP_LOGE_NODE(target
,
1584 "Type definition of untagged variant field class is not allowed.");
1591 * The semantic validator does not check whether the target is
1592 * abstract or not (if it has an identifier). Check it here.
1594 if (qdummy_field_name
!= 0) {
1595 _BT_COMP_LOGE_NODE(target
,
1596 "Expecting empty identifier: id=\"%s\"",
1597 g_quark_to_string(qdummy_field_name
));
1602 /* Create alias identifier */
1603 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1604 struct ctf_node
, siblings
);
1605 qalias
= create_class_alias_identifier(ctx
,
1606 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1607 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1608 g_quark_to_string(qalias
), class_decl
);
1610 _BT_COMP_LOGE_NODE(node
,
1611 "Cannot register class alias: name=\"%s\"",
1612 g_quark_to_string(qalias
));
1617 ctf_field_class_destroy(class_decl
);
1623 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1624 struct ctf_field_class_struct
*struct_decl
)
1628 switch (entry_node
->type
) {
1630 ret
= visit_field_class_def(ctx
,
1631 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1632 &entry_node
->u
.field_class_def
.field_class_declarators
);
1634 _BT_COMP_LOGE_NODE(entry_node
,
1635 "Cannot add field class found in structure field class: ret=%d",
1640 case NODE_TYPEALIAS
:
1641 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1642 entry_node
->u
.field_class_alias
.alias
);
1644 _BT_COMP_LOGE_NODE(entry_node
,
1645 "Cannot add field class alias found in structure field class: ret=%d",
1650 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1652 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1653 entry_node
->u
.struct_or_variant_declaration
.
1654 field_class_specifier_list
,
1655 &entry_node
->u
.struct_or_variant_declaration
.
1656 field_class_declarators
);
1662 _BT_COMP_LOGE_NODE(entry_node
,
1663 "Unexpected node type: node-type=%d", entry_node
->type
);
1673 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1674 struct ctf_field_class_variant
*variant_decl
)
1678 switch (entry_node
->type
) {
1680 ret
= visit_field_class_def(ctx
,
1681 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1682 &entry_node
->u
.field_class_def
.field_class_declarators
);
1684 _BT_COMP_LOGE_NODE(entry_node
,
1685 "Cannot add field class found in variant field class: ret=%d",
1690 case NODE_TYPEALIAS
:
1691 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1692 entry_node
->u
.field_class_alias
.alias
);
1694 _BT_COMP_LOGE_NODE(entry_node
,
1695 "Cannot add field class alias found in variant field class: ret=%d",
1700 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1702 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1703 entry_node
->u
.struct_or_variant_declaration
.
1704 field_class_specifier_list
,
1705 &entry_node
->u
.struct_or_variant_declaration
.
1706 field_class_declarators
);
1712 _BT_COMP_LOGE_NODE(entry_node
,
1713 "Unexpected node type: node-type=%d",
1724 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1725 struct bt_list_head
*decl_list
, int has_body
,
1726 struct bt_list_head
*min_align
,
1727 struct ctf_field_class_struct
**struct_decl
)
1731 BT_ASSERT(struct_decl
);
1732 *struct_decl
= NULL
;
1734 /* For named struct (without body), lookup in declaration scope */
1737 BT_COMP_LOGE_STR("Bodyless structure field class: missing name.");
1742 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
, ctx
->current_scope
,
1744 if (!*struct_decl
) {
1745 BT_COMP_LOGE("Cannot find structure field class: name=\"struct %s\"",
1751 struct ctf_node
*entry_node
;
1752 uint64_t min_align_value
= 0;
1755 if (ctx_decl_scope_lookup_struct(ctx
,
1756 ctx
->current_scope
, name
, 1, false)) {
1757 BT_COMP_LOGE("Structure field class already declared in local scope: "
1758 "name=\"struct %s\"", name
);
1764 if (!bt_list_empty(min_align
)) {
1765 ret
= get_unary_unsigned(ctx
, min_align
,
1768 BT_COMP_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1774 *struct_decl
= ctf_field_class_struct_create();
1775 BT_ASSERT(*struct_decl
);
1777 if (min_align_value
!= 0) {
1778 (*struct_decl
)->base
.alignment
= min_align_value
;
1781 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1783 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1784 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1787 _BT_COMP_LOGE_NODE(entry_node
,
1788 "Cannot visit structure field class entry: "
1798 ret
= ctx_decl_scope_register_struct(ctx
,
1799 ctx
->current_scope
, name
, *struct_decl
);
1801 BT_COMP_LOGE("Cannot register structure field class in declaration scope: "
1802 "name=\"struct %s\", ret=%d", name
, ret
);
1811 ctf_field_class_destroy((void *) *struct_decl
);
1812 *struct_decl
= NULL
;
1817 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1818 const char *tag
, struct bt_list_head
*decl_list
,
1819 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1822 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1824 BT_ASSERT(variant_decl
);
1825 *variant_decl
= NULL
;
1827 /* For named variant (without body), lookup in declaration scope */
1830 BT_COMP_LOGE_STR("Bodyless variant field class: missing name.");
1835 untagged_variant_decl
=
1836 ctx_decl_scope_lookup_variant(ctx
, ctx
->current_scope
,
1838 if (!untagged_variant_decl
) {
1839 BT_COMP_LOGE("Cannot find variant field class: name=\"variant %s\"",
1845 struct ctf_node
*entry_node
;
1848 if (ctx_decl_scope_lookup_variant(ctx
,
1849 ctx
->current_scope
, name
, 1, false)) {
1850 BT_COMP_LOGE("Variant field class already declared in local scope: "
1851 "name=\"variant %s\"", name
);
1857 untagged_variant_decl
= ctf_field_class_variant_create();
1858 BT_ASSERT(untagged_variant_decl
);
1859 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1861 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1862 ret
= visit_variant_decl_entry(ctx
, entry_node
,
1863 untagged_variant_decl
);
1865 _BT_COMP_LOGE_NODE(entry_node
,
1866 "Cannot visit variant field class entry: "
1876 ret
= ctx_decl_scope_register_variant(ctx
,
1877 ctx
->current_scope
, name
,
1878 untagged_variant_decl
);
1880 BT_COMP_LOGE("Cannot register variant field class in declaration scope: "
1881 "name=\"variant %s\", ret=%d", name
, ret
);
1888 * If tagged, create tagged variant and return; otherwise
1889 * return untagged variant.
1892 *variant_decl
= untagged_variant_decl
;
1893 untagged_variant_decl
= NULL
;
1896 * At this point, we have a fresh untagged variant; nobody
1897 * else owns it. Set its tag now.
1899 g_string_assign(untagged_variant_decl
->tag_ref
, tag
);
1900 *variant_decl
= untagged_variant_decl
;
1901 untagged_variant_decl
= NULL
;
1904 BT_ASSERT(!untagged_variant_decl
);
1905 BT_ASSERT(*variant_decl
);
1909 ctf_field_class_destroy((void *) untagged_variant_decl
);
1910 untagged_variant_decl
= NULL
;
1911 ctf_field_class_destroy((void *) *variant_decl
);
1912 *variant_decl
= NULL
;
1925 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
1926 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
1930 struct ctf_node
*iter
;
1931 struct uori start
= {
1939 const char *label
= enumerator
->u
.enumerator
.id
;
1940 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
1942 bt_list_for_each_entry(iter
, values
, siblings
) {
1943 struct uori
*target
;
1945 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
1946 _BT_COMP_LOGE_NODE(iter
,
1947 "Wrong expression for enumeration field class label: "
1948 "node-type=%d, label=\"%s\"", iter
->type
,
1960 switch (iter
->u
.unary_expression
.type
) {
1961 case UNARY_SIGNED_CONSTANT
:
1962 target
->is_signed
= true;
1964 iter
->u
.unary_expression
.u
.signed_constant
;
1966 case UNARY_UNSIGNED_CONSTANT
:
1967 target
->is_signed
= false;
1969 iter
->u
.unary_expression
.u
.unsigned_constant
;
1972 _BT_COMP_LOGE_NODE(iter
,
1973 "Invalid enumeration field class entry: "
1974 "expecting constant signed or unsigned integer: "
1975 "node-type=%d, label=\"%s\"",
1976 iter
->u
.unary_expression
.type
, label
);
1982 _BT_COMP_LOGE_NODE(iter
,
1983 "Invalid enumeration field class entry: label=\"%s\"",
2000 if (end
.is_signed
) {
2001 last
->value
.i
= end
.value
.i
+ 1;
2003 last
->value
.u
= end
.value
.u
+ 1;
2006 ctf_field_class_enum_map_range(enum_decl
, label
,
2007 start
.value
.u
, end
.value
.u
);
2015 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2016 struct ctf_node
*container_cls
,
2017 struct bt_list_head
*enumerator_list
,
2018 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2022 struct ctf_field_class_int
*integer_decl
= NULL
;
2024 BT_ASSERT(enum_decl
);
2027 /* For named enum (without body), lookup in declaration scope */
2030 BT_COMP_LOGE_STR("Bodyless enumeration field class: missing name.");
2035 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2038 BT_COMP_LOGE("Cannot find enumeration field class: "
2039 "name=\"enum %s\"", name
);
2044 struct ctf_node
*iter
;
2045 struct uori last_value
= {
2051 if (ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2053 BT_COMP_LOGE("Enumeration field class already declared in local scope: "
2054 "name=\"enum %s\"", name
);
2060 if (!container_cls
) {
2061 integer_decl
= (void *) ctx_decl_scope_lookup_alias(ctx
,
2062 ctx
->current_scope
, "int", -1, true);
2063 if (!integer_decl
) {
2064 BT_COMP_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2069 ret
= visit_field_class_declarator(ctx
, container_cls
,
2070 &qdummy_id
, NULL
, (void *) &integer_decl
,
2073 BT_ASSERT(!integer_decl
);
2079 BT_ASSERT(integer_decl
);
2081 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2082 BT_COMP_LOGE("Container field class for enumeration field class is not an integer field class: "
2083 "fc-type=%d", integer_decl
->base
.base
.type
);
2088 *enum_decl
= ctf_field_class_enum_create();
2089 BT_ASSERT(*enum_decl
);
2090 (*enum_decl
)->base
.base
.base
.alignment
=
2091 integer_decl
->base
.base
.alignment
;
2092 ctf_field_class_int_copy_content((void *) *enum_decl
,
2093 (void *) integer_decl
);
2094 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2096 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2097 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2100 _BT_COMP_LOGE_NODE(iter
,
2101 "Cannot visit enumeration field class entry: "
2108 ret
= ctx_decl_scope_register_enum(ctx
,
2109 ctx
->current_scope
, name
, *enum_decl
);
2111 BT_COMP_LOGE("Cannot register enumeration field class in declaration scope: "
2121 ctf_field_class_destroy((void *) *enum_decl
);
2125 ctf_field_class_destroy((void *) integer_decl
);
2126 integer_decl
= NULL
;
2131 int visit_field_class_specifier(struct ctx
*ctx
,
2132 struct ctf_node
*cls_specifier_list
,
2133 struct ctf_field_class
**decl
)
2136 GString
*str
= NULL
;
2139 str
= g_string_new("");
2140 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2142 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2143 "Cannot get field class specifier list's name: ret=%d", ret
);
2147 *decl
= ctx_decl_scope_lookup_alias(ctx
, ctx
->current_scope
, str
->str
,
2150 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2151 "Cannot find field class alias: name=\"%s\"", str
->str
);
2159 ctf_field_class_destroy(*decl
);
2164 g_string_free(str
, TRUE
);
2171 int visit_integer_decl(struct ctx
*ctx
,
2172 struct bt_list_head
*expressions
,
2173 struct ctf_field_class_int
**integer_decl
)
2178 struct ctf_node
*expression
;
2179 uint64_t alignment
= 0, size
= 0;
2180 struct ctf_clock_class
*mapped_clock_class
= NULL
;
2181 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2182 bt_field_class_integer_preferred_display_base base
=
2183 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2184 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2186 *integer_decl
= NULL
;
2188 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2189 struct ctf_node
*left
, *right
;
2191 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2192 struct ctf_node
, siblings
);
2193 right
= _BT_LIST_FIRST_ENTRY(
2194 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2197 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2198 _BT_COMP_LOGE_NODE(left
,
2199 "Unexpected unary expression type: type=%d",
2200 left
->u
.unary_expression
.type
);
2205 if (strcmp(left
->u
.unary_expression
.u
.string
, "signed") == 0) {
2206 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2207 _BT_COMP_LOGE_DUP_ATTR(left
, "signed",
2208 "integer field class");
2213 signedness
= get_boolean(ctx
, right
);
2214 if (signedness
< 0) {
2215 _BT_COMP_LOGE_NODE(right
,
2216 "Invalid boolean value for integer field class's `signed` attribute: "
2222 _SET(&set
, _INTEGER_SIGNED_SET
);
2223 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2224 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2225 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2226 "integer field class");
2231 byte_order
= get_real_byte_order(ctx
, right
);
2232 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2233 _BT_COMP_LOGE_NODE(right
,
2234 "Invalid `byte_order` attribute in integer field class: "
2240 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2241 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "size") == 0) {
2242 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2243 _BT_COMP_LOGE_DUP_ATTR(left
, "size",
2244 "integer field class");
2249 if (right
->u
.unary_expression
.type
!=
2250 UNARY_UNSIGNED_CONSTANT
) {
2251 _BT_COMP_LOGE_NODE(right
,
2252 "Invalid `size` attribute in integer field class: "
2253 "expecting unsigned constant integer: "
2255 right
->u
.unary_expression
.type
);
2260 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2262 _BT_COMP_LOGE_NODE(right
,
2263 "Invalid `size` attribute in integer field class: "
2264 "expecting positive constant integer: "
2265 "size=%" PRIu64
, size
);
2268 } else if (size
> 64) {
2269 _BT_COMP_LOGE_NODE(right
,
2270 "Invalid `size` attribute in integer field class: "
2271 "integer fields over 64 bits are not supported as of this version: "
2272 "size=%" PRIu64
, size
);
2277 _SET(&set
, _INTEGER_SIZE_SET
);
2278 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2279 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2280 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2281 "integer field class");
2286 if (right
->u
.unary_expression
.type
!=
2287 UNARY_UNSIGNED_CONSTANT
) {
2288 _BT_COMP_LOGE_NODE(right
,
2289 "Invalid `align` attribute in integer field class: "
2290 "expecting unsigned constant integer: "
2292 right
->u
.unary_expression
.type
);
2298 right
->u
.unary_expression
.u
.unsigned_constant
;
2299 if (!is_align_valid(alignment
)) {
2300 _BT_COMP_LOGE_NODE(right
,
2301 "Invalid `align` attribute in integer field class: "
2302 "expecting power of two: "
2303 "align=%" PRIu64
, alignment
);
2308 _SET(&set
, _INTEGER_ALIGN_SET
);
2309 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "base") == 0) {
2310 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2311 _BT_COMP_LOGE_DUP_ATTR(left
, "base",
2312 "integer field class");
2317 switch (right
->u
.unary_expression
.type
) {
2318 case UNARY_UNSIGNED_CONSTANT
:
2320 uint64_t constant
= right
->u
.unary_expression
.
2321 u
.unsigned_constant
;
2325 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2328 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2331 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2334 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2337 _BT_COMP_LOGE_NODE(right
,
2338 "Invalid `base` attribute in integer field class: "
2340 right
->u
.unary_expression
.u
.unsigned_constant
);
2348 char *s_right
= ctf_ast_concatenate_unary_strings(
2349 &expression
->u
.ctf_expression
.right
);
2351 _BT_COMP_LOGE_NODE(right
,
2352 "Unexpected unary expression for integer field class's `base` attribute.");
2357 if (strcmp(s_right
, "decimal") == 0 ||
2358 strcmp(s_right
, "dec") == 0 ||
2359 strcmp(s_right
, "d") == 0 ||
2360 strcmp(s_right
, "i") == 0 ||
2361 strcmp(s_right
, "u") == 0) {
2362 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2363 } else if (strcmp(s_right
, "hexadecimal") == 0 ||
2364 strcmp(s_right
, "hex") == 0 ||
2365 strcmp(s_right
, "x") == 0 ||
2366 strcmp(s_right
, "X") == 0 ||
2367 strcmp(s_right
, "p") == 0) {
2368 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2369 } else if (strcmp(s_right
, "octal") == 0 ||
2370 strcmp(s_right
, "oct") == 0 ||
2371 strcmp(s_right
, "o") == 0) {
2372 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2373 } else if (strcmp(s_right
, "binary") == 0 ||
2374 strcmp(s_right
, "b") == 0) {
2375 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2377 _BT_COMP_LOGE_NODE(right
,
2378 "Unexpected unary expression for integer field class's `base` attribute: "
2379 "base=\"%s\"", s_right
);
2389 _BT_COMP_LOGE_NODE(right
,
2390 "Invalid `base` attribute in integer field class: "
2391 "expecting unsigned constant integer or unary string.");
2396 _SET(&set
, _INTEGER_BASE_SET
);
2397 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2400 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2401 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2402 "integer field class");
2407 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2408 _BT_COMP_LOGE_NODE(right
,
2409 "Invalid `encoding` attribute in integer field class: "
2410 "expecting unary string.");
2415 s_right
= ctf_ast_concatenate_unary_strings(
2416 &expression
->u
.ctf_expression
.right
);
2418 _BT_COMP_LOGE_NODE(right
,
2419 "Unexpected unary expression for integer field class's `encoding` attribute.");
2424 if (strcmp(s_right
, "UTF8") == 0 ||
2425 strcmp(s_right
, "utf8") == 0 ||
2426 strcmp(s_right
, "utf-8") == 0 ||
2427 strcmp(s_right
, "UTF-8") == 0 ||
2428 strcmp(s_right
, "ASCII") == 0 ||
2429 strcmp(s_right
, "ascii") == 0) {
2430 encoding
= CTF_ENCODING_UTF8
;
2431 } else if (strcmp(s_right
, "none") == 0) {
2432 encoding
= CTF_ENCODING_NONE
;
2434 _BT_COMP_LOGE_NODE(right
,
2435 "Invalid `encoding` attribute in integer field class: "
2436 "unknown encoding: encoding=\"%s\"",
2444 _SET(&set
, _INTEGER_ENCODING_SET
);
2445 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "map") == 0) {
2446 const char *clock_name
;
2448 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2449 _BT_COMP_LOGE_DUP_ATTR(left
, "map",
2450 "integer field class");
2455 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2456 _BT_COMP_LOGE_NODE(right
,
2457 "Invalid `map` attribute in integer field class: "
2458 "expecting unary string.");
2464 get_map_clock_name_value(
2465 &expression
->u
.ctf_expression
.right
);
2467 char *s_right
= ctf_ast_concatenate_unary_strings(
2468 &expression
->u
.ctf_expression
.right
);
2471 _BT_COMP_LOGE_NODE(right
,
2472 "Unexpected unary expression for integer field class's `map` attribute.");
2477 _BT_COMP_LOGE_NODE(right
,
2478 "Invalid `map` attribute in integer field class: "
2479 "cannot find clock class at this point: name=\"%s\"",
2481 _SET(&set
, _INTEGER_MAP_SET
);
2486 mapped_clock_class
=
2487 ctf_trace_class_borrow_clock_class_by_name(
2488 ctx
->ctf_tc
, clock_name
);
2489 if (!mapped_clock_class
) {
2490 _BT_COMP_LOGE_NODE(right
,
2491 "Invalid `map` attribute in integer field class: "
2492 "cannot find clock class at this point: name=\"%s\"",
2498 _SET(&set
, _INTEGER_MAP_SET
);
2500 _BT_COMP_LOGW_NODE(left
,
2501 "Unknown attribute in integer field class: "
2503 left
->u
.unary_expression
.u
.string
);
2507 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2508 BT_COMP_LOGE_STR("Missing `size` attribute in integer field class.");
2513 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2514 if (size
% CHAR_BIT
) {
2515 /* Bit-packed alignment */
2518 /* Byte-packed alignment */
2519 alignment
= CHAR_BIT
;
2523 *integer_decl
= ctf_field_class_int_create();
2524 BT_ASSERT(*integer_decl
);
2525 (*integer_decl
)->base
.base
.alignment
= alignment
;
2526 (*integer_decl
)->base
.byte_order
= byte_order
;
2527 (*integer_decl
)->base
.size
= size
;
2528 (*integer_decl
)->is_signed
= (signedness
> 0);
2529 (*integer_decl
)->disp_base
= base
;
2530 (*integer_decl
)->encoding
= encoding
;
2531 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2535 ctf_field_class_destroy((void *) *integer_decl
);
2536 *integer_decl
= NULL
;
2541 int visit_floating_point_number_decl(struct ctx
*ctx
,
2542 struct bt_list_head
*expressions
,
2543 struct ctf_field_class_float
**float_decl
)
2547 struct ctf_node
*expression
;
2548 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2549 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2553 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2554 struct ctf_node
*left
, *right
;
2556 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2557 struct ctf_node
, siblings
);
2558 right
= _BT_LIST_FIRST_ENTRY(
2559 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2562 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2563 _BT_COMP_LOGE_NODE(left
,
2564 "Unexpected unary expression type: type=%d",
2565 left
->u
.unary_expression
.type
);
2570 if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2571 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2572 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2573 "floating point number field class");
2578 byte_order
= get_real_byte_order(ctx
, right
);
2579 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2580 _BT_COMP_LOGE_NODE(right
,
2581 "Invalid `byte_order` attribute in floating point number field class: "
2587 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2588 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig") == 0) {
2589 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2590 _BT_COMP_LOGE_DUP_ATTR(left
, "exp_dig",
2591 "floating point number field class");
2596 if (right
->u
.unary_expression
.type
!=
2597 UNARY_UNSIGNED_CONSTANT
) {
2598 _BT_COMP_LOGE_NODE(right
,
2599 "Invalid `exp_dig` attribute in floating point number field class: "
2600 "expecting unsigned constant integer: "
2602 right
->u
.unary_expression
.type
);
2607 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2608 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2609 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig") == 0) {
2610 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2611 _BT_COMP_LOGE_DUP_ATTR(left
, "mant_dig",
2612 "floating point number field class");
2617 if (right
->u
.unary_expression
.type
!=
2618 UNARY_UNSIGNED_CONSTANT
) {
2619 _BT_COMP_LOGE_NODE(right
,
2620 "Invalid `mant_dig` attribute in floating point number field class: "
2621 "expecting unsigned constant integer: "
2623 right
->u
.unary_expression
.type
);
2628 mant_dig
= right
->u
.unary_expression
.u
.
2630 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2631 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2632 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2633 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2634 "floating point number field class");
2639 if (right
->u
.unary_expression
.type
!=
2640 UNARY_UNSIGNED_CONSTANT
) {
2641 _BT_COMP_LOGE_NODE(right
,
2642 "Invalid `align` attribute in floating point number field class: "
2643 "expecting unsigned constant integer: "
2645 right
->u
.unary_expression
.type
);
2650 alignment
= right
->u
.unary_expression
.u
.
2653 if (!is_align_valid(alignment
)) {
2654 _BT_COMP_LOGE_NODE(right
,
2655 "Invalid `align` attribute in floating point number field class: "
2656 "expecting power of two: "
2657 "align=%" PRIu64
, alignment
);
2662 _SET(&set
, _FLOAT_ALIGN_SET
);
2664 _BT_COMP_LOGW_NODE(left
,
2665 "Unknown attribute in floating point number field class: "
2667 left
->u
.unary_expression
.u
.string
);
2671 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2672 BT_COMP_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2677 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2678 BT_COMP_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2683 if (mant_dig
!= 24 && mant_dig
!= 53) {
2684 BT_COMP_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2689 if (mant_dig
== 24 && exp_dig
!= 8) {
2690 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2695 if (mant_dig
== 53 && exp_dig
!= 11) {
2696 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2701 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2702 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2703 /* Bit-packed alignment */
2706 /* Byte-packed alignment */
2707 alignment
= CHAR_BIT
;
2711 *float_decl
= ctf_field_class_float_create();
2712 BT_ASSERT(*float_decl
);
2713 (*float_decl
)->base
.base
.alignment
= alignment
;
2714 (*float_decl
)->base
.byte_order
= byte_order
;
2715 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2719 ctf_field_class_destroy((void *) *float_decl
);
2725 int visit_string_decl(struct ctx
*ctx
,
2726 struct bt_list_head
*expressions
,
2727 struct ctf_field_class_string
**string_decl
)
2731 struct ctf_node
*expression
;
2732 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2734 *string_decl
= NULL
;
2736 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2737 struct ctf_node
*left
, *right
;
2739 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2740 struct ctf_node
, siblings
);
2741 right
= _BT_LIST_FIRST_ENTRY(
2742 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2745 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2746 _BT_COMP_LOGE_NODE(left
,
2747 "Unexpected unary expression type: type=%d",
2748 left
->u
.unary_expression
.type
);
2753 if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2756 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2757 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2758 "string field class");
2763 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2764 _BT_COMP_LOGE_NODE(right
,
2765 "Invalid `encoding` attribute in string field class: "
2766 "expecting unary string.");
2771 s_right
= ctf_ast_concatenate_unary_strings(
2772 &expression
->u
.ctf_expression
.right
);
2774 _BT_COMP_LOGE_NODE(right
,
2775 "Unexpected unary expression for string field class's `encoding` attribute.");
2780 if (strcmp(s_right
, "UTF8") == 0 ||
2781 strcmp(s_right
, "utf8") == 0 ||
2782 strcmp(s_right
, "utf-8") == 0 ||
2783 strcmp(s_right
, "UTF-8") == 0 ||
2784 strcmp(s_right
, "ASCII") == 0 ||
2785 strcmp(s_right
, "ascii") == 0) {
2786 encoding
= CTF_ENCODING_UTF8
;
2787 } else if (strcmp(s_right
, "none") == 0) {
2788 encoding
= CTF_ENCODING_NONE
;
2790 _BT_COMP_LOGE_NODE(right
,
2791 "Invalid `encoding` attribute in string field class: "
2792 "unknown encoding: encoding=\"%s\"",
2800 _SET(&set
, _STRING_ENCODING_SET
);
2802 _BT_COMP_LOGW_NODE(left
,
2803 "Unknown attribute in string field class: "
2805 left
->u
.unary_expression
.u
.string
);
2809 *string_decl
= ctf_field_class_string_create();
2810 BT_ASSERT(*string_decl
);
2811 (*string_decl
)->encoding
= encoding
;
2815 ctf_field_class_destroy((void *) *string_decl
);
2816 *string_decl
= NULL
;
2821 int visit_field_class_specifier_list(struct ctx
*ctx
,
2822 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
2825 struct ctf_node
*first
, *node
;
2829 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
2830 _BT_COMP_LOGE_NODE(ts_list
,
2831 "Unexpected node type: node-type=%d", ts_list
->type
);
2836 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
2837 struct ctf_node
, siblings
);
2838 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
2839 _BT_COMP_LOGE_NODE(first
,
2840 "Unexpected node type: node-type=%d", first
->type
);
2845 node
= first
->u
.field_class_specifier
.node
;
2847 switch (first
->u
.field_class_specifier
.type
) {
2848 case TYPESPEC_INTEGER
:
2849 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
2856 case TYPESPEC_FLOATING_POINT
:
2857 ret
= visit_floating_point_number_decl(ctx
,
2858 &node
->u
.floating_point
.expressions
, (void *) decl
);
2864 case TYPESPEC_STRING
:
2865 ret
= visit_string_decl(ctx
,
2866 &node
->u
.string
.expressions
, (void *) decl
);
2872 case TYPESPEC_STRUCT
:
2873 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
2874 &node
->u
._struct
.declaration_list
,
2875 node
->u
._struct
.has_body
,
2876 &node
->u
._struct
.min_align
, (void *) decl
);
2882 case TYPESPEC_VARIANT
:
2883 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
2884 node
->u
.variant
.choice
,
2885 &node
->u
.variant
.declaration_list
,
2886 node
->u
.variant
.has_body
, (void *) decl
);
2893 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
2894 node
->u
._enum
.container_field_class
,
2895 &node
->u
._enum
.enumerator_list
,
2896 node
->u
._enum
.has_body
, (void *) decl
);
2904 case TYPESPEC_SHORT
:
2907 case TYPESPEC_FLOAT
:
2908 case TYPESPEC_DOUBLE
:
2909 case TYPESPEC_SIGNED
:
2910 case TYPESPEC_UNSIGNED
:
2912 case TYPESPEC_COMPLEX
:
2913 case TYPESPEC_IMAGINARY
:
2914 case TYPESPEC_CONST
:
2915 case TYPESPEC_ID_TYPE
:
2916 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
2918 _BT_COMP_LOGE_NODE(first
,
2919 "Cannot visit field class specifier: ret=%d",
2926 _BT_COMP_LOGE_NODE(first
,
2927 "Unexpected field class specifier type: node-type=%d",
2928 first
->u
.field_class_specifier
.type
);
2937 ctf_field_class_destroy((void *) *decl
);
2943 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
2944 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
2950 switch (node
->type
) {
2952 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
2953 &node
->u
.field_class_def
.field_class_declarators
);
2955 _BT_COMP_LOGE_NODE(node
,
2956 "Cannot add field class found in event class.");
2960 case NODE_TYPEALIAS
:
2961 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
2962 node
->u
.field_class_alias
.alias
);
2964 _BT_COMP_LOGE_NODE(node
,
2965 "Cannot add field class alias found in event class.");
2969 case NODE_CTF_EXPRESSION
:
2971 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2973 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
2978 if (strcmp(left
, "name") == 0) {
2979 /* This is already known at this stage */
2980 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
2981 _BT_COMP_LOGE_DUP_ATTR(node
, "name", "event class");
2986 _SET(set
, _EVENT_NAME_SET
);
2987 } else if (strcmp(left
, "id") == 0) {
2990 if (_IS_SET(set
, _EVENT_ID_SET
)) {
2991 _BT_COMP_LOGE_DUP_ATTR(node
, "id", "event class");
2996 ret
= get_unary_unsigned(ctx
,
2997 &node
->u
.ctf_expression
.right
,
2999 /* Only read "id" if get_unary_unsigned() succeeded. */
3000 if (ret
|| (!ret
&& id
< 0)) {
3001 _BT_COMP_LOGE_NODE(node
,
3002 "Unexpected unary expression for event class's `id` attribute.");
3007 event_class
->id
= id
;
3008 _SET(set
, _EVENT_ID_SET
);
3009 } else if (strcmp(left
, "stream_id") == 0) {
3010 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3011 _BT_COMP_LOGE_DUP_ATTR(node
, "stream_id",
3017 ret
= get_unary_unsigned(ctx
,
3018 &node
->u
.ctf_expression
.right
, stream_id
);
3021 * Only read "stream_id" if get_unary_unsigned()
3025 _BT_COMP_LOGE_NODE(node
,
3026 "Unexpected unary expression for event class's `stream_id` attribute.");
3031 _SET(set
, _EVENT_STREAM_ID_SET
);
3032 } else if (strcmp(left
, "context") == 0) {
3033 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3034 _BT_COMP_LOGE_NODE(node
,
3035 "Duplicate `context` entry in event class.");
3040 ret
= visit_field_class_specifier_list(ctx
,
3041 _BT_LIST_FIRST_ENTRY(
3042 &node
->u
.ctf_expression
.right
,
3043 struct ctf_node
, siblings
),
3044 &event_class
->spec_context_fc
);
3046 _BT_COMP_LOGE_NODE(node
,
3047 "Cannot create event class's context field class.");
3051 BT_ASSERT(event_class
->spec_context_fc
);
3052 _SET(set
, _EVENT_CONTEXT_SET
);
3053 } else if (strcmp(left
, "fields") == 0) {
3054 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3055 _BT_COMP_LOGE_NODE(node
,
3056 "Duplicate `fields` entry in event class.");
3061 ret
= visit_field_class_specifier_list(ctx
,
3062 _BT_LIST_FIRST_ENTRY(
3063 &node
->u
.ctf_expression
.right
,
3064 struct ctf_node
, siblings
),
3065 &event_class
->payload_fc
);
3067 _BT_COMP_LOGE_NODE(node
,
3068 "Cannot create event class's payload field class.");
3072 BT_ASSERT(event_class
->payload_fc
);
3073 _SET(set
, _EVENT_FIELDS_SET
);
3074 } else if (strcmp(left
, "loglevel") == 0) {
3075 uint64_t loglevel_value
;
3076 bool is_log_level_known
= true;
3077 bt_event_class_log_level log_level
= -1;
3079 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3080 _BT_COMP_LOGE_DUP_ATTR(node
, "loglevel",
3086 ret
= get_unary_unsigned(ctx
,
3087 &node
->u
.ctf_expression
.right
, &loglevel_value
);
3089 _BT_COMP_LOGE_NODE(node
,
3090 "Unexpected unary expression for event class's `loglevel` attribute.");
3095 switch (loglevel_value
) {
3097 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3100 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3103 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3106 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3109 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3112 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3115 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3118 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3121 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3124 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3127 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3130 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3133 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3136 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3139 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3142 is_log_level_known
= false;
3143 _BT_COMP_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3144 "log-level=%" PRIu64
, loglevel_value
);
3147 if (is_log_level_known
) {
3148 ctf_event_class_set_log_level(event_class
, log_level
);
3151 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3152 } else if (strcmp(left
, "model.emf.uri") == 0) {
3155 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3156 _BT_COMP_LOGE_DUP_ATTR(node
, "model.emf.uri",
3162 right
= ctf_ast_concatenate_unary_strings(
3163 &node
->u
.ctf_expression
.right
);
3165 _BT_COMP_LOGE_NODE(node
,
3166 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3171 if (strlen(right
) == 0) {
3172 _BT_COMP_LOGW_NODE(node
,
3173 "Not setting event class's EMF URI because it's empty.");
3175 g_string_assign(event_class
->emf_uri
,
3180 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3182 _BT_COMP_LOGW_NODE(node
,
3183 "Unknown attribute in event class: "
3184 "attr-name=\"%s\"", left
);
3206 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3210 struct ctf_node
*iter
;
3211 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3213 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3214 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3218 left
= ctf_ast_concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3220 _BT_COMP_LOGE_NODE(iter
,
3221 "Cannot concatenate unary strings.");
3225 if (strcmp(left
, "name") == 0) {
3226 name
= ctf_ast_concatenate_unary_strings(
3227 &iter
->u
.ctf_expression
.right
);
3229 _BT_COMP_LOGE_NODE(iter
,
3230 "Unexpected unary expression for event class's `name` attribute.");
3251 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3255 struct ctf_node
*iter
;
3256 uint64_t stream_id
= 0;
3257 char *event_name
= NULL
;
3258 struct ctf_event_class
*event_class
= NULL
;
3259 struct ctf_stream_class
*stream_class
= NULL
;
3260 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3261 bool pop_scope
= false;
3263 if (node
->visited
) {
3267 node
->visited
= TRUE
;
3268 event_name
= get_event_decl_name(ctx
, node
);
3270 _BT_COMP_LOGE_NODE(node
,
3271 "Missing `name` attribute in event class.");
3276 event_class
= ctf_event_class_create();
3277 BT_ASSERT(event_class
);
3278 g_string_assign(event_class
->name
, event_name
);
3279 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3282 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3283 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3286 _BT_COMP_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3292 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3294 * Allow missing stream_id if there is only a single
3297 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3299 /* Create implicit stream class if there's none */
3301 stream_class
= ctf_stream_class_create();
3302 BT_ASSERT(stream_class
);
3303 stream_class
->id
= stream_id
;
3304 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3308 /* Single stream class: get its ID */
3309 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3310 stream_id
= stream_class
->id
;
3313 _BT_COMP_LOGE_NODE(node
,
3314 "Missing `stream_id` attribute in event class.");
3320 /* We have the stream ID now; get the stream class if found */
3321 if (!stream_class
) {
3322 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3323 ctx
->ctf_tc
, stream_id
);
3324 if (!stream_class
) {
3325 _BT_COMP_LOGE_NODE(node
,
3326 "Cannot find stream class at this point: "
3327 "id=%" PRId64
, stream_id
);
3333 BT_ASSERT(stream_class
);
3335 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3336 /* Allow only one event without ID per stream */
3337 if (stream_class
->event_classes
->len
!= 0) {
3338 _BT_COMP_LOGE_NODE(node
,
3339 "Missing `id` attribute in event class.");
3345 event_class
->id
= 0;
3348 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3350 _BT_COMP_LOGE_NODE(node
,
3351 "Duplicate event class (same ID) in the same stream class: "
3352 "id=%" PRId64
, event_class
->id
);
3357 ctf_stream_class_append_event_class(stream_class
, event_class
);
3362 ctf_event_class_destroy(event_class
);
3380 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3381 struct ctf_field_class
*fc
)
3383 struct ctf_clock_class
*clock_class_to_map_to
= NULL
;
3384 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3386 uint64_t clock_class_count
;
3392 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3393 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3397 if (int_fc
->mapped_clock_class
) {
3398 /* Already mapped */
3402 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3404 switch (clock_class_count
) {
3407 * No clock class exists in the trace at this point. Create an
3408 * implicit one at 1 GHz, named `default`, and use this clock
3411 clock_class_to_map_to
= ctf_clock_class_create();
3412 BT_ASSERT(clock_class_to_map_to
);
3413 clock_class_to_map_to
->frequency
= UINT64_C(1000000000);
3414 g_string_assign(clock_class_to_map_to
->name
, "default");
3415 BT_ASSERT(ret
== 0);
3416 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3417 clock_class_to_map_to
);
3421 * Only one clock class exists in the trace at this point: use
3424 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3428 * Timestamp field not mapped to a clock class and there's more
3429 * than one clock class in the trace: this is an error.
3431 BT_COMP_LOGE_STR("Timestamp field found with no mapped clock class, "
3432 "but there's more than one clock class in the trace at this point.");
3437 BT_ASSERT(clock_class_to_map_to
);
3438 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3445 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3446 struct ctf_field_class
*root_fc
, const char *field_name
)
3450 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3451 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3457 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3458 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3462 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3463 count
= struct_fc
->members
->len
;
3465 count
= var_fc
->options
->len
;
3468 for (i
= 0; i
< count
; i
++) {
3469 struct ctf_named_field_class
*named_fc
= NULL
;
3471 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3472 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3474 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3475 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3481 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3482 ret
= auto_map_field_to_trace_clock_class(ctx
,
3485 BT_COMP_LOGE("Cannot automatically map field to trace's clock class: "
3486 "field-name=\"%s\"", field_name
);
3491 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3494 BT_COMP_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3495 "field-name=\"%s\", root-field-name=\"%s\"",
3496 field_name
, named_fc
->name
->str
);
3506 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3507 struct ctf_stream_class
*stream_class
, int *set
)
3512 switch (node
->type
) {
3514 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3515 &node
->u
.field_class_def
.field_class_declarators
);
3517 _BT_COMP_LOGE_NODE(node
,
3518 "Cannot add field class found in stream class.");
3522 case NODE_TYPEALIAS
:
3523 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3524 node
->u
.field_class_alias
.alias
);
3526 _BT_COMP_LOGE_NODE(node
,
3527 "Cannot add field class alias found in stream class.");
3531 case NODE_CTF_EXPRESSION
:
3533 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3535 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3540 if (strcmp(left
, "id") == 0) {
3543 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3544 _BT_COMP_LOGE_DUP_ATTR(node
, "id",
3545 "stream declaration");
3550 ret
= get_unary_unsigned(ctx
,
3551 &node
->u
.ctf_expression
.right
,
3554 /* Only read "id" if get_unary_unsigned() succeeded. */
3555 if (ret
|| (!ret
&& id
< 0)) {
3556 _BT_COMP_LOGE_NODE(node
,
3557 "Unexpected unary expression for stream class's `id` attribute.");
3562 if (ctf_trace_class_borrow_stream_class_by_id(
3564 _BT_COMP_LOGE_NODE(node
,
3565 "Duplicate stream class (same ID): id=%" PRId64
,
3571 stream_class
->id
= id
;
3572 _SET(set
, _STREAM_ID_SET
);
3573 } else if (strcmp(left
, "event.header") == 0) {
3574 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3575 _BT_COMP_LOGE_NODE(node
,
3576 "Duplicate `event.header` entry in stream class.");
3581 ret
= visit_field_class_specifier_list(ctx
,
3582 _BT_LIST_FIRST_ENTRY(
3583 &node
->u
.ctf_expression
.right
,
3584 struct ctf_node
, siblings
),
3585 &stream_class
->event_header_fc
);
3587 _BT_COMP_LOGE_NODE(node
,
3588 "Cannot create stream class's event header field class.");
3592 BT_ASSERT(stream_class
->event_header_fc
);
3593 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3594 stream_class
->event_header_fc
, "timestamp");
3596 _BT_COMP_LOGE_NODE(node
,
3597 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3601 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3602 } else if (strcmp(left
, "event.context") == 0) {
3603 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3604 _BT_COMP_LOGE_NODE(node
,
3605 "Duplicate `event.context` entry in stream class.");
3610 ret
= visit_field_class_specifier_list(ctx
,
3611 _BT_LIST_FIRST_ENTRY(
3612 &node
->u
.ctf_expression
.right
,
3613 struct ctf_node
, siblings
),
3614 &stream_class
->event_common_context_fc
);
3616 _BT_COMP_LOGE_NODE(node
,
3617 "Cannot create stream class's event context field class.");
3621 BT_ASSERT(stream_class
->event_common_context_fc
);
3622 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3623 } else if (strcmp(left
, "packet.context") == 0) {
3624 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3625 _BT_COMP_LOGE_NODE(node
,
3626 "Duplicate `packet.context` entry in stream class.");
3631 ret
= visit_field_class_specifier_list(ctx
,
3632 _BT_LIST_FIRST_ENTRY(
3633 &node
->u
.ctf_expression
.right
,
3634 struct ctf_node
, siblings
),
3635 &stream_class
->packet_context_fc
);
3637 _BT_COMP_LOGE_NODE(node
,
3638 "Cannot create stream class's packet context field class.");
3642 BT_ASSERT(stream_class
->packet_context_fc
);
3643 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3644 stream_class
->packet_context_fc
,
3647 _BT_COMP_LOGE_NODE(node
,
3648 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3652 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3653 stream_class
->packet_context_fc
,
3656 _BT_COMP_LOGE_NODE(node
,
3657 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3661 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3663 _BT_COMP_LOGW_NODE(node
,
3664 "Unknown attribute in stream class: "
3665 "attr-name=\"%s\"", left
);
3686 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3690 struct ctf_node
*iter
;
3691 struct ctf_stream_class
*stream_class
= NULL
;
3692 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3694 if (node
->visited
) {
3698 node
->visited
= TRUE
;
3699 stream_class
= ctf_stream_class_create();
3700 BT_ASSERT(stream_class
);
3701 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3703 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3704 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3706 _BT_COMP_LOGE_NODE(iter
,
3707 "Cannot visit stream class's entry: "
3716 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3717 /* Check that packet header has `stream_id` field */
3718 struct ctf_named_field_class
*named_fc
= NULL
;
3720 if (!ctx
->ctf_tc
->packet_header_fc
) {
3721 _BT_COMP_LOGE_NODE(node
,
3722 "Stream class has a `id` attribute, "
3723 "but trace has no packet header field class.");
3727 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3728 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3730 _BT_COMP_LOGE_NODE(node
,
3731 "Stream class has a `id` attribute, "
3732 "but trace's packet header field class has no `stream_id` field.");
3736 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3737 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3738 _BT_COMP_LOGE_NODE(node
,
3739 "Stream class has a `id` attribute, "
3740 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3744 /* Allow only _one_ ID-less stream */
3745 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3746 _BT_COMP_LOGE_NODE(node
,
3747 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3752 /* Automatic ID: 0 */
3753 stream_class
->id
= 0;
3757 * Make sure that this stream class's ID is currently unique in
3760 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3761 stream_class
->id
)) {
3762 _BT_COMP_LOGE_NODE(node
,
3763 "Duplicate stream class (same ID): id=%" PRId64
,
3769 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3770 stream_class
= NULL
;
3774 ctf_stream_class_destroy(stream_class
);
3775 stream_class
= NULL
;
3782 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3788 switch (node
->type
) {
3790 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3791 &node
->u
.field_class_def
.field_class_declarators
);
3793 _BT_COMP_LOGE_NODE(node
,
3794 "Cannot add field class found in trace (`trace` block).");
3798 case NODE_TYPEALIAS
:
3799 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3800 node
->u
.field_class_alias
.alias
);
3802 _BT_COMP_LOGE_NODE(node
,
3803 "Cannot add field class alias found in trace (`trace` block).");
3807 case NODE_CTF_EXPRESSION
:
3809 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3811 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3816 if (strcmp(left
, "major") == 0) {
3817 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
3818 _BT_COMP_LOGE_DUP_ATTR(node
, "major", "trace");
3823 ret
= get_unary_unsigned(ctx
,
3824 &node
->u
.ctf_expression
.right
, &val
);
3826 _BT_COMP_LOGE_NODE(node
,
3827 "Unexpected unary expression for trace's `major` attribute.");
3833 _BT_COMP_LOGE_NODE(node
,
3834 "Invalid trace's `minor` attribute: expecting 1.");
3838 ctx
->ctf_tc
->major
= val
;
3839 _SET(set
, _TRACE_MAJOR_SET
);
3840 } else if (strcmp(left
, "minor") == 0) {
3841 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
3842 _BT_COMP_LOGE_DUP_ATTR(node
, "minor", "trace");
3847 ret
= get_unary_unsigned(ctx
,
3848 &node
->u
.ctf_expression
.right
, &val
);
3850 _BT_COMP_LOGE_NODE(node
,
3851 "Unexpected unary expression for trace's `minor` attribute.");
3857 _BT_COMP_LOGE_NODE(node
,
3858 "Invalid trace's `minor` attribute: expecting 8.");
3862 ctx
->ctf_tc
->minor
= val
;
3863 _SET(set
, _TRACE_MINOR_SET
);
3864 } else if (strcmp(left
, "uuid") == 0) {
3865 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
3866 _BT_COMP_LOGE_DUP_ATTR(node
, "uuid", "trace");
3871 ret
= get_unary_uuid(ctx
,
3872 &node
->u
.ctf_expression
.right
,
3875 _BT_COMP_LOGE_NODE(node
,
3876 "Invalid trace's `uuid` attribute.");
3880 ctx
->ctf_tc
->is_uuid_set
= true;
3881 _SET(set
, _TRACE_UUID_SET
);
3882 } else if (strcmp(left
, "byte_order") == 0) {
3883 /* Default byte order is already known at this stage */
3884 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
3885 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
3891 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= CTF_BYTE_ORDER_UNKNOWN
);
3892 _SET(set
, _TRACE_BYTE_ORDER_SET
);
3893 } else if (strcmp(left
, "packet.header") == 0) {
3894 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
3895 _BT_COMP_LOGE_NODE(node
,
3896 "Duplicate `packet.header` entry in trace.");
3901 ret
= visit_field_class_specifier_list(ctx
,
3902 _BT_LIST_FIRST_ENTRY(
3903 &node
->u
.ctf_expression
.right
,
3904 struct ctf_node
, siblings
),
3905 &ctx
->ctf_tc
->packet_header_fc
);
3907 _BT_COMP_LOGE_NODE(node
,
3908 "Cannot create trace's packet header field class.");
3912 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
3913 _SET(set
, _TRACE_PACKET_HEADER_SET
);
3915 _BT_COMP_LOGW_NODE(node
,
3916 "Unknown attribute in stream class: "
3917 "attr-name=\"%s\"", left
);
3925 _BT_COMP_LOGE_NODE(node
, "Unknown expression in trace.");
3938 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3942 struct ctf_node
*iter
;
3943 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
3945 if (node
->visited
) {
3949 node
->visited
= TRUE
;
3951 if (ctx
->is_trace_visited
) {
3952 _BT_COMP_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
3957 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3959 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3960 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
3962 _BT_COMP_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
3971 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
3972 _BT_COMP_LOGE_NODE(node
,
3973 "Missing `major` attribute in trace (`trace` block).");
3978 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
3979 _BT_COMP_LOGE_NODE(node
,
3980 "Missing `minor` attribute in trace (`trace` block).");
3985 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
3986 _BT_COMP_LOGE_NODE(node
,
3987 "Missing `byte_order` attribute in trace (`trace` block).");
3992 ctx
->is_trace_visited
= true;
4002 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4006 struct ctf_node
*entry_node
;
4007 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4009 if (node
->visited
) {
4013 node
->visited
= TRUE
;
4015 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4016 struct bt_list_head
*right_head
=
4017 &entry_node
->u
.ctf_expression
.right
;
4019 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4020 _BT_COMP_LOGE_NODE(entry_node
,
4021 "Wrong expression in environment entry: "
4022 "node-type=%d", entry_node
->type
);
4027 left
= ctf_ast_concatenate_unary_strings(
4028 &entry_node
->u
.ctf_expression
.left
);
4030 _BT_COMP_LOGE_NODE(entry_node
,
4031 "Cannot get environment entry's name.");
4036 if (is_unary_string(right_head
)) {
4037 char *right
= ctf_ast_concatenate_unary_strings(right_head
);
4040 _BT_COMP_LOGE_NODE(entry_node
,
4041 "Unexpected unary expression for environment entry's value: "
4042 "name=\"%s\"", left
);
4047 if (strcmp(left
, "tracer_name") == 0) {
4048 if (strncmp(right
, "lttng", 5) == 0) {
4049 BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
4050 "tracer-name=\"%s\"",
4052 ctx
->is_lttng
= true;
4056 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4057 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4060 } else if (is_unary_unsigned(right_head
) ||
4061 is_unary_signed(right_head
)) {
4064 if (is_unary_unsigned(right_head
)) {
4065 ret
= get_unary_unsigned(ctx
, right_head
,
4068 ret
= get_unary_signed(right_head
, &v
);
4071 _BT_COMP_LOGE_NODE(entry_node
,
4072 "Unexpected unary expression for environment entry's value: "
4073 "name=\"%s\"", left
);
4078 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4079 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4082 _BT_COMP_LOGW_NODE(entry_node
,
4083 "Environment entry has unknown type: "
4084 "name=\"%s\"", left
);
4100 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4105 struct ctf_node
*node
;
4106 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4108 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4109 if (node
->type
== NODE_CTF_EXPRESSION
) {
4110 struct ctf_node
*right_node
;
4112 left
= ctf_ast_concatenate_unary_strings(
4113 &node
->u
.ctf_expression
.left
);
4115 _BT_COMP_LOGE_NODE(node
,
4116 "Cannot concatenate unary strings.");
4121 if (strcmp(left
, "byte_order") == 0) {
4122 enum ctf_byte_order bo
;
4124 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4125 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
4131 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4132 right_node
= _BT_LIST_FIRST_ENTRY(
4133 &node
->u
.ctf_expression
.right
,
4134 struct ctf_node
, siblings
);
4135 bo
= byte_order_from_unary_expr(ctx
,
4137 if (bo
== CTF_BYTE_ORDER_UNKNOWN
) {
4138 _BT_COMP_LOGE_NODE(node
,
4139 "Invalid `byte_order` attribute in trace (`trace` block): "
4140 "expecting `le`, `be`, or `network`.");
4143 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4144 _BT_COMP_LOGE_NODE(node
,
4145 "Invalid `byte_order` attribute in trace (`trace` block): "
4146 "cannot be set to `native` here.");
4151 ctx
->ctf_tc
->default_byte_order
= bo
;
4159 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4160 _BT_COMP_LOGE_NODE(trace_node
,
4161 "Missing `byte_order` attribute in trace (`trace` block).");
4174 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4175 struct ctf_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4176 uint64_t *offset_cycles
)
4181 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4182 _BT_COMP_LOGE_NODE(entry_node
,
4183 "Unexpected node type: node-type=%d",
4189 left
= ctf_ast_concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4191 _BT_COMP_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4196 if (strcmp(left
, "name") == 0) {
4199 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4200 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4205 right
= ctf_ast_concatenate_unary_strings(
4206 &entry_node
->u
.ctf_expression
.right
);
4208 _BT_COMP_LOGE_NODE(entry_node
,
4209 "Unexpected unary expression for clock class's `name` attribute.");
4214 g_string_assign(clock
->name
, right
);
4216 _SET(set
, _CLOCK_NAME_SET
);
4217 } else if (strcmp(left
, "uuid") == 0) {
4220 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4221 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4226 ret
= get_unary_uuid(ctx
, &entry_node
->u
.ctf_expression
.right
,
4229 _BT_COMP_LOGE_NODE(entry_node
,
4230 "Invalid clock class's `uuid` attribute.");
4234 clock
->has_uuid
= true;
4235 bt_uuid_copy(clock
->uuid
, uuid
);
4236 _SET(set
, _CLOCK_UUID_SET
);
4237 } else if (strcmp(left
, "description") == 0) {
4240 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4241 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "description",
4247 right
= ctf_ast_concatenate_unary_strings(
4248 &entry_node
->u
.ctf_expression
.right
);
4250 _BT_COMP_LOGE_NODE(entry_node
,
4251 "Unexpected unary expression for clock class's `description` attribute.");
4256 g_string_assign(clock
->description
, right
);
4258 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4259 } else if (strcmp(left
, "freq") == 0) {
4260 uint64_t freq
= UINT64_C(-1);
4262 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4263 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4268 ret
= get_unary_unsigned(ctx
,
4269 &entry_node
->u
.ctf_expression
.right
, &freq
);
4271 _BT_COMP_LOGE_NODE(entry_node
,
4272 "Unexpected unary expression for clock class's `freq` attribute.");
4277 if (freq
== UINT64_C(-1) || freq
== 0) {
4278 _BT_COMP_LOGE_NODE(entry_node
,
4279 "Invalid clock class frequency: freq=%" PRIu64
,
4285 clock
->frequency
= freq
;
4286 _SET(set
, _CLOCK_FREQ_SET
);
4287 } else if (strcmp(left
, "precision") == 0) {
4290 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4291 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "precision",
4297 ret
= get_unary_unsigned(ctx
,
4298 &entry_node
->u
.ctf_expression
.right
, &precision
);
4300 _BT_COMP_LOGE_NODE(entry_node
,
4301 "Unexpected unary expression for clock class's `precision` attribute.");
4306 clock
->precision
= precision
;
4307 _SET(set
, _CLOCK_PRECISION_SET
);
4308 } else if (strcmp(left
, "offset_s") == 0) {
4309 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4310 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset_s",
4316 ret
= get_unary_signed(
4317 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4319 _BT_COMP_LOGE_NODE(entry_node
,
4320 "Unexpected unary expression for clock class's `offset_s` attribute.");
4325 _SET(set
, _CLOCK_OFFSET_S_SET
);
4326 } else if (strcmp(left
, "offset") == 0) {
4327 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4328 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4333 ret
= get_unary_unsigned(ctx
,
4334 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4336 _BT_COMP_LOGE_NODE(entry_node
,
4337 "Unexpected unary expression for clock class's `offset` attribute.");
4342 _SET(set
, _CLOCK_OFFSET_SET
);
4343 } else if (strcmp(left
, "absolute") == 0) {
4344 struct ctf_node
*right
;
4346 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4347 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "absolute",
4353 right
= _BT_LIST_FIRST_ENTRY(
4354 &entry_node
->u
.ctf_expression
.right
,
4355 struct ctf_node
, siblings
);
4356 ret
= get_boolean(ctx
, right
);
4358 _BT_COMP_LOGE_NODE(entry_node
,
4359 "Unexpected unary expression for clock class's `absolute` attribute.");
4364 clock
->is_absolute
= ret
;
4365 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4367 _BT_COMP_LOGW_NODE(entry_node
,
4368 "Unknown attribute in clock class: attr-name=\"%s\"",
4382 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4387 if (frequency
== UINT64_C(1000000000)) {
4390 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4397 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4398 uint64_t *offset_cycles
, uint64_t freq
)
4400 if (*offset_cycles
>= freq
) {
4401 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4403 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4404 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4409 void apply_clock_class_is_absolute(struct ctx
*ctx
,
4410 struct ctf_clock_class
*clock
)
4412 if (ctx
->decoder_config
.force_clock_class_origin_unix_epoch
) {
4413 clock
->is_absolute
= true;
4420 void apply_clock_class_offset(struct ctx
*ctx
,
4421 struct ctf_clock_class
*clock
)
4424 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4425 uint64_t offset_ns_to_apply
;
4426 int64_t cur_offset_s
;
4427 uint64_t cur_offset_cycles
;
4429 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4430 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4434 /* Transfer nanoseconds to seconds as much as possible */
4435 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4436 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4437 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4438 const int64_t extra_s
= -abs_extra_s
;
4439 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4440 (extra_s
* INT64_C(1000000000));
4442 BT_ASSERT(offset_ns
> 0);
4443 offset_ns_to_apply
= (uint64_t) offset_ns
;
4444 offset_s_to_apply
+= extra_s
;
4446 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4447 INT64_C(1000000000);
4448 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4449 (extra_s
* INT64_C(1000000000));
4451 BT_ASSERT(offset_ns
>= 0);
4452 offset_ns_to_apply
= (uint64_t) offset_ns
;
4453 offset_s_to_apply
+= extra_s
;
4456 freq
= clock
->frequency
;
4457 cur_offset_s
= clock
->offset_seconds
;
4458 cur_offset_cycles
= clock
->offset_cycles
;
4461 cur_offset_s
+= offset_s_to_apply
;
4462 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4465 * Recalibrate offsets because the part in cycles can be greater
4466 * than the frequency at this point.
4468 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4470 /* Set final offsets */
4471 clock
->offset_seconds
= cur_offset_s
;
4472 clock
->offset_cycles
= cur_offset_cycles
;
4479 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4483 struct ctf_clock_class
*clock
;
4484 struct ctf_node
*entry_node
;
4485 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4486 const char *clock_class_name
;
4487 int64_t offset_seconds
= 0;
4488 uint64_t offset_cycles
= 0;
4491 if (clock_node
->visited
) {
4495 clock_node
->visited
= TRUE
;
4497 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4498 clock
= ctf_clock_class_create();
4500 _BT_COMP_LOGE_NODE(clock_node
,
4501 "Cannot create default clock class.");
4506 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4507 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4508 &offset_seconds
, &offset_cycles
);
4510 _BT_COMP_LOGE_NODE(entry_node
,
4511 "Cannot visit clock class's entry: ret=%d",
4517 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4518 _BT_COMP_LOGE_NODE(clock_node
,
4519 "Missing `name` attribute in clock class.");
4524 clock_class_name
= clock
->name
->str
;
4525 BT_ASSERT(clock_class_name
);
4526 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4528 * Old versions of LTTng forgot to set its clock class
4529 * as absolute, even if it is. This is important because
4530 * it's a condition to be able to sort messages
4531 * from different sources.
4533 clock
->is_absolute
= true;
4537 * Adjust offsets so that the part in cycles is less than the
4538 * frequency (move to the part in seconds).
4540 freq
= clock
->frequency
;
4541 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4542 BT_ASSERT(offset_cycles
< clock
->frequency
);
4543 clock
->offset_seconds
= offset_seconds
;
4544 clock
->offset_cycles
= offset_cycles
;
4545 apply_clock_class_offset(ctx
, clock
);
4546 apply_clock_class_is_absolute(ctx
, clock
);
4547 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4552 ctf_clock_class_destroy(clock
);
4559 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4563 if (root_decl_node
->visited
) {
4567 root_decl_node
->visited
= TRUE
;
4569 switch (root_decl_node
->type
) {
4571 ret
= visit_field_class_def(ctx
,
4572 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4573 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4575 _BT_COMP_LOGE_NODE(root_decl_node
,
4576 "Cannot add field class found in root scope.");
4580 case NODE_TYPEALIAS
:
4581 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4582 root_decl_node
->u
.field_class_alias
.alias
);
4584 _BT_COMP_LOGE_NODE(root_decl_node
,
4585 "Cannot add field class alias found in root scope.");
4589 case NODE_TYPE_SPECIFIER_LIST
:
4591 struct ctf_field_class
*decl
= NULL
;
4594 * Just add the field class specifier to the root
4595 * declaration scope. Put local reference.
4597 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4599 _BT_COMP_LOGE_NODE(root_decl_node
,
4600 "Cannot visit root scope's field class: "
4606 ctf_field_class_destroy(decl
);
4611 _BT_COMP_LOGE_NODE(root_decl_node
,
4612 "Unexpected node type: node-type=%d",
4613 root_decl_node
->type
);
4623 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4624 const struct ctf_metadata_decoder_config
*decoder_config
)
4626 struct ctx
*ctx
= NULL
;
4628 /* Create visitor's context */
4629 ctx
= ctx_create(decoder_config
);
4631 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
4632 decoder_config
->self_comp
,
4633 "Cannot create visitor's context.");
4644 return (void *) ctx
;
4648 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4650 ctx_destroy((void *) visitor
);
4654 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4655 struct ctf_visitor_generate_ir
*visitor
)
4657 struct ctx
*ctx
= (void *) visitor
;
4661 if (ctx
->trace_class
) {
4662 bt_trace_class_get_ref(ctx
->trace_class
);
4665 return ctx
->trace_class
;
4669 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4670 struct ctf_visitor_generate_ir
*visitor
)
4672 struct ctx
*ctx
= (void *) visitor
;
4675 BT_ASSERT_DBG(ctx
->ctf_tc
);
4680 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4681 struct ctf_node
*node
)
4684 struct ctx
*ctx
= (void *) visitor
;
4686 BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4688 switch (node
->type
) {
4691 struct ctf_node
*iter
;
4692 bool got_trace_decl
= false;
4695 * The first thing we need is the native byte order of
4696 * the trace block, because early class aliases can have
4697 * a `byte_order` attribute set to `native`. If we don't
4698 * have the native byte order yet, and we don't have any
4699 * trace block yet, then fail with EINCOMPLETE.
4701 if (ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
4702 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4703 if (got_trace_decl
) {
4704 _BT_COMP_LOGE_NODE(node
,
4705 "Duplicate trace (`trace` block).");
4710 ret
= set_trace_byte_order(ctx
, iter
);
4712 _BT_COMP_LOGE_NODE(node
,
4713 "Cannot set trace's native byte order: "
4718 got_trace_decl
= true;
4721 if (!got_trace_decl
) {
4722 BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4728 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4729 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4730 BT_ASSERT(ctx
->current_scope
&&
4731 !ctx
->current_scope
->parent_scope
);
4734 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4735 ret
= visit_env(ctx
, iter
);
4737 _BT_COMP_LOGE_NODE(iter
,
4738 "Cannot visit trace's environment (`env` block) entry: "
4744 BT_ASSERT(ctx
->current_scope
&&
4745 !ctx
->current_scope
->parent_scope
);
4748 * Visit clock blocks.
4750 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4751 ret
= visit_clock_decl(ctx
, iter
);
4753 _BT_COMP_LOGE_NODE(iter
,
4754 "Cannot visit clock class: ret=%d",
4760 BT_ASSERT(ctx
->current_scope
&&
4761 !ctx
->current_scope
->parent_scope
);
4764 * Visit root declarations next, as they can be used by any
4767 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4769 ret
= visit_root_decl(ctx
, iter
);
4771 _BT_COMP_LOGE_NODE(iter
,
4772 "Cannot visit root entry: ret=%d",
4778 BT_ASSERT(ctx
->current_scope
&&
4779 !ctx
->current_scope
->parent_scope
);
4781 /* Callsite blocks are not supported */
4782 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4783 _BT_COMP_LOGW_NODE(iter
,
4784 "\"callsite\" blocks are not supported as of this version.");
4787 BT_ASSERT(ctx
->current_scope
&&
4788 !ctx
->current_scope
->parent_scope
);
4791 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4792 ret
= visit_trace_decl(ctx
, iter
);
4794 _BT_COMP_LOGE_NODE(iter
,
4795 "Cannot visit trace (`trace` block): "
4801 BT_ASSERT(ctx
->current_scope
&&
4802 !ctx
->current_scope
->parent_scope
);
4805 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4806 ret
= visit_stream_decl(ctx
, iter
);
4808 _BT_COMP_LOGE_NODE(iter
,
4809 "Cannot visit stream class: ret=%d",
4815 BT_ASSERT(ctx
->current_scope
&&
4816 !ctx
->current_scope
->parent_scope
);
4819 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4820 ret
= visit_event_decl(ctx
, iter
);
4822 _BT_COMP_LOGE_NODE(iter
,
4823 "Cannot visit event class: ret=%d",
4829 BT_ASSERT(ctx
->current_scope
&&
4830 !ctx
->current_scope
->parent_scope
);
4834 _BT_COMP_LOGE_NODE(node
,
4835 "Unexpected node type: node-type=%d",
4841 /* Update default clock classes */
4842 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
,
4849 /* Update trace class meanings */
4850 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
4856 /* Update stream class configuration */
4857 ret
= ctf_trace_class_update_stream_class_config(ctx
->ctf_tc
);
4863 /* Update text arrays and sequences */
4864 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
4870 /* Resolve sequence lengths and variant tags */
4871 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
, &ctx
->log_cfg
);
4877 if (ctx
->trace_class
) {
4879 * Update "in IR" for field classes.
4881 * If we have no IR trace class, then we'll have no way
4882 * to create IR fields anyway, so we leave all the
4883 * `in_ir` members false.
4885 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
4892 /* Update saved value indexes */
4893 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
4899 /* Validate what we have so far */
4900 ret
= ctf_trace_class_validate(ctx
->ctf_tc
, &ctx
->log_cfg
);
4907 * If there are fields which are not related to the CTF format
4908 * itself in the packet header and in event header field
4909 * classes, warn about it because they are never translated.
4911 ctf_trace_class_warn_meaningless_header_fields(ctx
->ctf_tc
,
4914 if (ctx
->trace_class
) {
4915 /* Copy new CTF metadata -> new IR metadata */
4916 ret
= ctf_trace_class_translate(ctx
->log_cfg
.self_comp
,
4917 ctx
->trace_class
, ctx
->ctf_tc
);