2 * ctf-visitor-generate-ir.c
4 * Common Trace Format metadata visitor (generates CTF IR objects).
6 * Based on older ctf-visitor-generate-io-struct.c.
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2018 - Philippe Proulx <philippe.proulx@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp)
31 #define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level)
32 #define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
33 #include "logging/comp-logging.h"
41 #include "common/assert.h"
45 #include "common/common.h"
46 #include "common/uuid.h"
47 #include "compat/endian.h"
48 #include <babeltrace2/babeltrace.h>
56 #include "ctf-meta-visitors.h"
58 /* Bit value (left shift) */
59 #define _BV(_val) (1 << (_val))
61 /* Bit is set in a set of bits */
62 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
64 /* Set bit in a set of bits */
65 #define _SET(_set, _mask) (*(_set) |= (_mask))
67 /* Try to push scope, or go to the `error` label */
68 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
70 ret = ctx_push_scope(ctx); \
72 BT_COMP_LOGE_STR("Cannot push scope."); \
77 /* Bits for verifying existing attributes in various declarations */
79 _CLOCK_NAME_SET
= _BV(0),
80 _CLOCK_UUID_SET
= _BV(1),
81 _CLOCK_FREQ_SET
= _BV(2),
82 _CLOCK_PRECISION_SET
= _BV(3),
83 _CLOCK_OFFSET_S_SET
= _BV(4),
84 _CLOCK_OFFSET_SET
= _BV(5),
85 _CLOCK_ABSOLUTE_SET
= _BV(6),
86 _CLOCK_DESCRIPTION_SET
= _BV(7),
90 _INTEGER_ALIGN_SET
= _BV(0),
91 _INTEGER_SIZE_SET
= _BV(1),
92 _INTEGER_BASE_SET
= _BV(2),
93 _INTEGER_ENCODING_SET
= _BV(3),
94 _INTEGER_BYTE_ORDER_SET
= _BV(4),
95 _INTEGER_SIGNED_SET
= _BV(5),
96 _INTEGER_MAP_SET
= _BV(6),
100 _FLOAT_ALIGN_SET
= _BV(0),
101 _FLOAT_MANT_DIG_SET
= _BV(1),
102 _FLOAT_EXP_DIG_SET
= _BV(2),
103 _FLOAT_BYTE_ORDER_SET
= _BV(3),
107 _STRING_ENCODING_SET
= _BV(0),
111 _TRACE_MINOR_SET
= _BV(0),
112 _TRACE_MAJOR_SET
= _BV(1),
113 _TRACE_BYTE_ORDER_SET
= _BV(2),
114 _TRACE_UUID_SET
= _BV(3),
115 _TRACE_PACKET_HEADER_SET
= _BV(4),
119 _STREAM_ID_SET
= _BV(0),
120 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
121 _STREAM_EVENT_HEADER_SET
= _BV(2),
122 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
126 _EVENT_NAME_SET
= _BV(0),
127 _EVENT_ID_SET
= _BV(1),
128 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
129 _EVENT_STREAM_ID_SET
= _BV(3),
130 _EVENT_LOG_LEVEL_SET
= _BV(4),
131 _EVENT_CONTEXT_SET
= _BV(5),
132 _EVENT_FIELDS_SET
= _BV(6),
140 LOG_LEVEL_WARNING
= 4,
141 LOG_LEVEL_NOTICE
= 5,
143 LOG_LEVEL_DEBUG_SYSTEM
= 7,
144 LOG_LEVEL_DEBUG_PROGRAM
= 8,
145 LOG_LEVEL_DEBUG_PROCESS
= 9,
146 LOG_LEVEL_DEBUG_MODULE
= 10,
147 LOG_LEVEL_DEBUG_UNIT
= 11,
148 LOG_LEVEL_DEBUG_FUNCTION
= 12,
149 LOG_LEVEL_DEBUG_LINE
= 13,
150 LOG_LEVEL_DEBUG
= 14,
154 /* Prefixes of class aliases */
155 #define _PREFIX_ALIAS 'a'
156 #define _PREFIX_ENUM 'e'
157 #define _PREFIX_STRUCT 's'
158 #define _PREFIX_VARIANT 'v'
160 /* First entry in a BT list */
161 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
162 bt_list_entry((_ptr)->next, _class, _member)
164 #define _BT_COMP_LOGE_DUP_ATTR(_node, _attr, _entity) \
165 _BT_COMP_LOGE_LINENO((_node)->lineno, \
166 "Duplicate attribute in %s: attr-name=\"%s\"", \
169 #define _BT_COMP_LOGE_NODE(_node, _msg, args...) \
170 _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args)
172 #define _BT_COMP_LOGW_NODE(_node, _msg, args...) \
173 _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args)
175 #define _BT_COMP_LOGT_NODE(_node, _msg, args...) \
176 _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args)
179 * Declaration scope of a visitor context. This represents a TSDL
180 * lexical scope, so that aliases and named structures, variants,
181 * and enumerations may be registered and looked up hierarchically.
183 struct ctx_decl_scope
{
185 * Alias name to field class.
187 * GQuark -> struct ctf_field_class * (owned by this)
189 GHashTable
*decl_map
;
191 /* Parent scope; NULL if this is the root declaration scope */
192 struct ctx_decl_scope
*parent_scope
;
196 * Visitor context (private).
199 struct meta_log_config log_cfg
;
201 /* Trace IR trace class being filled (owned by this) */
202 bt_trace_class
*trace_class
;
204 /* CTF meta trace being filled (owned by this) */
205 struct ctf_trace_class
*ctf_tc
;
207 /* Current declaration scope (top of the stack) (owned by this) */
208 struct ctx_decl_scope
*current_scope
;
210 /* True if trace declaration is visited */
211 bool is_trace_visited
;
213 /* True if this is an LTTng trace */
216 /* Config passed by the user */
217 struct ctf_metadata_decoder_config decoder_config
;
223 struct ctf_visitor_generate_ir
;
226 * Creates a new declaration scope.
228 * @param par_scope Parent scope (NULL if creating a root scope)
229 * @returns New declaration scope, or NULL on error
232 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx
*ctx
,
233 struct ctx_decl_scope
*par_scope
)
235 struct ctx_decl_scope
*scope
;
237 scope
= g_new(struct ctx_decl_scope
, 1);
239 BT_COMP_LOGE_STR("Failed to allocate one declaration scope.");
243 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
244 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
245 scope
->parent_scope
= par_scope
;
252 * Destroys a declaration scope.
254 * This function does not destroy the parent scope.
256 * @param scope Scope to destroy
259 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
265 g_hash_table_destroy(scope
->decl_map
);
273 * Returns the GQuark of a prefixed alias.
275 * @param prefix Prefix character
277 * @returns Associated GQuark, or 0 on error
280 GQuark
get_prefixed_named_quark(struct ctx
*ctx
, char prefix
, const char *name
)
286 /* Prefix character + original string + '\0' */
287 char *prname
= g_new(char, strlen(name
) + 2);
289 BT_COMP_LOGE_STR("Failed to allocate a string.");
293 sprintf(prname
, "%c%s", prefix
, name
);
294 qname
= g_quark_from_string(prname
);
302 * Looks up a prefixed class alias within a declaration scope.
304 * @param scope Declaration scope
305 * @param prefix Prefix character
306 * @param name Alias name
307 * @param levels Number of levels to dig into (-1 means infinite)
308 * @param copy True to return a copy
309 * @returns Declaration (owned by caller if \p copy is true),
310 * or NULL if not found
313 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
314 struct ctx
*ctx
, struct ctx_decl_scope
*scope
, char prefix
,
315 const char *name
, int levels
, bool copy
)
319 struct ctf_field_class
*decl
= NULL
;
320 struct ctx_decl_scope
*cur_scope
= scope
;
324 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
333 while (cur_scope
&& cur_levels
< levels
) {
334 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
335 (gconstpointer
) GUINT_TO_POINTER(qname
));
337 /* Caller's reference */
339 decl
= ctf_field_class_copy(decl
);
346 cur_scope
= cur_scope
->parent_scope
;
355 * Looks up a class alias within a declaration scope.
357 * @param scope Declaration scope
358 * @param name Alias name
359 * @param levels Number of levels to dig into (-1 means infinite)
360 * @param copy True to return a copy
361 * @returns Declaration (owned by caller if \p copy is true),
362 * or NULL if not found
365 struct ctf_field_class
*ctx_decl_scope_lookup_alias(struct ctx
*ctx
,
366 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
369 return ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
374 * Looks up an enumeration within a declaration scope.
376 * @param scope Declaration scope
377 * @param name Enumeration name
378 * @param levels Number of levels to dig into (-1 means infinite)
379 * @param copy True to return a copy
380 * @returns Declaration (owned by caller if \p copy is true),
381 * or NULL if not found
384 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(struct ctx
*ctx
,
385 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
388 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
389 _PREFIX_ENUM
, name
, levels
, copy
);
393 * Looks up a structure within a declaration scope.
395 * @param scope Declaration scope
396 * @param name Structure name
397 * @param levels Number of levels to dig into (-1 means infinite)
398 * @param copy True to return a copy
399 * @returns Declaration (owned by caller if \p copy is true),
400 * or NULL if not found
403 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(struct ctx
*ctx
,
404 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
407 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
408 _PREFIX_STRUCT
, name
, levels
, copy
);
412 * Looks up a variant within a declaration scope.
414 * @param scope Declaration scope
415 * @param name Variant name
416 * @param levels Number of levels to dig into (-1 means infinite)
417 * @param copy True to return a copy
418 * @returns Declaration (owned by caller if \p copy is true),
419 * or NULL if not found
422 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(struct ctx
*ctx
,
423 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
426 return (void *) ctx_decl_scope_lookup_prefix_alias(ctx
, scope
,
427 _PREFIX_VARIANT
, name
, levels
, copy
);
431 * Registers a prefixed class alias within a declaration scope.
433 * @param scope Declaration scope
434 * @param prefix Prefix character
435 * @param name Alias name (non-NULL)
436 * @param decl Field class to register (copied)
437 * @returns 0 if registration went okay, negative value otherwise
440 int ctx_decl_scope_register_prefix_alias(struct ctx
*ctx
,
441 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
442 struct ctf_field_class
*decl
)
450 qname
= get_prefixed_named_quark(ctx
, prefix
, name
);
456 /* Make sure alias does not exist in local scope */
457 if (ctx_decl_scope_lookup_prefix_alias(ctx
, scope
, prefix
, name
, 1,
463 decl
= ctf_field_class_copy(decl
);
465 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
472 * Registers a class alias within a declaration scope.
474 * @param scope Declaration scope
475 * @param name Alias name (non-NULL)
476 * @param decl Field class to register (copied)
477 * @returns 0 if registration went okay, negative value otherwise
480 int ctx_decl_scope_register_alias(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
481 const char *name
, struct ctf_field_class
*decl
)
483 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ALIAS
,
484 name
, (void *) decl
);
488 * Registers an enumeration declaration within a declaration scope.
490 * @param scope Declaration scope
491 * @param name Enumeration name (non-NULL)
492 * @param decl Enumeration field class to register (copied)
493 * @returns 0 if registration went okay, negative value otherwise
496 int ctx_decl_scope_register_enum(struct ctx
*ctx
, struct ctx_decl_scope
*scope
,
497 const char *name
, struct ctf_field_class_enum
*decl
)
499 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_ENUM
,
500 name
, (void *) decl
);
504 * Registers a structure declaration within a declaration scope.
506 * @param scope Declaration scope
507 * @param name Structure name (non-NULL)
508 * @param decl Structure field class to register (copied)
509 * @returns 0 if registration went okay, negative value otherwise
512 int ctx_decl_scope_register_struct(struct ctx
*ctx
,
513 struct ctx_decl_scope
*scope
, const char *name
,
514 struct ctf_field_class_struct
*decl
)
516 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_STRUCT
,
517 name
, (void *) decl
);
521 * Registers a variant declaration within a declaration scope.
523 * @param scope Declaration scope
524 * @param name Variant name (non-NULL)
525 * @param decl Variant field class to register
526 * @returns 0 if registration went okay, negative value otherwise
529 int ctx_decl_scope_register_variant(struct ctx
*ctx
,
530 struct ctx_decl_scope
*scope
, const char *name
,
531 struct ctf_field_class_variant
*decl
)
533 return ctx_decl_scope_register_prefix_alias(ctx
, scope
, _PREFIX_VARIANT
,
534 name
, (void *) decl
);
538 * Destroys a visitor context.
540 * @param ctx Visitor context to destroy
543 void ctx_destroy(struct ctx
*ctx
)
545 struct ctx_decl_scope
*scope
;
551 scope
= ctx
->current_scope
;
554 * Destroy all scopes, from current one to the root scope.
557 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
559 ctx_decl_scope_destroy(scope
);
560 scope
= parent_scope
;
563 bt_trace_class_put_ref(ctx
->trace_class
);
566 ctf_trace_class_destroy(ctx
->ctf_tc
);
576 * Creates a new visitor context.
578 * @param trace Associated trace
579 * @returns New visitor context, or NULL on error
582 struct ctx
*ctx_create(const struct ctf_metadata_decoder_config
*decoder_config
)
584 struct ctx
*ctx
= NULL
;
586 BT_ASSERT(decoder_config
);
588 ctx
= g_new0(struct ctx
, 1);
590 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
591 decoder_config
->self_comp
,
592 "Failed to allocate one visitor context.");
596 ctx
->log_cfg
.log_level
= decoder_config
->log_level
;
597 ctx
->log_cfg
.self_comp
= decoder_config
->self_comp
;
599 if (decoder_config
->self_comp
) {
600 ctx
->trace_class
= bt_trace_class_create(
601 decoder_config
->self_comp
);
602 if (!ctx
->trace_class
) {
603 BT_COMP_LOGE_STR("Cannot create empty trace class.");
608 ctx
->ctf_tc
= ctf_trace_class_create();
610 BT_COMP_LOGE_STR("Cannot create CTF trace class.");
614 /* Root declaration scope */
615 ctx
->current_scope
= ctx_decl_scope_create(ctx
, NULL
);
616 if (!ctx
->current_scope
) {
617 BT_COMP_LOGE_STR("Cannot create declaration scope.");
621 ctx
->decoder_config
= *decoder_config
;
633 * Pushes a new declaration scope on top of a visitor context's
634 * declaration scope stack.
636 * @param ctx Visitor context
637 * @returns 0 on success, or a negative value on error
640 int ctx_push_scope(struct ctx
*ctx
)
643 struct ctx_decl_scope
*new_scope
;
646 new_scope
= ctx_decl_scope_create(ctx
, ctx
->current_scope
);
648 BT_COMP_LOGE_STR("Cannot create declaration scope.");
653 ctx
->current_scope
= new_scope
;
660 void ctx_pop_scope(struct ctx
*ctx
)
662 struct ctx_decl_scope
*parent_scope
= NULL
;
666 if (!ctx
->current_scope
) {
670 parent_scope
= ctx
->current_scope
->parent_scope
;
671 ctx_decl_scope_destroy(ctx
->current_scope
);
672 ctx
->current_scope
= parent_scope
;
679 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
680 struct ctf_field_class
**decl
);
683 int is_unary_string(struct bt_list_head
*head
)
686 struct ctf_node
*node
;
688 bt_list_for_each_entry(node
, head
, siblings
) {
689 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
693 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
702 const char *get_map_clock_name_value(struct bt_list_head
*head
)
705 struct ctf_node
*node
;
706 const char *name
= NULL
;
708 bt_list_for_each_entry(node
, head
, siblings
) {
710 int uexpr_type
= node
->u
.unary_expression
.type
;
711 int uexpr_link
= node
->u
.unary_expression
.link
;
712 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
713 uexpr_type
!= UNARY_STRING
||
714 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
719 /* Needs to be chained with . */
720 switch (node
->u
.unary_expression
.link
) {
723 case UNARY_ARROWLINK
:
724 case UNARY_DOTDOTDOT
:
730 src_string
= node
->u
.unary_expression
.u
.string
;
734 if (strcmp("clock", src_string
)) {
742 if (strcmp("value", src_string
)) {
747 /* Extra identifier, unknown */
761 int is_unary_unsigned(struct bt_list_head
*head
)
764 struct ctf_node
*node
;
766 bt_list_for_each_entry(node
, head
, siblings
) {
767 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
771 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
780 int get_unary_unsigned(struct ctx
*ctx
, struct bt_list_head
*head
,
785 struct ctf_node
*node
;
789 if (bt_list_empty(head
)) {
794 bt_list_for_each_entry(node
, head
, siblings
) {
795 int uexpr_type
= node
->u
.unary_expression
.type
;
796 int uexpr_link
= node
->u
.unary_expression
.link
;
797 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
798 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
799 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
801 _BT_COMP_LOGE_NODE(node
, "Invalid constant unsigned integer.");
806 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
815 int is_unary_signed(struct bt_list_head
*head
)
818 struct ctf_node
*node
;
820 bt_list_for_each_entry(node
, head
, siblings
) {
821 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
825 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
834 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
838 struct ctf_node
*node
;
840 bt_list_for_each_entry(node
, head
, siblings
) {
841 int uexpr_type
= node
->u
.unary_expression
.type
;
842 int uexpr_link
= node
->u
.unary_expression
.link
;
843 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
844 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
845 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
846 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
852 switch (uexpr_type
) {
853 case UNARY_UNSIGNED_CONSTANT
:
855 node
->u
.unary_expression
.u
.unsigned_constant
;
857 case UNARY_SIGNED_CONSTANT
:
858 *value
= node
->u
.unary_expression
.u
.signed_constant
;
872 int get_unary_uuid(struct ctx
*ctx
, struct bt_list_head
*head
,
875 return ctf_ast_get_unary_uuid(head
, uuid
, ctx
->log_cfg
.log_level
,
876 ctx
->log_cfg
.self_comp
);
880 int get_boolean(struct ctx
*ctx
, struct ctf_node
*unary_expr
)
884 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
885 _BT_COMP_LOGE_NODE(unary_expr
,
886 "Expecting unary expression: node-type=%d",
892 switch (unary_expr
->u
.unary_expression
.type
) {
893 case UNARY_UNSIGNED_CONSTANT
:
894 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
896 case UNARY_SIGNED_CONSTANT
:
897 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
901 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
903 if (strcmp(str
, "true") == 0 || strcmp(str
, "TRUE") == 0) {
905 } else if (strcmp(str
, "false") == 0 || strcmp(str
, "FALSE") == 0) {
908 _BT_COMP_LOGE_NODE(unary_expr
,
909 "Unexpected boolean value: value=\"%s\"", str
);
916 _BT_COMP_LOGE_NODE(unary_expr
,
917 "Unexpected unary expression type: node-type=%d",
918 unary_expr
->u
.unary_expression
.type
);
928 enum ctf_byte_order
byte_order_from_unary_expr(struct ctx
*ctx
,
929 struct ctf_node
*unary_expr
)
932 enum ctf_byte_order bo
= CTF_BYTE_ORDER_UNKNOWN
;
934 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
935 _BT_COMP_LOGE_NODE(unary_expr
,
936 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
940 str
= unary_expr
->u
.unary_expression
.u
.string
;
942 if (strcmp(str
, "be") == 0 || strcmp(str
, "network") == 0) {
943 bo
= CTF_BYTE_ORDER_BIG
;
944 } else if (strcmp(str
, "le") == 0) {
945 bo
= CTF_BYTE_ORDER_LITTLE
;
946 } else if (strcmp(str
, "native") == 0) {
947 bo
= CTF_BYTE_ORDER_DEFAULT
;
949 _BT_COMP_LOGE_NODE(unary_expr
,
950 "Unexpected \"byte_order\" attribute value: "
951 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
961 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
962 struct ctf_node
*uexpr
)
964 enum ctf_byte_order bo
= byte_order_from_unary_expr(ctx
, uexpr
);
966 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
967 bo
= ctx
->ctf_tc
->default_byte_order
;
974 int is_align_valid(uint64_t align
)
976 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
980 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
985 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
986 _BT_COMP_LOGE_NODE(cls_specifier
,
987 "Unexpected node type: node-type=%d",
988 cls_specifier
->type
);
993 switch (cls_specifier
->u
.field_class_specifier
.type
) {
995 g_string_append(str
, "void");
998 g_string_append(str
, "char");
1000 case TYPESPEC_SHORT
:
1001 g_string_append(str
, "short");
1004 g_string_append(str
, "int");
1007 g_string_append(str
, "long");
1009 case TYPESPEC_FLOAT
:
1010 g_string_append(str
, "float");
1012 case TYPESPEC_DOUBLE
:
1013 g_string_append(str
, "double");
1015 case TYPESPEC_SIGNED
:
1016 g_string_append(str
, "signed");
1018 case TYPESPEC_UNSIGNED
:
1019 g_string_append(str
, "unsigned");
1022 g_string_append(str
, "bool");
1024 case TYPESPEC_COMPLEX
:
1025 g_string_append(str
, "_Complex");
1027 case TYPESPEC_IMAGINARY
:
1028 g_string_append(str
, "_Imaginary");
1030 case TYPESPEC_CONST
:
1031 g_string_append(str
, "const");
1033 case TYPESPEC_ID_TYPE
:
1034 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1035 g_string_append(str
,
1036 cls_specifier
->u
.field_class_specifier
.id_type
);
1039 case TYPESPEC_STRUCT
:
1041 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1043 if (!node
->u
._struct
.name
) {
1044 _BT_COMP_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1049 g_string_append(str
, "struct ");
1050 g_string_append(str
, node
->u
._struct
.name
);
1053 case TYPESPEC_VARIANT
:
1055 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1057 if (!node
->u
.variant
.name
) {
1058 _BT_COMP_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1063 g_string_append(str
, "variant ");
1064 g_string_append(str
, node
->u
.variant
.name
);
1069 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1071 if (!node
->u
._enum
.enum_id
) {
1072 _BT_COMP_LOGE_NODE(node
,
1073 "Unexpected empty enumeration field class (`enum`) name.");
1078 g_string_append(str
, "enum ");
1079 g_string_append(str
, node
->u
._enum
.enum_id
);
1082 case TYPESPEC_FLOATING_POINT
:
1083 case TYPESPEC_INTEGER
:
1084 case TYPESPEC_STRING
:
1086 _BT_COMP_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1087 "Unexpected field class specifier type: %d",
1088 cls_specifier
->u
.field_class_specifier
.type
);
1098 int get_class_specifier_list_name(struct ctx
*ctx
,
1099 struct ctf_node
*cls_specifier_list
, GString
*str
)
1102 struct ctf_node
*iter
;
1103 int alias_item_nr
= 0;
1104 struct bt_list_head
*head
=
1105 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1107 bt_list_for_each_entry(iter
, head
, siblings
) {
1108 if (alias_item_nr
!= 0) {
1109 g_string_append(str
, " ");
1113 ret
= get_class_specifier_name(ctx
, iter
, str
);
1124 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1125 struct ctf_node
*cls_specifier_list
,
1126 struct ctf_node
*node_field_class_declarator
)
1132 struct ctf_node
*iter
;
1133 struct bt_list_head
*pointers
=
1134 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1136 str
= g_string_new("");
1137 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1139 g_string_free(str
, TRUE
);
1143 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1144 g_string_append(str
, " *");
1146 if (iter
->u
.pointer
.const_qualifier
) {
1147 g_string_append(str
, " const");
1151 str_c
= g_string_free(str
, FALSE
);
1152 qalias
= g_quark_from_string(str_c
);
1160 int visit_field_class_declarator(struct ctx
*ctx
,
1161 struct ctf_node
*cls_specifier_list
,
1162 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1163 struct ctf_field_class
**field_decl
,
1164 struct ctf_field_class
*nested_decl
)
1167 * During this whole function, nested_decl is always OURS,
1168 * whereas field_decl is an output which we create, but
1169 * belongs to the caller (it is moved).
1174 /* Validate field class declarator node */
1175 if (node_field_class_declarator
) {
1176 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1178 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1179 "Unexpected field class declarator type: type=%d",
1180 node_field_class_declarator
->u
.field_class_declarator
.type
);
1185 /* TODO: GCC bitfields not supported yet */
1186 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1188 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1189 "GCC bitfields are not supported as of this version.");
1195 /* Find the right nested declaration if not provided */
1197 struct bt_list_head
*pointers
=
1198 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1200 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1204 * If we have a pointer declarator, it HAS to
1205 * be present in the field class aliases (else
1208 qalias
= create_class_alias_identifier(ctx
,
1209 cls_specifier_list
, node_field_class_declarator
);
1211 ctx_decl_scope_lookup_alias(ctx
,
1213 g_quark_to_string(qalias
), -1, true);
1215 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1216 "Cannot find class alias: name=\"%s\"",
1217 g_quark_to_string(qalias
));
1222 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1223 /* Pointer: force integer's base to 16 */
1224 struct ctf_field_class_int
*int_fc
=
1225 (void *) nested_decl
;
1228 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1231 ret
= visit_field_class_specifier_list(ctx
,
1232 cls_specifier_list
, &nested_decl
);
1234 BT_ASSERT(!nested_decl
);
1240 BT_ASSERT(nested_decl
);
1242 if (!node_field_class_declarator
) {
1243 *field_decl
= nested_decl
;
1248 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1249 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1251 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1253 *field_name
= g_quark_from_string(id
);
1258 *field_decl
= nested_decl
;
1262 struct ctf_node
*first
;
1263 struct ctf_field_class
*decl
= NULL
;
1264 struct ctf_field_class
*outer_field_decl
= NULL
;
1265 struct bt_list_head
*length
=
1266 &node_field_class_declarator
->
1267 u
.field_class_declarator
.u
.nested
.length
;
1269 /* Create array/sequence, pass nested_decl as child */
1270 if (bt_list_empty(length
)) {
1271 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1272 "Expecting length field reference or value.");
1277 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1278 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1279 _BT_COMP_LOGE_NODE(first
,
1280 "Unexpected node type: node-type=%d",
1286 switch (first
->u
.unary_expression
.type
) {
1287 case UNARY_UNSIGNED_CONSTANT
:
1289 struct ctf_field_class_array
*array_decl
= NULL
;
1291 array_decl
= ctf_field_class_array_create();
1292 BT_ASSERT(array_decl
);
1293 array_decl
->length
=
1294 first
->u
.unary_expression
.u
.unsigned_constant
;
1295 array_decl
->base
.elem_fc
= nested_decl
;
1297 decl
= (void *) array_decl
;
1302 /* Lookup unsigned integer definition, create seq. */
1303 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1304 char *length_name
= ctf_ast_concatenate_unary_strings(length
);
1307 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1308 "Cannot concatenate unary strings.");
1313 if (strncmp(length_name
, "env.", 4) == 0) {
1314 /* This is, in fact, an array */
1315 const char *env_entry_name
= &length_name
[4];
1316 struct ctf_trace_class_env_entry
*env_entry
=
1317 ctf_trace_class_borrow_env_entry_by_name(
1318 ctx
->ctf_tc
, env_entry_name
);
1319 struct ctf_field_class_array
*array_decl
;
1322 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1323 "Cannot find environment entry: "
1324 "name=\"%s\"", env_entry_name
);
1329 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1330 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1331 "Wrong environment entry type "
1332 "(expecting integer): "
1333 "name=\"%s\"", env_entry_name
);
1338 if (env_entry
->value
.i
< 0) {
1339 _BT_COMP_LOGE_NODE(node_field_class_declarator
,
1340 "Invalid, negative array length: "
1341 "env-entry-name=\"%s\", "
1344 env_entry
->value
.i
);
1349 array_decl
= ctf_field_class_array_create();
1350 BT_ASSERT(array_decl
);
1351 array_decl
->length
=
1352 (uint64_t) env_entry
->value
.i
;
1353 array_decl
->base
.elem_fc
= nested_decl
;
1355 decl
= (void *) array_decl
;
1357 seq_decl
= ctf_field_class_sequence_create();
1358 BT_ASSERT(seq_decl
);
1359 seq_decl
->base
.elem_fc
= nested_decl
;
1361 g_string_assign(seq_decl
->length_ref
,
1363 decl
= (void *) seq_decl
;
1366 g_free(length_name
);
1374 BT_ASSERT(!nested_decl
);
1376 BT_ASSERT(!*field_decl
);
1379 * At this point, we found the next nested declaration.
1380 * We currently own this (and lost the ownership of
1381 * nested_decl in the meantime). Pass this next
1382 * nested declaration as the content of the outer
1383 * container, MOVING its ownership.
1385 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1387 node_field_class_declarator
->
1388 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1389 &outer_field_decl
, decl
);
1392 BT_ASSERT(!outer_field_decl
);
1397 BT_ASSERT(outer_field_decl
);
1398 *field_decl
= outer_field_decl
;
1399 outer_field_decl
= NULL
;
1402 BT_ASSERT(*field_decl
);
1406 ctf_field_class_destroy(*field_decl
);
1414 ctf_field_class_destroy(nested_decl
);
1420 int visit_struct_decl_field(struct ctx
*ctx
,
1421 struct ctf_field_class_struct
*struct_decl
,
1422 struct ctf_node
*cls_specifier_list
,
1423 struct bt_list_head
*field_class_declarators
)
1426 struct ctf_node
*iter
;
1427 struct ctf_field_class
*field_decl
= NULL
;
1429 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1432 const char *field_name
;
1434 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1435 &qfield_name
, iter
, &field_decl
, NULL
);
1437 BT_ASSERT(!field_decl
);
1438 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1439 "Cannot visit field class declarator: ret=%d", ret
);
1443 BT_ASSERT(field_decl
);
1444 field_name
= g_quark_to_string(qfield_name
);
1446 /* Check if field with same name already exists */
1447 if (ctf_field_class_struct_borrow_member_by_name(
1448 struct_decl
, field_name
)) {
1449 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1450 "Duplicate field in structure field class: "
1451 "field-name=\"%s\"", field_name
);
1456 /* Add field to structure */
1457 ctf_field_class_struct_append_member(struct_decl
,
1458 field_name
, field_decl
);
1465 ctf_field_class_destroy(field_decl
);
1471 int visit_variant_decl_field(struct ctx
*ctx
,
1472 struct ctf_field_class_variant
*variant_decl
,
1473 struct ctf_node
*cls_specifier_list
,
1474 struct bt_list_head
*field_class_declarators
)
1477 struct ctf_node
*iter
;
1478 struct ctf_field_class
*field_decl
= NULL
;
1480 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1483 const char *field_name
;
1485 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1486 &qfield_name
, iter
, &field_decl
, NULL
);
1488 BT_ASSERT(!field_decl
);
1489 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1490 "Cannot visit field class declarator: ret=%d", ret
);
1494 BT_ASSERT(field_decl
);
1495 field_name
= g_quark_to_string(qfield_name
);
1497 /* Check if field with same name already exists */
1498 if (ctf_field_class_variant_borrow_option_by_name(
1499 variant_decl
, field_name
)) {
1500 _BT_COMP_LOGE_NODE(cls_specifier_list
,
1501 "Duplicate field in variant field class: "
1502 "field-name=\"%s\"", field_name
);
1507 /* Add field to structure */
1508 ctf_field_class_variant_append_option(variant_decl
,
1509 field_name
, field_decl
);
1516 ctf_field_class_destroy(field_decl
);
1522 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1523 struct bt_list_head
*field_class_declarators
)
1527 struct ctf_node
*iter
;
1528 struct ctf_field_class
*class_decl
= NULL
;
1530 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1531 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1532 &qidentifier
, iter
, &class_decl
, NULL
);
1534 _BT_COMP_LOGE_NODE(iter
,
1535 "Cannot visit field class declarator: ret=%d", ret
);
1540 /* Do not allow field class def and alias of untagged variants */
1541 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1542 struct ctf_field_class_variant
*var_fc
=
1543 (void *) class_decl
;
1545 if (var_fc
->tag_path
.path
->len
== 0) {
1546 _BT_COMP_LOGE_NODE(iter
,
1547 "Type definition of untagged variant field class is not allowed.");
1553 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1554 g_quark_to_string(qidentifier
), class_decl
);
1556 _BT_COMP_LOGE_NODE(iter
,
1557 "Cannot register field class alias: name=\"%s\"",
1558 g_quark_to_string(qidentifier
));
1564 ctf_field_class_destroy(class_decl
);
1570 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1571 struct ctf_node
*alias
)
1575 struct ctf_node
*node
;
1576 GQuark qdummy_field_name
;
1577 struct ctf_field_class
*class_decl
= NULL
;
1579 /* Create target field class */
1580 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1583 node
= _BT_LIST_FIRST_ENTRY(
1584 &target
->u
.field_class_alias_target
.field_class_declarators
,
1585 struct ctf_node
, siblings
);
1588 ret
= visit_field_class_declarator(ctx
,
1589 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1590 &qdummy_field_name
, node
, &class_decl
, NULL
);
1592 BT_ASSERT(!class_decl
);
1593 _BT_COMP_LOGE_NODE(node
,
1594 "Cannot visit field class declarator: ret=%d", ret
);
1598 /* Do not allow field class def and alias of untagged variants */
1599 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1600 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1602 if (var_fc
->tag_path
.path
->len
== 0) {
1603 _BT_COMP_LOGE_NODE(target
,
1604 "Type definition of untagged variant field class is not allowed.");
1611 * The semantic validator does not check whether the target is
1612 * abstract or not (if it has an identifier). Check it here.
1614 if (qdummy_field_name
!= 0) {
1615 _BT_COMP_LOGE_NODE(target
,
1616 "Expecting empty identifier: id=\"%s\"",
1617 g_quark_to_string(qdummy_field_name
));
1622 /* Create alias identifier */
1623 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1624 struct ctf_node
, siblings
);
1625 qalias
= create_class_alias_identifier(ctx
,
1626 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1627 ret
= ctx_decl_scope_register_alias(ctx
, ctx
->current_scope
,
1628 g_quark_to_string(qalias
), class_decl
);
1630 _BT_COMP_LOGE_NODE(node
,
1631 "Cannot register class alias: name=\"%s\"",
1632 g_quark_to_string(qalias
));
1637 ctf_field_class_destroy(class_decl
);
1643 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1644 struct ctf_field_class_struct
*struct_decl
)
1648 switch (entry_node
->type
) {
1650 ret
= visit_field_class_def(ctx
,
1651 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1652 &entry_node
->u
.field_class_def
.field_class_declarators
);
1654 _BT_COMP_LOGE_NODE(entry_node
,
1655 "Cannot add field class found in structure field class: ret=%d",
1660 case NODE_TYPEALIAS
:
1661 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1662 entry_node
->u
.field_class_alias
.alias
);
1664 _BT_COMP_LOGE_NODE(entry_node
,
1665 "Cannot add field class alias found in structure field class: ret=%d",
1670 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1672 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1673 entry_node
->u
.struct_or_variant_declaration
.
1674 field_class_specifier_list
,
1675 &entry_node
->u
.struct_or_variant_declaration
.
1676 field_class_declarators
);
1682 _BT_COMP_LOGE_NODE(entry_node
,
1683 "Unexpected node type: node-type=%d", entry_node
->type
);
1693 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1694 struct ctf_field_class_variant
*variant_decl
)
1698 switch (entry_node
->type
) {
1700 ret
= visit_field_class_def(ctx
,
1701 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1702 &entry_node
->u
.field_class_def
.field_class_declarators
);
1704 _BT_COMP_LOGE_NODE(entry_node
,
1705 "Cannot add field class found in variant field class: ret=%d",
1710 case NODE_TYPEALIAS
:
1711 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1712 entry_node
->u
.field_class_alias
.alias
);
1714 _BT_COMP_LOGE_NODE(entry_node
,
1715 "Cannot add field class alias found in variant field class: ret=%d",
1720 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1722 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1723 entry_node
->u
.struct_or_variant_declaration
.
1724 field_class_specifier_list
,
1725 &entry_node
->u
.struct_or_variant_declaration
.
1726 field_class_declarators
);
1732 _BT_COMP_LOGE_NODE(entry_node
,
1733 "Unexpected node type: node-type=%d",
1744 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1745 struct bt_list_head
*decl_list
, int has_body
,
1746 struct bt_list_head
*min_align
,
1747 struct ctf_field_class_struct
**struct_decl
)
1751 BT_ASSERT(struct_decl
);
1752 *struct_decl
= NULL
;
1754 /* For named struct (without body), lookup in declaration scope */
1757 BT_COMP_LOGE_STR("Bodyless structure field class: missing name.");
1762 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
, ctx
->current_scope
,
1764 if (!*struct_decl
) {
1765 BT_COMP_LOGE("Cannot find structure field class: name=\"struct %s\"",
1771 struct ctf_node
*entry_node
;
1772 uint64_t min_align_value
= 0;
1775 if (ctx_decl_scope_lookup_struct(ctx
,
1776 ctx
->current_scope
, name
, 1, false)) {
1777 BT_COMP_LOGE("Structure field class already declared in local scope: "
1778 "name=\"struct %s\"", name
);
1784 if (!bt_list_empty(min_align
)) {
1785 ret
= get_unary_unsigned(ctx
, min_align
,
1788 BT_COMP_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1794 *struct_decl
= ctf_field_class_struct_create();
1795 BT_ASSERT(*struct_decl
);
1797 if (min_align_value
!= 0) {
1798 (*struct_decl
)->base
.alignment
= min_align_value
;
1801 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1803 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1804 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1807 _BT_COMP_LOGE_NODE(entry_node
,
1808 "Cannot visit structure field class entry: "
1818 ret
= ctx_decl_scope_register_struct(ctx
,
1819 ctx
->current_scope
, name
, *struct_decl
);
1821 BT_COMP_LOGE("Cannot register structure field class in declaration scope: "
1822 "name=\"struct %s\", ret=%d", name
, ret
);
1831 ctf_field_class_destroy((void *) *struct_decl
);
1832 *struct_decl
= NULL
;
1837 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1838 const char *tag
, struct bt_list_head
*decl_list
,
1839 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1842 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1844 BT_ASSERT(variant_decl
);
1845 *variant_decl
= NULL
;
1847 /* For named variant (without body), lookup in declaration scope */
1850 BT_COMP_LOGE_STR("Bodyless variant field class: missing name.");
1855 untagged_variant_decl
=
1856 ctx_decl_scope_lookup_variant(ctx
, ctx
->current_scope
,
1858 if (!untagged_variant_decl
) {
1859 BT_COMP_LOGE("Cannot find variant field class: name=\"variant %s\"",
1865 struct ctf_node
*entry_node
;
1868 if (ctx_decl_scope_lookup_variant(ctx
,
1869 ctx
->current_scope
, name
, 1, false)) {
1870 BT_COMP_LOGE("Variant field class already declared in local scope: "
1871 "name=\"variant %s\"", name
);
1877 untagged_variant_decl
= ctf_field_class_variant_create();
1878 BT_ASSERT(untagged_variant_decl
);
1879 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1881 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1882 ret
= visit_variant_decl_entry(ctx
, entry_node
,
1883 untagged_variant_decl
);
1885 _BT_COMP_LOGE_NODE(entry_node
,
1886 "Cannot visit variant field class entry: "
1896 ret
= ctx_decl_scope_register_variant(ctx
,
1897 ctx
->current_scope
, name
,
1898 untagged_variant_decl
);
1900 BT_COMP_LOGE("Cannot register variant field class in declaration scope: "
1901 "name=\"variant %s\", ret=%d", name
, ret
);
1908 * If tagged, create tagged variant and return; otherwise
1909 * return untagged variant.
1912 *variant_decl
= untagged_variant_decl
;
1913 untagged_variant_decl
= NULL
;
1916 * At this point, we have a fresh untagged variant; nobody
1917 * else owns it. Set its tag now.
1919 g_string_assign(untagged_variant_decl
->tag_ref
, tag
);
1920 *variant_decl
= untagged_variant_decl
;
1921 untagged_variant_decl
= NULL
;
1924 BT_ASSERT(!untagged_variant_decl
);
1925 BT_ASSERT(*variant_decl
);
1929 ctf_field_class_destroy((void *) untagged_variant_decl
);
1930 untagged_variant_decl
= NULL
;
1931 ctf_field_class_destroy((void *) *variant_decl
);
1932 *variant_decl
= NULL
;
1945 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
1946 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
1950 struct ctf_node
*iter
;
1951 struct uori start
= {
1959 const char *label
= enumerator
->u
.enumerator
.id
;
1960 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
1962 bt_list_for_each_entry(iter
, values
, siblings
) {
1963 struct uori
*target
;
1965 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
1966 _BT_COMP_LOGE_NODE(iter
,
1967 "Wrong expression for enumeration field class label: "
1968 "node-type=%d, label=\"%s\"", iter
->type
,
1980 switch (iter
->u
.unary_expression
.type
) {
1981 case UNARY_SIGNED_CONSTANT
:
1982 target
->is_signed
= true;
1984 iter
->u
.unary_expression
.u
.signed_constant
;
1986 case UNARY_UNSIGNED_CONSTANT
:
1987 target
->is_signed
= false;
1989 iter
->u
.unary_expression
.u
.unsigned_constant
;
1992 _BT_COMP_LOGE_NODE(iter
,
1993 "Invalid enumeration field class entry: "
1994 "expecting constant signed or unsigned integer: "
1995 "node-type=%d, label=\"%s\"",
1996 iter
->u
.unary_expression
.type
, label
);
2002 _BT_COMP_LOGE_NODE(iter
,
2003 "Invalid enumeration field class entry: label=\"%s\"",
2020 if (end
.is_signed
) {
2021 last
->value
.i
= end
.value
.i
+ 1;
2023 last
->value
.u
= end
.value
.u
+ 1;
2026 ctf_field_class_enum_map_range(enum_decl
, label
,
2027 start
.value
.u
, end
.value
.u
);
2035 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2036 struct ctf_node
*container_cls
,
2037 struct bt_list_head
*enumerator_list
,
2038 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2042 struct ctf_field_class_int
*integer_decl
= NULL
;
2044 BT_ASSERT(enum_decl
);
2047 /* For named enum (without body), lookup in declaration scope */
2050 BT_COMP_LOGE_STR("Bodyless enumeration field class: missing name.");
2055 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2058 BT_COMP_LOGE("Cannot find enumeration field class: "
2059 "name=\"enum %s\"", name
);
2064 struct ctf_node
*iter
;
2065 struct uori last_value
= {
2071 if (ctx_decl_scope_lookup_enum(ctx
, ctx
->current_scope
,
2073 BT_COMP_LOGE("Enumeration field class already declared in local scope: "
2074 "name=\"enum %s\"", name
);
2080 if (!container_cls
) {
2081 integer_decl
= (void *) ctx_decl_scope_lookup_alias(ctx
,
2082 ctx
->current_scope
, "int", -1, true);
2083 if (!integer_decl
) {
2084 BT_COMP_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2089 ret
= visit_field_class_declarator(ctx
, container_cls
,
2090 &qdummy_id
, NULL
, (void *) &integer_decl
,
2093 BT_ASSERT(!integer_decl
);
2099 BT_ASSERT(integer_decl
);
2101 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2102 BT_COMP_LOGE("Container field class for enumeration field class is not an integer field class: "
2103 "fc-type=%d", integer_decl
->base
.base
.type
);
2108 *enum_decl
= ctf_field_class_enum_create();
2109 BT_ASSERT(*enum_decl
);
2110 (*enum_decl
)->base
.base
.base
.alignment
=
2111 integer_decl
->base
.base
.alignment
;
2112 ctf_field_class_int_copy_content((void *) *enum_decl
,
2113 (void *) integer_decl
);
2114 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2116 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2117 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2120 _BT_COMP_LOGE_NODE(iter
,
2121 "Cannot visit enumeration field class entry: "
2128 ret
= ctx_decl_scope_register_enum(ctx
,
2129 ctx
->current_scope
, name
, *enum_decl
);
2131 BT_COMP_LOGE("Cannot register enumeration field class in declaration scope: "
2141 ctf_field_class_destroy((void *) *enum_decl
);
2145 ctf_field_class_destroy((void *) integer_decl
);
2146 integer_decl
= NULL
;
2151 int visit_field_class_specifier(struct ctx
*ctx
,
2152 struct ctf_node
*cls_specifier_list
,
2153 struct ctf_field_class
**decl
)
2156 GString
*str
= NULL
;
2159 str
= g_string_new("");
2160 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2162 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2163 "Cannot get field class specifier list's name: ret=%d", ret
);
2167 *decl
= ctx_decl_scope_lookup_alias(ctx
, ctx
->current_scope
, str
->str
,
2170 _BT_COMP_LOGE_NODE(cls_specifier_list
,
2171 "Cannot find field class alias: name=\"%s\"", str
->str
);
2179 ctf_field_class_destroy(*decl
);
2184 g_string_free(str
, TRUE
);
2191 int visit_integer_decl(struct ctx
*ctx
,
2192 struct bt_list_head
*expressions
,
2193 struct ctf_field_class_int
**integer_decl
)
2198 struct ctf_node
*expression
;
2199 uint64_t alignment
= 0, size
= 0;
2200 struct ctf_clock_class
*mapped_clock_class
= NULL
;
2201 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2202 bt_field_class_integer_preferred_display_base base
=
2203 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2204 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2206 *integer_decl
= NULL
;
2208 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2209 struct ctf_node
*left
, *right
;
2211 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2212 struct ctf_node
, siblings
);
2213 right
= _BT_LIST_FIRST_ENTRY(
2214 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2217 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2218 _BT_COMP_LOGE_NODE(left
,
2219 "Unexpected unary expression type: type=%d",
2220 left
->u
.unary_expression
.type
);
2225 if (strcmp(left
->u
.unary_expression
.u
.string
, "signed") == 0) {
2226 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2227 _BT_COMP_LOGE_DUP_ATTR(left
, "signed",
2228 "integer field class");
2233 signedness
= get_boolean(ctx
, right
);
2234 if (signedness
< 0) {
2235 _BT_COMP_LOGE_NODE(right
,
2236 "Invalid boolean value for integer field class's `signed` attribute: "
2242 _SET(&set
, _INTEGER_SIGNED_SET
);
2243 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2244 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2245 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2246 "integer field class");
2251 byte_order
= get_real_byte_order(ctx
, right
);
2252 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2253 _BT_COMP_LOGE_NODE(right
,
2254 "Invalid `byte_order` attribute in integer field class: "
2260 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2261 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "size") == 0) {
2262 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2263 _BT_COMP_LOGE_DUP_ATTR(left
, "size",
2264 "integer field class");
2269 if (right
->u
.unary_expression
.type
!=
2270 UNARY_UNSIGNED_CONSTANT
) {
2271 _BT_COMP_LOGE_NODE(right
,
2272 "Invalid `size` attribute in integer field class: "
2273 "expecting unsigned constant integer: "
2275 right
->u
.unary_expression
.type
);
2280 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2282 _BT_COMP_LOGE_NODE(right
,
2283 "Invalid `size` attribute in integer field class: "
2284 "expecting positive constant integer: "
2285 "size=%" PRIu64
, size
);
2288 } else if (size
> 64) {
2289 _BT_COMP_LOGE_NODE(right
,
2290 "Invalid `size` attribute in integer field class: "
2291 "integer fields over 64 bits are not supported as of this version: "
2292 "size=%" PRIu64
, size
);
2297 _SET(&set
, _INTEGER_SIZE_SET
);
2298 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2299 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2300 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2301 "integer field class");
2306 if (right
->u
.unary_expression
.type
!=
2307 UNARY_UNSIGNED_CONSTANT
) {
2308 _BT_COMP_LOGE_NODE(right
,
2309 "Invalid `align` attribute in integer field class: "
2310 "expecting unsigned constant integer: "
2312 right
->u
.unary_expression
.type
);
2318 right
->u
.unary_expression
.u
.unsigned_constant
;
2319 if (!is_align_valid(alignment
)) {
2320 _BT_COMP_LOGE_NODE(right
,
2321 "Invalid `align` attribute in integer field class: "
2322 "expecting power of two: "
2323 "align=%" PRIu64
, alignment
);
2328 _SET(&set
, _INTEGER_ALIGN_SET
);
2329 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "base") == 0) {
2330 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2331 _BT_COMP_LOGE_DUP_ATTR(left
, "base",
2332 "integer field class");
2337 switch (right
->u
.unary_expression
.type
) {
2338 case UNARY_UNSIGNED_CONSTANT
:
2340 uint64_t constant
= right
->u
.unary_expression
.
2341 u
.unsigned_constant
;
2345 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2348 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2351 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2354 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2357 _BT_COMP_LOGE_NODE(right
,
2358 "Invalid `base` attribute in integer field class: "
2360 right
->u
.unary_expression
.u
.unsigned_constant
);
2368 char *s_right
= ctf_ast_concatenate_unary_strings(
2369 &expression
->u
.ctf_expression
.right
);
2371 _BT_COMP_LOGE_NODE(right
,
2372 "Unexpected unary expression for integer field class's `base` attribute.");
2377 if (strcmp(s_right
, "decimal") == 0 ||
2378 strcmp(s_right
, "dec") == 0 ||
2379 strcmp(s_right
, "d") == 0 ||
2380 strcmp(s_right
, "i") == 0 ||
2381 strcmp(s_right
, "u") == 0) {
2382 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2383 } else if (strcmp(s_right
, "hexadecimal") == 0 ||
2384 strcmp(s_right
, "hex") == 0 ||
2385 strcmp(s_right
, "x") == 0 ||
2386 strcmp(s_right
, "X") == 0 ||
2387 strcmp(s_right
, "p") == 0) {
2388 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2389 } else if (strcmp(s_right
, "octal") == 0 ||
2390 strcmp(s_right
, "oct") == 0 ||
2391 strcmp(s_right
, "o") == 0) {
2392 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2393 } else if (strcmp(s_right
, "binary") == 0 ||
2394 strcmp(s_right
, "b") == 0) {
2395 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2397 _BT_COMP_LOGE_NODE(right
,
2398 "Unexpected unary expression for integer field class's `base` attribute: "
2399 "base=\"%s\"", s_right
);
2409 _BT_COMP_LOGE_NODE(right
,
2410 "Invalid `base` attribute in integer field class: "
2411 "expecting unsigned constant integer or unary string.");
2416 _SET(&set
, _INTEGER_BASE_SET
);
2417 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2420 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2421 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2422 "integer field class");
2427 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2428 _BT_COMP_LOGE_NODE(right
,
2429 "Invalid `encoding` attribute in integer field class: "
2430 "expecting unary string.");
2435 s_right
= ctf_ast_concatenate_unary_strings(
2436 &expression
->u
.ctf_expression
.right
);
2438 _BT_COMP_LOGE_NODE(right
,
2439 "Unexpected unary expression for integer field class's `encoding` attribute.");
2444 if (strcmp(s_right
, "UTF8") == 0 ||
2445 strcmp(s_right
, "utf8") == 0 ||
2446 strcmp(s_right
, "utf-8") == 0 ||
2447 strcmp(s_right
, "UTF-8") == 0 ||
2448 strcmp(s_right
, "ASCII") == 0 ||
2449 strcmp(s_right
, "ascii") == 0) {
2450 encoding
= CTF_ENCODING_UTF8
;
2451 } else if (strcmp(s_right
, "none") == 0) {
2452 encoding
= CTF_ENCODING_NONE
;
2454 _BT_COMP_LOGE_NODE(right
,
2455 "Invalid `encoding` attribute in integer field class: "
2456 "unknown encoding: encoding=\"%s\"",
2464 _SET(&set
, _INTEGER_ENCODING_SET
);
2465 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "map") == 0) {
2466 const char *clock_name
;
2468 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2469 _BT_COMP_LOGE_DUP_ATTR(left
, "map",
2470 "integer field class");
2475 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2476 _BT_COMP_LOGE_NODE(right
,
2477 "Invalid `map` attribute in integer field class: "
2478 "expecting unary string.");
2484 get_map_clock_name_value(
2485 &expression
->u
.ctf_expression
.right
);
2487 char *s_right
= ctf_ast_concatenate_unary_strings(
2488 &expression
->u
.ctf_expression
.right
);
2491 _BT_COMP_LOGE_NODE(right
,
2492 "Unexpected unary expression for integer field class's `map` attribute.");
2497 _BT_COMP_LOGE_NODE(right
,
2498 "Invalid `map` attribute in integer field class: "
2499 "cannot find clock class at this point: name=\"%s\"",
2501 _SET(&set
, _INTEGER_MAP_SET
);
2506 mapped_clock_class
=
2507 ctf_trace_class_borrow_clock_class_by_name(
2508 ctx
->ctf_tc
, clock_name
);
2509 if (!mapped_clock_class
) {
2510 _BT_COMP_LOGE_NODE(right
,
2511 "Invalid `map` attribute in integer field class: "
2512 "cannot find clock class at this point: name=\"%s\"",
2518 _SET(&set
, _INTEGER_MAP_SET
);
2520 _BT_COMP_LOGW_NODE(left
,
2521 "Unknown attribute in integer field class: "
2523 left
->u
.unary_expression
.u
.string
);
2527 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2528 BT_COMP_LOGE_STR("Missing `size` attribute in integer field class.");
2533 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2534 if (size
% CHAR_BIT
) {
2535 /* Bit-packed alignment */
2538 /* Byte-packed alignment */
2539 alignment
= CHAR_BIT
;
2543 *integer_decl
= ctf_field_class_int_create();
2544 BT_ASSERT(*integer_decl
);
2545 (*integer_decl
)->base
.base
.alignment
= alignment
;
2546 (*integer_decl
)->base
.byte_order
= byte_order
;
2547 (*integer_decl
)->base
.size
= size
;
2548 (*integer_decl
)->is_signed
= (signedness
> 0);
2549 (*integer_decl
)->disp_base
= base
;
2550 (*integer_decl
)->encoding
= encoding
;
2551 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2555 ctf_field_class_destroy((void *) *integer_decl
);
2556 *integer_decl
= NULL
;
2561 int visit_floating_point_number_decl(struct ctx
*ctx
,
2562 struct bt_list_head
*expressions
,
2563 struct ctf_field_class_float
**float_decl
)
2567 struct ctf_node
*expression
;
2568 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2569 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2573 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2574 struct ctf_node
*left
, *right
;
2576 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2577 struct ctf_node
, siblings
);
2578 right
= _BT_LIST_FIRST_ENTRY(
2579 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2582 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2583 _BT_COMP_LOGE_NODE(left
,
2584 "Unexpected unary expression type: type=%d",
2585 left
->u
.unary_expression
.type
);
2590 if (strcmp(left
->u
.unary_expression
.u
.string
, "byte_order") == 0) {
2591 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2592 _BT_COMP_LOGE_DUP_ATTR(left
, "byte_order",
2593 "floating point number field class");
2598 byte_order
= get_real_byte_order(ctx
, right
);
2599 if (byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
2600 _BT_COMP_LOGE_NODE(right
,
2601 "Invalid `byte_order` attribute in floating point number field class: "
2607 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2608 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig") == 0) {
2609 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2610 _BT_COMP_LOGE_DUP_ATTR(left
, "exp_dig",
2611 "floating point number field class");
2616 if (right
->u
.unary_expression
.type
!=
2617 UNARY_UNSIGNED_CONSTANT
) {
2618 _BT_COMP_LOGE_NODE(right
,
2619 "Invalid `exp_dig` attribute in floating point number field class: "
2620 "expecting unsigned constant integer: "
2622 right
->u
.unary_expression
.type
);
2627 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2628 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2629 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig") == 0) {
2630 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2631 _BT_COMP_LOGE_DUP_ATTR(left
, "mant_dig",
2632 "floating point number field class");
2637 if (right
->u
.unary_expression
.type
!=
2638 UNARY_UNSIGNED_CONSTANT
) {
2639 _BT_COMP_LOGE_NODE(right
,
2640 "Invalid `mant_dig` attribute in floating point number field class: "
2641 "expecting unsigned constant integer: "
2643 right
->u
.unary_expression
.type
);
2648 mant_dig
= right
->u
.unary_expression
.u
.
2650 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2651 } else if (strcmp(left
->u
.unary_expression
.u
.string
, "align") == 0) {
2652 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2653 _BT_COMP_LOGE_DUP_ATTR(left
, "align",
2654 "floating point number field class");
2659 if (right
->u
.unary_expression
.type
!=
2660 UNARY_UNSIGNED_CONSTANT
) {
2661 _BT_COMP_LOGE_NODE(right
,
2662 "Invalid `align` attribute in floating point number field class: "
2663 "expecting unsigned constant integer: "
2665 right
->u
.unary_expression
.type
);
2670 alignment
= right
->u
.unary_expression
.u
.
2673 if (!is_align_valid(alignment
)) {
2674 _BT_COMP_LOGE_NODE(right
,
2675 "Invalid `align` attribute in floating point number field class: "
2676 "expecting power of two: "
2677 "align=%" PRIu64
, alignment
);
2682 _SET(&set
, _FLOAT_ALIGN_SET
);
2684 _BT_COMP_LOGW_NODE(left
,
2685 "Unknown attribute in floating point number field class: "
2687 left
->u
.unary_expression
.u
.string
);
2691 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2692 BT_COMP_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2697 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2698 BT_COMP_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2703 if (mant_dig
!= 24 && mant_dig
!= 53) {
2704 BT_COMP_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2709 if (mant_dig
== 24 && exp_dig
!= 8) {
2710 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2715 if (mant_dig
== 53 && exp_dig
!= 11) {
2716 BT_COMP_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2721 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2722 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2723 /* Bit-packed alignment */
2726 /* Byte-packed alignment */
2727 alignment
= CHAR_BIT
;
2731 *float_decl
= ctf_field_class_float_create();
2732 BT_ASSERT(*float_decl
);
2733 (*float_decl
)->base
.base
.alignment
= alignment
;
2734 (*float_decl
)->base
.byte_order
= byte_order
;
2735 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2739 ctf_field_class_destroy((void *) *float_decl
);
2745 int visit_string_decl(struct ctx
*ctx
,
2746 struct bt_list_head
*expressions
,
2747 struct ctf_field_class_string
**string_decl
)
2751 struct ctf_node
*expression
;
2752 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2754 *string_decl
= NULL
;
2756 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2757 struct ctf_node
*left
, *right
;
2759 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2760 struct ctf_node
, siblings
);
2761 right
= _BT_LIST_FIRST_ENTRY(
2762 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2765 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2766 _BT_COMP_LOGE_NODE(left
,
2767 "Unexpected unary expression type: type=%d",
2768 left
->u
.unary_expression
.type
);
2773 if (strcmp(left
->u
.unary_expression
.u
.string
, "encoding") == 0) {
2776 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2777 _BT_COMP_LOGE_DUP_ATTR(left
, "encoding",
2778 "string field class");
2783 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2784 _BT_COMP_LOGE_NODE(right
,
2785 "Invalid `encoding` attribute in string field class: "
2786 "expecting unary string.");
2791 s_right
= ctf_ast_concatenate_unary_strings(
2792 &expression
->u
.ctf_expression
.right
);
2794 _BT_COMP_LOGE_NODE(right
,
2795 "Unexpected unary expression for string field class's `encoding` attribute.");
2800 if (strcmp(s_right
, "UTF8") == 0 ||
2801 strcmp(s_right
, "utf8") == 0 ||
2802 strcmp(s_right
, "utf-8") == 0 ||
2803 strcmp(s_right
, "UTF-8") == 0 ||
2804 strcmp(s_right
, "ASCII") == 0 ||
2805 strcmp(s_right
, "ascii") == 0) {
2806 encoding
= CTF_ENCODING_UTF8
;
2807 } else if (strcmp(s_right
, "none") == 0) {
2808 encoding
= CTF_ENCODING_NONE
;
2810 _BT_COMP_LOGE_NODE(right
,
2811 "Invalid `encoding` attribute in string field class: "
2812 "unknown encoding: encoding=\"%s\"",
2820 _SET(&set
, _STRING_ENCODING_SET
);
2822 _BT_COMP_LOGW_NODE(left
,
2823 "Unknown attribute in string field class: "
2825 left
->u
.unary_expression
.u
.string
);
2829 *string_decl
= ctf_field_class_string_create();
2830 BT_ASSERT(*string_decl
);
2831 (*string_decl
)->encoding
= encoding
;
2835 ctf_field_class_destroy((void *) *string_decl
);
2836 *string_decl
= NULL
;
2841 int visit_field_class_specifier_list(struct ctx
*ctx
,
2842 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
2845 struct ctf_node
*first
, *node
;
2849 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
2850 _BT_COMP_LOGE_NODE(ts_list
,
2851 "Unexpected node type: node-type=%d", ts_list
->type
);
2856 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
2857 struct ctf_node
, siblings
);
2858 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
2859 _BT_COMP_LOGE_NODE(first
,
2860 "Unexpected node type: node-type=%d", first
->type
);
2865 node
= first
->u
.field_class_specifier
.node
;
2867 switch (first
->u
.field_class_specifier
.type
) {
2868 case TYPESPEC_INTEGER
:
2869 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
2876 case TYPESPEC_FLOATING_POINT
:
2877 ret
= visit_floating_point_number_decl(ctx
,
2878 &node
->u
.floating_point
.expressions
, (void *) decl
);
2884 case TYPESPEC_STRING
:
2885 ret
= visit_string_decl(ctx
,
2886 &node
->u
.string
.expressions
, (void *) decl
);
2892 case TYPESPEC_STRUCT
:
2893 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
2894 &node
->u
._struct
.declaration_list
,
2895 node
->u
._struct
.has_body
,
2896 &node
->u
._struct
.min_align
, (void *) decl
);
2902 case TYPESPEC_VARIANT
:
2903 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
2904 node
->u
.variant
.choice
,
2905 &node
->u
.variant
.declaration_list
,
2906 node
->u
.variant
.has_body
, (void *) decl
);
2913 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
2914 node
->u
._enum
.container_field_class
,
2915 &node
->u
._enum
.enumerator_list
,
2916 node
->u
._enum
.has_body
, (void *) decl
);
2924 case TYPESPEC_SHORT
:
2927 case TYPESPEC_FLOAT
:
2928 case TYPESPEC_DOUBLE
:
2929 case TYPESPEC_SIGNED
:
2930 case TYPESPEC_UNSIGNED
:
2932 case TYPESPEC_COMPLEX
:
2933 case TYPESPEC_IMAGINARY
:
2934 case TYPESPEC_CONST
:
2935 case TYPESPEC_ID_TYPE
:
2936 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
2938 _BT_COMP_LOGE_NODE(first
,
2939 "Cannot visit field class specifier: ret=%d",
2946 _BT_COMP_LOGE_NODE(first
,
2947 "Unexpected field class specifier type: node-type=%d",
2948 first
->u
.field_class_specifier
.type
);
2957 ctf_field_class_destroy((void *) *decl
);
2963 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
2964 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
2970 switch (node
->type
) {
2972 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
2973 &node
->u
.field_class_def
.field_class_declarators
);
2975 _BT_COMP_LOGE_NODE(node
,
2976 "Cannot add field class found in event class.");
2980 case NODE_TYPEALIAS
:
2981 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
2982 node
->u
.field_class_alias
.alias
);
2984 _BT_COMP_LOGE_NODE(node
,
2985 "Cannot add field class alias found in event class.");
2989 case NODE_CTF_EXPRESSION
:
2991 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2993 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
2998 if (strcmp(left
, "name") == 0) {
2999 /* This is already known at this stage */
3000 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3001 _BT_COMP_LOGE_DUP_ATTR(node
, "name", "event class");
3006 _SET(set
, _EVENT_NAME_SET
);
3007 } else if (strcmp(left
, "id") == 0) {
3010 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3011 _BT_COMP_LOGE_DUP_ATTR(node
, "id", "event class");
3016 ret
= get_unary_unsigned(ctx
,
3017 &node
->u
.ctf_expression
.right
,
3019 /* Only read "id" if get_unary_unsigned() succeeded. */
3020 if (ret
|| (!ret
&& id
< 0)) {
3021 _BT_COMP_LOGE_NODE(node
,
3022 "Unexpected unary expression for event class's `id` attribute.");
3027 event_class
->id
= id
;
3028 _SET(set
, _EVENT_ID_SET
);
3029 } else if (strcmp(left
, "stream_id") == 0) {
3030 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3031 _BT_COMP_LOGE_DUP_ATTR(node
, "stream_id",
3037 ret
= get_unary_unsigned(ctx
,
3038 &node
->u
.ctf_expression
.right
, stream_id
);
3041 * Only read "stream_id" if get_unary_unsigned()
3045 _BT_COMP_LOGE_NODE(node
,
3046 "Unexpected unary expression for event class's `stream_id` attribute.");
3051 _SET(set
, _EVENT_STREAM_ID_SET
);
3052 } else if (strcmp(left
, "context") == 0) {
3053 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3054 _BT_COMP_LOGE_NODE(node
,
3055 "Duplicate `context` entry in event class.");
3060 ret
= visit_field_class_specifier_list(ctx
,
3061 _BT_LIST_FIRST_ENTRY(
3062 &node
->u
.ctf_expression
.right
,
3063 struct ctf_node
, siblings
),
3064 &event_class
->spec_context_fc
);
3066 _BT_COMP_LOGE_NODE(node
,
3067 "Cannot create event class's context field class.");
3071 BT_ASSERT(event_class
->spec_context_fc
);
3072 _SET(set
, _EVENT_CONTEXT_SET
);
3073 } else if (strcmp(left
, "fields") == 0) {
3074 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3075 _BT_COMP_LOGE_NODE(node
,
3076 "Duplicate `fields` entry in event class.");
3081 ret
= visit_field_class_specifier_list(ctx
,
3082 _BT_LIST_FIRST_ENTRY(
3083 &node
->u
.ctf_expression
.right
,
3084 struct ctf_node
, siblings
),
3085 &event_class
->payload_fc
);
3087 _BT_COMP_LOGE_NODE(node
,
3088 "Cannot create event class's payload field class.");
3092 BT_ASSERT(event_class
->payload_fc
);
3093 _SET(set
, _EVENT_FIELDS_SET
);
3094 } else if (strcmp(left
, "loglevel") == 0) {
3095 uint64_t loglevel_value
;
3096 bool is_log_level_known
= true;
3097 bt_event_class_log_level log_level
= -1;
3099 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3100 _BT_COMP_LOGE_DUP_ATTR(node
, "loglevel",
3106 ret
= get_unary_unsigned(ctx
,
3107 &node
->u
.ctf_expression
.right
, &loglevel_value
);
3109 _BT_COMP_LOGE_NODE(node
,
3110 "Unexpected unary expression for event class's `loglevel` attribute.");
3115 switch (loglevel_value
) {
3117 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3120 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3123 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3126 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3129 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3132 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3135 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3138 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3141 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3144 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3147 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3150 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3153 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3156 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3159 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3162 is_log_level_known
= false;
3163 _BT_COMP_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3164 "log-level=%" PRIu64
, loglevel_value
);
3167 if (is_log_level_known
) {
3168 ctf_event_class_set_log_level(event_class
, log_level
);
3171 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3172 } else if (strcmp(left
, "model.emf.uri") == 0) {
3175 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3176 _BT_COMP_LOGE_DUP_ATTR(node
, "model.emf.uri",
3182 right
= ctf_ast_concatenate_unary_strings(
3183 &node
->u
.ctf_expression
.right
);
3185 _BT_COMP_LOGE_NODE(node
,
3186 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3191 if (strlen(right
) == 0) {
3192 _BT_COMP_LOGW_NODE(node
,
3193 "Not setting event class's EMF URI because it's empty.");
3195 g_string_assign(event_class
->emf_uri
,
3200 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3202 _BT_COMP_LOGW_NODE(node
,
3203 "Unknown attribute in event class: "
3204 "attr-name=\"%s\"", left
);
3226 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3230 struct ctf_node
*iter
;
3231 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3233 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3234 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3238 left
= ctf_ast_concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3240 _BT_COMP_LOGE_NODE(iter
,
3241 "Cannot concatenate unary strings.");
3245 if (strcmp(left
, "name") == 0) {
3246 name
= ctf_ast_concatenate_unary_strings(
3247 &iter
->u
.ctf_expression
.right
);
3249 _BT_COMP_LOGE_NODE(iter
,
3250 "Unexpected unary expression for event class's `name` attribute.");
3271 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3275 struct ctf_node
*iter
;
3276 uint64_t stream_id
= 0;
3277 char *event_name
= NULL
;
3278 struct ctf_event_class
*event_class
= NULL
;
3279 struct ctf_stream_class
*stream_class
= NULL
;
3280 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3281 bool pop_scope
= false;
3283 if (node
->visited
) {
3287 node
->visited
= TRUE
;
3288 event_name
= get_event_decl_name(ctx
, node
);
3290 _BT_COMP_LOGE_NODE(node
,
3291 "Missing `name` attribute in event class.");
3296 event_class
= ctf_event_class_create();
3297 BT_ASSERT(event_class
);
3298 g_string_assign(event_class
->name
, event_name
);
3299 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3302 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3303 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3306 _BT_COMP_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3312 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3314 * Allow missing stream_id if there is only a single
3317 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3319 /* Create implicit stream class if there's none */
3321 stream_class
= ctf_stream_class_create();
3322 BT_ASSERT(stream_class
);
3323 stream_class
->id
= stream_id
;
3324 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3328 /* Single stream class: get its ID */
3329 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3330 stream_id
= stream_class
->id
;
3333 _BT_COMP_LOGE_NODE(node
,
3334 "Missing `stream_id` attribute in event class.");
3340 /* We have the stream ID now; get the stream class if found */
3341 if (!stream_class
) {
3342 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3343 ctx
->ctf_tc
, stream_id
);
3344 if (!stream_class
) {
3345 _BT_COMP_LOGE_NODE(node
,
3346 "Cannot find stream class at this point: "
3347 "id=%" PRId64
, stream_id
);
3353 BT_ASSERT(stream_class
);
3355 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3356 /* Allow only one event without ID per stream */
3357 if (stream_class
->event_classes
->len
!= 0) {
3358 _BT_COMP_LOGE_NODE(node
,
3359 "Missing `id` attribute in event class.");
3365 event_class
->id
= 0;
3368 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3370 _BT_COMP_LOGE_NODE(node
,
3371 "Duplicate event class (same ID) in the same stream class: "
3372 "id=%" PRId64
, event_class
->id
);
3377 ctf_stream_class_append_event_class(stream_class
, event_class
);
3382 ctf_event_class_destroy(event_class
);
3400 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3401 struct ctf_field_class
*fc
)
3403 struct ctf_clock_class
*clock_class_to_map_to
= NULL
;
3404 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3406 uint64_t clock_class_count
;
3412 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3413 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3417 if (int_fc
->mapped_clock_class
) {
3418 /* Already mapped */
3422 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3424 switch (clock_class_count
) {
3427 * No clock class exists in the trace at this point. Create an
3428 * implicit one at 1 GHz, named `default`, and use this clock
3431 clock_class_to_map_to
= ctf_clock_class_create();
3432 BT_ASSERT(clock_class_to_map_to
);
3433 clock_class_to_map_to
->frequency
= UINT64_C(1000000000);
3434 g_string_assign(clock_class_to_map_to
->name
, "default");
3435 BT_ASSERT(ret
== 0);
3436 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3437 clock_class_to_map_to
);
3441 * Only one clock class exists in the trace at this point: use
3444 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3448 * Timestamp field not mapped to a clock class and there's more
3449 * than one clock class in the trace: this is an error.
3451 BT_COMP_LOGE_STR("Timestamp field found with no mapped clock class, "
3452 "but there's more than one clock class in the trace at this point.");
3457 BT_ASSERT(clock_class_to_map_to
);
3458 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3465 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3466 struct ctf_field_class
*root_fc
, const char *field_name
)
3470 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3471 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3477 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3478 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3482 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3483 count
= struct_fc
->members
->len
;
3485 count
= var_fc
->options
->len
;
3488 for (i
= 0; i
< count
; i
++) {
3489 struct ctf_named_field_class
*named_fc
= NULL
;
3491 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3492 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3494 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3495 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3499 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3500 ret
= auto_map_field_to_trace_clock_class(ctx
,
3503 BT_COMP_LOGE("Cannot automatically map field to trace's clock class: "
3504 "field-name=\"%s\"", field_name
);
3509 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3512 BT_COMP_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3513 "field-name=\"%s\", root-field-name=\"%s\"",
3514 field_name
, named_fc
->name
->str
);
3524 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3525 struct ctf_stream_class
*stream_class
, int *set
)
3530 switch (node
->type
) {
3532 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3533 &node
->u
.field_class_def
.field_class_declarators
);
3535 _BT_COMP_LOGE_NODE(node
,
3536 "Cannot add field class found in stream class.");
3540 case NODE_TYPEALIAS
:
3541 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3542 node
->u
.field_class_alias
.alias
);
3544 _BT_COMP_LOGE_NODE(node
,
3545 "Cannot add field class alias found in stream class.");
3549 case NODE_CTF_EXPRESSION
:
3551 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3553 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3558 if (strcmp(left
, "id") == 0) {
3561 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3562 _BT_COMP_LOGE_DUP_ATTR(node
, "id",
3563 "stream declaration");
3568 ret
= get_unary_unsigned(ctx
,
3569 &node
->u
.ctf_expression
.right
,
3572 /* Only read "id" if get_unary_unsigned() succeeded. */
3573 if (ret
|| (!ret
&& id
< 0)) {
3574 _BT_COMP_LOGE_NODE(node
,
3575 "Unexpected unary expression for stream class's `id` attribute.");
3580 if (ctf_trace_class_borrow_stream_class_by_id(
3582 _BT_COMP_LOGE_NODE(node
,
3583 "Duplicate stream class (same ID): id=%" PRId64
,
3589 stream_class
->id
= id
;
3590 _SET(set
, _STREAM_ID_SET
);
3591 } else if (strcmp(left
, "event.header") == 0) {
3592 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3593 _BT_COMP_LOGE_NODE(node
,
3594 "Duplicate `event.header` entry in stream class.");
3599 ret
= visit_field_class_specifier_list(ctx
,
3600 _BT_LIST_FIRST_ENTRY(
3601 &node
->u
.ctf_expression
.right
,
3602 struct ctf_node
, siblings
),
3603 &stream_class
->event_header_fc
);
3605 _BT_COMP_LOGE_NODE(node
,
3606 "Cannot create stream class's event header field class.");
3610 BT_ASSERT(stream_class
->event_header_fc
);
3611 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3612 stream_class
->event_header_fc
, "timestamp");
3614 _BT_COMP_LOGE_NODE(node
,
3615 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3619 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3620 } else if (strcmp(left
, "event.context") == 0) {
3621 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3622 _BT_COMP_LOGE_NODE(node
,
3623 "Duplicate `event.context` entry in stream class.");
3628 ret
= visit_field_class_specifier_list(ctx
,
3629 _BT_LIST_FIRST_ENTRY(
3630 &node
->u
.ctf_expression
.right
,
3631 struct ctf_node
, siblings
),
3632 &stream_class
->event_common_context_fc
);
3634 _BT_COMP_LOGE_NODE(node
,
3635 "Cannot create stream class's event context field class.");
3639 BT_ASSERT(stream_class
->event_common_context_fc
);
3640 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3641 } else if (strcmp(left
, "packet.context") == 0) {
3642 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3643 _BT_COMP_LOGE_NODE(node
,
3644 "Duplicate `packet.context` entry in stream class.");
3649 ret
= visit_field_class_specifier_list(ctx
,
3650 _BT_LIST_FIRST_ENTRY(
3651 &node
->u
.ctf_expression
.right
,
3652 struct ctf_node
, siblings
),
3653 &stream_class
->packet_context_fc
);
3655 _BT_COMP_LOGE_NODE(node
,
3656 "Cannot create stream class's packet context field class.");
3660 BT_ASSERT(stream_class
->packet_context_fc
);
3661 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3662 stream_class
->packet_context_fc
,
3665 _BT_COMP_LOGE_NODE(node
,
3666 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3670 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3671 stream_class
->packet_context_fc
,
3674 _BT_COMP_LOGE_NODE(node
,
3675 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3679 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3681 _BT_COMP_LOGW_NODE(node
,
3682 "Unknown attribute in stream class: "
3683 "attr-name=\"%s\"", left
);
3704 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3708 struct ctf_node
*iter
;
3709 struct ctf_stream_class
*stream_class
= NULL
;
3710 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3712 if (node
->visited
) {
3716 node
->visited
= TRUE
;
3717 stream_class
= ctf_stream_class_create();
3718 BT_ASSERT(stream_class
);
3719 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3721 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3722 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3724 _BT_COMP_LOGE_NODE(iter
,
3725 "Cannot visit stream class's entry: "
3734 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3735 /* Check that packet header has `stream_id` field */
3736 struct ctf_named_field_class
*named_fc
= NULL
;
3738 if (!ctx
->ctf_tc
->packet_header_fc
) {
3739 _BT_COMP_LOGE_NODE(node
,
3740 "Stream class has a `id` attribute, "
3741 "but trace has no packet header field class.");
3745 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3746 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3748 _BT_COMP_LOGE_NODE(node
,
3749 "Stream class has a `id` attribute, "
3750 "but trace's packet header field class has no `stream_id` field.");
3754 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3755 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3756 _BT_COMP_LOGE_NODE(node
,
3757 "Stream class has a `id` attribute, "
3758 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3762 /* Allow only _one_ ID-less stream */
3763 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3764 _BT_COMP_LOGE_NODE(node
,
3765 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3770 /* Automatic ID: 0 */
3771 stream_class
->id
= 0;
3775 * Make sure that this stream class's ID is currently unique in
3778 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3779 stream_class
->id
)) {
3780 _BT_COMP_LOGE_NODE(node
,
3781 "Duplicate stream class (same ID): id=%" PRId64
,
3787 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3788 stream_class
= NULL
;
3792 ctf_stream_class_destroy(stream_class
);
3793 stream_class
= NULL
;
3800 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3806 switch (node
->type
) {
3808 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3809 &node
->u
.field_class_def
.field_class_declarators
);
3811 _BT_COMP_LOGE_NODE(node
,
3812 "Cannot add field class found in trace (`trace` block).");
3816 case NODE_TYPEALIAS
:
3817 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3818 node
->u
.field_class_alias
.alias
);
3820 _BT_COMP_LOGE_NODE(node
,
3821 "Cannot add field class alias found in trace (`trace` block).");
3825 case NODE_CTF_EXPRESSION
:
3827 left
= ctf_ast_concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3829 _BT_COMP_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3834 if (strcmp(left
, "major") == 0) {
3835 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
3836 _BT_COMP_LOGE_DUP_ATTR(node
, "major", "trace");
3841 ret
= get_unary_unsigned(ctx
,
3842 &node
->u
.ctf_expression
.right
, &val
);
3844 _BT_COMP_LOGE_NODE(node
,
3845 "Unexpected unary expression for trace's `major` attribute.");
3851 _BT_COMP_LOGE_NODE(node
,
3852 "Invalid trace's `minor` attribute: expecting 1.");
3856 ctx
->ctf_tc
->major
= val
;
3857 _SET(set
, _TRACE_MAJOR_SET
);
3858 } else if (strcmp(left
, "minor") == 0) {
3859 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
3860 _BT_COMP_LOGE_DUP_ATTR(node
, "minor", "trace");
3865 ret
= get_unary_unsigned(ctx
,
3866 &node
->u
.ctf_expression
.right
, &val
);
3868 _BT_COMP_LOGE_NODE(node
,
3869 "Unexpected unary expression for trace's `minor` attribute.");
3875 _BT_COMP_LOGE_NODE(node
,
3876 "Invalid trace's `minor` attribute: expecting 8.");
3880 ctx
->ctf_tc
->minor
= val
;
3881 _SET(set
, _TRACE_MINOR_SET
);
3882 } else if (strcmp(left
, "uuid") == 0) {
3883 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
3884 _BT_COMP_LOGE_DUP_ATTR(node
, "uuid", "trace");
3889 ret
= get_unary_uuid(ctx
,
3890 &node
->u
.ctf_expression
.right
,
3893 _BT_COMP_LOGE_NODE(node
,
3894 "Invalid trace's `uuid` attribute.");
3898 ctx
->ctf_tc
->is_uuid_set
= true;
3899 _SET(set
, _TRACE_UUID_SET
);
3900 } else if (strcmp(left
, "byte_order") == 0) {
3901 /* Default byte order is already known at this stage */
3902 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
3903 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
3909 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= CTF_BYTE_ORDER_UNKNOWN
);
3910 _SET(set
, _TRACE_BYTE_ORDER_SET
);
3911 } else if (strcmp(left
, "packet.header") == 0) {
3912 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
3913 _BT_COMP_LOGE_NODE(node
,
3914 "Duplicate `packet.header` entry in trace.");
3919 ret
= visit_field_class_specifier_list(ctx
,
3920 _BT_LIST_FIRST_ENTRY(
3921 &node
->u
.ctf_expression
.right
,
3922 struct ctf_node
, siblings
),
3923 &ctx
->ctf_tc
->packet_header_fc
);
3925 _BT_COMP_LOGE_NODE(node
,
3926 "Cannot create trace's packet header field class.");
3930 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
3931 _SET(set
, _TRACE_PACKET_HEADER_SET
);
3933 _BT_COMP_LOGW_NODE(node
,
3934 "Unknown attribute in stream class: "
3935 "attr-name=\"%s\"", left
);
3943 _BT_COMP_LOGE_NODE(node
, "Unknown expression in trace.");
3956 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3960 struct ctf_node
*iter
;
3961 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
3963 if (node
->visited
) {
3967 node
->visited
= TRUE
;
3969 if (ctx
->is_trace_visited
) {
3970 _BT_COMP_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
3975 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3977 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3978 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
3980 _BT_COMP_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
3989 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
3990 _BT_COMP_LOGE_NODE(node
,
3991 "Missing `major` attribute in trace (`trace` block).");
3996 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
3997 _BT_COMP_LOGE_NODE(node
,
3998 "Missing `minor` attribute in trace (`trace` block).");
4003 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4004 _BT_COMP_LOGE_NODE(node
,
4005 "Missing `byte_order` attribute in trace (`trace` block).");
4010 ctx
->is_trace_visited
= true;
4020 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4024 struct ctf_node
*entry_node
;
4025 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4027 if (node
->visited
) {
4031 node
->visited
= TRUE
;
4033 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4034 struct bt_list_head
*right_head
=
4035 &entry_node
->u
.ctf_expression
.right
;
4037 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4038 _BT_COMP_LOGE_NODE(entry_node
,
4039 "Wrong expression in environment entry: "
4040 "node-type=%d", entry_node
->type
);
4045 left
= ctf_ast_concatenate_unary_strings(
4046 &entry_node
->u
.ctf_expression
.left
);
4048 _BT_COMP_LOGE_NODE(entry_node
,
4049 "Cannot get environment entry's name.");
4054 if (is_unary_string(right_head
)) {
4055 char *right
= ctf_ast_concatenate_unary_strings(right_head
);
4058 _BT_COMP_LOGE_NODE(entry_node
,
4059 "Unexpected unary expression for environment entry's value: "
4060 "name=\"%s\"", left
);
4065 if (strcmp(left
, "tracer_name") == 0) {
4066 if (strncmp(right
, "lttng", 5) == 0) {
4067 BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
4068 "tracer-name=\"%s\"",
4070 ctx
->is_lttng
= true;
4074 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4075 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4078 } else if (is_unary_unsigned(right_head
) ||
4079 is_unary_signed(right_head
)) {
4082 if (is_unary_unsigned(right_head
)) {
4083 ret
= get_unary_unsigned(ctx
, right_head
,
4086 ret
= get_unary_signed(right_head
, &v
);
4089 _BT_COMP_LOGE_NODE(entry_node
,
4090 "Unexpected unary expression for environment entry's value: "
4091 "name=\"%s\"", left
);
4096 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4097 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4100 _BT_COMP_LOGW_NODE(entry_node
,
4101 "Environment entry has unknown type: "
4102 "name=\"%s\"", left
);
4118 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4123 struct ctf_node
*node
;
4124 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4126 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4127 if (node
->type
== NODE_CTF_EXPRESSION
) {
4128 struct ctf_node
*right_node
;
4130 left
= ctf_ast_concatenate_unary_strings(
4131 &node
->u
.ctf_expression
.left
);
4133 _BT_COMP_LOGE_NODE(node
,
4134 "Cannot concatenate unary strings.");
4139 if (strcmp(left
, "byte_order") == 0) {
4140 enum ctf_byte_order bo
;
4142 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4143 _BT_COMP_LOGE_DUP_ATTR(node
, "byte_order",
4149 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4150 right_node
= _BT_LIST_FIRST_ENTRY(
4151 &node
->u
.ctf_expression
.right
,
4152 struct ctf_node
, siblings
);
4153 bo
= byte_order_from_unary_expr(ctx
,
4155 if (bo
== CTF_BYTE_ORDER_UNKNOWN
) {
4156 _BT_COMP_LOGE_NODE(node
,
4157 "Invalid `byte_order` attribute in trace (`trace` block): "
4158 "expecting `le`, `be`, or `network`.");
4161 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4162 _BT_COMP_LOGE_NODE(node
,
4163 "Invalid `byte_order` attribute in trace (`trace` block): "
4164 "cannot be set to `native` here.");
4169 ctx
->ctf_tc
->default_byte_order
= bo
;
4177 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4178 _BT_COMP_LOGE_NODE(trace_node
,
4179 "Missing `byte_order` attribute in trace (`trace` block).");
4192 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4193 struct ctf_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4194 uint64_t *offset_cycles
)
4199 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4200 _BT_COMP_LOGE_NODE(entry_node
,
4201 "Unexpected node type: node-type=%d",
4207 left
= ctf_ast_concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4209 _BT_COMP_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4214 if (strcmp(left
, "name") == 0) {
4217 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4218 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4223 right
= ctf_ast_concatenate_unary_strings(
4224 &entry_node
->u
.ctf_expression
.right
);
4226 _BT_COMP_LOGE_NODE(entry_node
,
4227 "Unexpected unary expression for clock class's `name` attribute.");
4232 g_string_assign(clock
->name
, right
);
4234 _SET(set
, _CLOCK_NAME_SET
);
4235 } else if (strcmp(left
, "uuid") == 0) {
4238 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4239 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4244 ret
= get_unary_uuid(ctx
, &entry_node
->u
.ctf_expression
.right
,
4247 _BT_COMP_LOGE_NODE(entry_node
,
4248 "Invalid clock class's `uuid` attribute.");
4252 clock
->has_uuid
= true;
4253 bt_uuid_copy(clock
->uuid
, uuid
);
4254 _SET(set
, _CLOCK_UUID_SET
);
4255 } else if (strcmp(left
, "description") == 0) {
4258 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4259 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "description",
4265 right
= ctf_ast_concatenate_unary_strings(
4266 &entry_node
->u
.ctf_expression
.right
);
4268 _BT_COMP_LOGE_NODE(entry_node
,
4269 "Unexpected unary expression for clock class's `description` attribute.");
4274 g_string_assign(clock
->description
, right
);
4276 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4277 } else if (strcmp(left
, "freq") == 0) {
4278 uint64_t freq
= UINT64_C(-1);
4280 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4281 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4286 ret
= get_unary_unsigned(ctx
,
4287 &entry_node
->u
.ctf_expression
.right
, &freq
);
4289 _BT_COMP_LOGE_NODE(entry_node
,
4290 "Unexpected unary expression for clock class's `freq` attribute.");
4295 if (freq
== UINT64_C(-1) || freq
== 0) {
4296 _BT_COMP_LOGE_NODE(entry_node
,
4297 "Invalid clock class frequency: freq=%" PRIu64
,
4303 clock
->frequency
= freq
;
4304 _SET(set
, _CLOCK_FREQ_SET
);
4305 } else if (strcmp(left
, "precision") == 0) {
4308 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4309 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "precision",
4315 ret
= get_unary_unsigned(ctx
,
4316 &entry_node
->u
.ctf_expression
.right
, &precision
);
4318 _BT_COMP_LOGE_NODE(entry_node
,
4319 "Unexpected unary expression for clock class's `precision` attribute.");
4324 clock
->precision
= precision
;
4325 _SET(set
, _CLOCK_PRECISION_SET
);
4326 } else if (strcmp(left
, "offset_s") == 0) {
4327 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4328 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset_s",
4334 ret
= get_unary_signed(
4335 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4337 _BT_COMP_LOGE_NODE(entry_node
,
4338 "Unexpected unary expression for clock class's `offset_s` attribute.");
4343 _SET(set
, _CLOCK_OFFSET_S_SET
);
4344 } else if (strcmp(left
, "offset") == 0) {
4345 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4346 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4351 ret
= get_unary_unsigned(ctx
,
4352 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4354 _BT_COMP_LOGE_NODE(entry_node
,
4355 "Unexpected unary expression for clock class's `offset` attribute.");
4360 _SET(set
, _CLOCK_OFFSET_SET
);
4361 } else if (strcmp(left
, "absolute") == 0) {
4362 struct ctf_node
*right
;
4364 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4365 _BT_COMP_LOGE_DUP_ATTR(entry_node
, "absolute",
4371 right
= _BT_LIST_FIRST_ENTRY(
4372 &entry_node
->u
.ctf_expression
.right
,
4373 struct ctf_node
, siblings
);
4374 ret
= get_boolean(ctx
, right
);
4376 _BT_COMP_LOGE_NODE(entry_node
,
4377 "Unexpected unary expression for clock class's `absolute` attribute.");
4382 clock
->is_absolute
= ret
;
4383 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4385 _BT_COMP_LOGW_NODE(entry_node
,
4386 "Unknown attribute in clock class: attr-name=\"%s\"",
4400 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4405 if (frequency
== UINT64_C(1000000000)) {
4408 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4415 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4416 uint64_t *offset_cycles
, uint64_t freq
)
4418 if (*offset_cycles
>= freq
) {
4419 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4421 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4422 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4427 void apply_clock_class_offset(struct ctx
*ctx
,
4428 struct ctf_clock_class
*clock
)
4431 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4432 uint64_t offset_ns_to_apply
;
4433 int64_t cur_offset_s
;
4434 uint64_t cur_offset_cycles
;
4436 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4437 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4441 /* Transfer nanoseconds to seconds as much as possible */
4442 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4443 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4444 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4445 const int64_t extra_s
= -abs_extra_s
;
4446 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4447 (extra_s
* INT64_C(1000000000));
4449 BT_ASSERT(offset_ns
> 0);
4450 offset_ns_to_apply
= (uint64_t) offset_ns
;
4451 offset_s_to_apply
+= extra_s
;
4453 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4454 INT64_C(1000000000);
4455 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4456 (extra_s
* INT64_C(1000000000));
4458 BT_ASSERT(offset_ns
>= 0);
4459 offset_ns_to_apply
= (uint64_t) offset_ns
;
4460 offset_s_to_apply
+= extra_s
;
4463 freq
= clock
->frequency
;
4464 cur_offset_s
= clock
->offset_seconds
;
4465 cur_offset_cycles
= clock
->offset_cycles
;
4468 cur_offset_s
+= offset_s_to_apply
;
4469 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4472 * Recalibrate offsets because the part in cycles can be greater
4473 * than the frequency at this point.
4475 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4477 /* Set final offsets */
4478 clock
->offset_seconds
= cur_offset_s
;
4479 clock
->offset_cycles
= cur_offset_cycles
;
4486 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4490 struct ctf_clock_class
*clock
;
4491 struct ctf_node
*entry_node
;
4492 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4493 const char *clock_class_name
;
4494 int64_t offset_seconds
= 0;
4495 uint64_t offset_cycles
= 0;
4498 if (clock_node
->visited
) {
4502 clock_node
->visited
= TRUE
;
4504 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4505 clock
= ctf_clock_class_create();
4507 _BT_COMP_LOGE_NODE(clock_node
,
4508 "Cannot create default clock class.");
4513 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4514 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4515 &offset_seconds
, &offset_cycles
);
4517 _BT_COMP_LOGE_NODE(entry_node
,
4518 "Cannot visit clock class's entry: ret=%d",
4524 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4525 _BT_COMP_LOGE_NODE(clock_node
,
4526 "Missing `name` attribute in clock class.");
4531 clock_class_name
= clock
->name
->str
;
4532 BT_ASSERT(clock_class_name
);
4533 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4535 * Old versions of LTTng forgot to set its clock class
4536 * as absolute, even if it is. This is important because
4537 * it's a condition to be able to sort messages
4538 * from different sources.
4540 clock
->is_absolute
= true;
4544 * Adjust offsets so that the part in cycles is less than the
4545 * frequency (move to the part in seconds).
4547 freq
= clock
->frequency
;
4548 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4549 BT_ASSERT(offset_cycles
< clock
->frequency
);
4550 clock
->offset_seconds
= offset_seconds
;
4551 clock
->offset_cycles
= offset_cycles
;
4552 apply_clock_class_offset(ctx
, clock
);
4553 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4558 ctf_clock_class_destroy(clock
);
4565 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4569 if (root_decl_node
->visited
) {
4573 root_decl_node
->visited
= TRUE
;
4575 switch (root_decl_node
->type
) {
4577 ret
= visit_field_class_def(ctx
,
4578 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4579 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4581 _BT_COMP_LOGE_NODE(root_decl_node
,
4582 "Cannot add field class found in root scope.");
4586 case NODE_TYPEALIAS
:
4587 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4588 root_decl_node
->u
.field_class_alias
.alias
);
4590 _BT_COMP_LOGE_NODE(root_decl_node
,
4591 "Cannot add field class alias found in root scope.");
4595 case NODE_TYPE_SPECIFIER_LIST
:
4597 struct ctf_field_class
*decl
= NULL
;
4600 * Just add the field class specifier to the root
4601 * declaration scope. Put local reference.
4603 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4605 _BT_COMP_LOGE_NODE(root_decl_node
,
4606 "Cannot visit root scope's field class: "
4612 ctf_field_class_destroy(decl
);
4617 _BT_COMP_LOGE_NODE(root_decl_node
,
4618 "Unexpected node type: node-type=%d",
4619 root_decl_node
->type
);
4629 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4630 const struct ctf_metadata_decoder_config
*decoder_config
)
4632 struct ctx
*ctx
= NULL
;
4634 /* Create visitor's context */
4635 ctx
= ctx_create(decoder_config
);
4637 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR
, decoder_config
->log_level
,
4638 decoder_config
->self_comp
,
4639 "Cannot create visitor's context.");
4650 return (void *) ctx
;
4654 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4656 ctx_destroy((void *) visitor
);
4660 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4661 struct ctf_visitor_generate_ir
*visitor
)
4663 struct ctx
*ctx
= (void *) visitor
;
4667 if (ctx
->trace_class
) {
4668 bt_trace_class_get_ref(ctx
->trace_class
);
4671 return ctx
->trace_class
;
4675 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4676 struct ctf_visitor_generate_ir
*visitor
)
4678 struct ctx
*ctx
= (void *) visitor
;
4681 BT_ASSERT(ctx
->ctf_tc
);
4686 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4687 struct ctf_node
*node
)
4690 struct ctx
*ctx
= (void *) visitor
;
4692 BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4694 switch (node
->type
) {
4697 struct ctf_node
*iter
;
4698 bool got_trace_decl
= false;
4701 * The first thing we need is the native byte order of
4702 * the trace block, because early class aliases can have
4703 * a `byte_order` attribute set to `native`. If we don't
4704 * have the native byte order yet, and we don't have any
4705 * trace block yet, then fail with EINCOMPLETE.
4707 if (ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_UNKNOWN
) {
4708 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4709 if (got_trace_decl
) {
4710 _BT_COMP_LOGE_NODE(node
,
4711 "Duplicate trace (`trace` block).");
4716 ret
= set_trace_byte_order(ctx
, iter
);
4718 _BT_COMP_LOGE_NODE(node
,
4719 "Cannot set trace's native byte order: "
4724 got_trace_decl
= true;
4727 if (!got_trace_decl
) {
4728 BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4734 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4735 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4736 BT_ASSERT(ctx
->current_scope
&&
4737 !ctx
->current_scope
->parent_scope
);
4740 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4741 ret
= visit_env(ctx
, iter
);
4743 _BT_COMP_LOGE_NODE(iter
,
4744 "Cannot visit trace's environment (`env` block) entry: "
4750 BT_ASSERT(ctx
->current_scope
&&
4751 !ctx
->current_scope
->parent_scope
);
4754 * Visit clock blocks.
4756 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4757 ret
= visit_clock_decl(ctx
, iter
);
4759 _BT_COMP_LOGE_NODE(iter
,
4760 "Cannot visit clock class: ret=%d",
4766 BT_ASSERT(ctx
->current_scope
&&
4767 !ctx
->current_scope
->parent_scope
);
4770 * Visit root declarations next, as they can be used by any
4773 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4775 ret
= visit_root_decl(ctx
, iter
);
4777 _BT_COMP_LOGE_NODE(iter
,
4778 "Cannot visit root entry: ret=%d",
4784 BT_ASSERT(ctx
->current_scope
&&
4785 !ctx
->current_scope
->parent_scope
);
4787 /* Callsite blocks are not supported */
4788 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4789 _BT_COMP_LOGW_NODE(iter
,
4790 "\"callsite\" blocks are not supported as of this version.");
4793 BT_ASSERT(ctx
->current_scope
&&
4794 !ctx
->current_scope
->parent_scope
);
4797 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4798 ret
= visit_trace_decl(ctx
, iter
);
4800 _BT_COMP_LOGE_NODE(iter
,
4801 "Cannot visit trace (`trace` block): "
4807 BT_ASSERT(ctx
->current_scope
&&
4808 !ctx
->current_scope
->parent_scope
);
4811 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4812 ret
= visit_stream_decl(ctx
, iter
);
4814 _BT_COMP_LOGE_NODE(iter
,
4815 "Cannot visit stream class: ret=%d",
4821 BT_ASSERT(ctx
->current_scope
&&
4822 !ctx
->current_scope
->parent_scope
);
4825 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4826 ret
= visit_event_decl(ctx
, iter
);
4828 _BT_COMP_LOGE_NODE(iter
,
4829 "Cannot visit event class: ret=%d",
4835 BT_ASSERT(ctx
->current_scope
&&
4836 !ctx
->current_scope
->parent_scope
);
4840 _BT_COMP_LOGE_NODE(node
,
4841 "Unexpected node type: node-type=%d",
4847 /* Update default clock classes */
4848 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
,
4855 /* Update trace class meanings */
4856 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
4862 /* Update stream class configuration */
4863 ret
= ctf_trace_class_update_stream_class_config(ctx
->ctf_tc
);
4869 /* Update text arrays and sequences */
4870 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
4876 /* Resolve sequence lengths and variant tags */
4877 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
, &ctx
->log_cfg
);
4883 if (ctx
->trace_class
) {
4885 * Update "in IR" for field classes.
4887 * If we have no IR trace class, then we'll have no way
4888 * to create IR fields anyway, so we leave all the
4889 * `in_ir` members false.
4891 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
4898 /* Update saved value indexes */
4899 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
4905 /* Validate what we have so far */
4906 ret
= ctf_trace_class_validate(ctx
->ctf_tc
, &ctx
->log_cfg
);
4913 * If there are fields which are not related to the CTF format
4914 * itself in the packet header and in event header field
4915 * classes, warn about it because they are never translated.
4917 ctf_trace_class_warn_meaningless_header_fields(ctx
->ctf_tc
,
4920 if (ctx
->trace_class
) {
4921 /* Copy new CTF metadata -> new IR metadata */
4922 ret
= ctf_trace_class_translate(ctx
->log_cfg
.self_comp
,
4923 ctx
->trace_class
, ctx
->ctf_tc
);