2 * ctf-visitor-generate-ir.c
4 * Common Trace Format metadata visitor (generates CTF IR objects).
6 * Based on older ctf-visitor-generate-io-struct.c.
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2018 - Philippe Proulx <philippe.proulx@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
39 #include "common/assert.h"
43 #include "common/common.h"
44 #include "compat/uuid.h"
45 #include "compat/endian.h"
46 #include <babeltrace2/babeltrace.h>
53 #include "ctf-meta-visitors.h"
55 /* Bit value (left shift) */
56 #define _BV(_val) (1 << (_val))
58 /* Bit is set in a set of bits */
59 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
61 /* Set bit in a set of bits */
62 #define _SET(_set, _mask) (*(_set) |= (_mask))
64 /* Try to push scope, or go to the `error` label */
65 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
67 ret = ctx_push_scope(ctx); \
69 BT_LOGE_STR("Cannot push scope."); \
74 /* Bits for verifying existing attributes in various declarations */
76 _CLOCK_NAME_SET
= _BV(0),
77 _CLOCK_UUID_SET
= _BV(1),
78 _CLOCK_FREQ_SET
= _BV(2),
79 _CLOCK_PRECISION_SET
= _BV(3),
80 _CLOCK_OFFSET_S_SET
= _BV(4),
81 _CLOCK_OFFSET_SET
= _BV(5),
82 _CLOCK_ABSOLUTE_SET
= _BV(6),
83 _CLOCK_DESCRIPTION_SET
= _BV(7),
87 _INTEGER_ALIGN_SET
= _BV(0),
88 _INTEGER_SIZE_SET
= _BV(1),
89 _INTEGER_BASE_SET
= _BV(2),
90 _INTEGER_ENCODING_SET
= _BV(3),
91 _INTEGER_BYTE_ORDER_SET
= _BV(4),
92 _INTEGER_SIGNED_SET
= _BV(5),
93 _INTEGER_MAP_SET
= _BV(6),
97 _FLOAT_ALIGN_SET
= _BV(0),
98 _FLOAT_MANT_DIG_SET
= _BV(1),
99 _FLOAT_EXP_DIG_SET
= _BV(2),
100 _FLOAT_BYTE_ORDER_SET
= _BV(3),
104 _STRING_ENCODING_SET
= _BV(0),
108 _TRACE_MINOR_SET
= _BV(0),
109 _TRACE_MAJOR_SET
= _BV(1),
110 _TRACE_BYTE_ORDER_SET
= _BV(2),
111 _TRACE_UUID_SET
= _BV(3),
112 _TRACE_PACKET_HEADER_SET
= _BV(4),
116 _STREAM_ID_SET
= _BV(0),
117 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
118 _STREAM_EVENT_HEADER_SET
= _BV(2),
119 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
123 _EVENT_NAME_SET
= _BV(0),
124 _EVENT_ID_SET
= _BV(1),
125 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
126 _EVENT_STREAM_ID_SET
= _BV(3),
127 _EVENT_LOG_LEVEL_SET
= _BV(4),
128 _EVENT_CONTEXT_SET
= _BV(5),
129 _EVENT_FIELDS_SET
= _BV(6),
137 LOG_LEVEL_WARNING
= 4,
138 LOG_LEVEL_NOTICE
= 5,
140 LOG_LEVEL_DEBUG_SYSTEM
= 7,
141 LOG_LEVEL_DEBUG_PROGRAM
= 8,
142 LOG_LEVEL_DEBUG_PROCESS
= 9,
143 LOG_LEVEL_DEBUG_MODULE
= 10,
144 LOG_LEVEL_DEBUG_UNIT
= 11,
145 LOG_LEVEL_DEBUG_FUNCTION
= 12,
146 LOG_LEVEL_DEBUG_LINE
= 13,
147 LOG_LEVEL_DEBUG
= 14,
151 /* Prefixes of class aliases */
152 #define _PREFIX_ALIAS 'a'
153 #define _PREFIX_ENUM 'e'
154 #define _PREFIX_STRUCT 's'
155 #define _PREFIX_VARIANT 'v'
157 /* First entry in a BT list */
158 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
159 bt_list_entry((_ptr)->next, _class, _member)
161 #define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
162 _BT_LOGE_LINENO((_node)->lineno, \
163 "Duplicate attribute in %s: attr-name=\"%s\"", \
166 #define _BT_LOGE_NODE(_node, _msg, args...) \
167 _BT_LOGE_LINENO((_node)->lineno, _msg, ## args)
169 #define _BT_LOGW_NODE(_node, _msg, args...) \
170 _BT_LOGW_LINENO((_node)->lineno, _msg, ## args)
172 #define _BT_LOGV_NODE(_node, _msg, args...) \
173 _BT_LOGV_LINENO((_node)->lineno, _msg, ## args)
176 * Declaration scope of a visitor context. This represents a TSDL
177 * lexical scope, so that aliases and named structures, variants,
178 * and enumerations may be registered and looked up hierarchically.
180 struct ctx_decl_scope
{
182 * Alias name to field class.
184 * GQuark -> struct ctf_field_class * (owned by this)
186 GHashTable
*decl_map
;
188 /* Parent scope; NULL if this is the root declaration scope */
189 struct ctx_decl_scope
*parent_scope
;
193 * Visitor context (private).
196 bt_self_component_source
*self_comp
;
197 /* Trace IR trace class being filled (owned by this) */
198 bt_trace_class
*trace_class
;
200 /* CTF meta trace being filled (owned by this) */
201 struct ctf_trace_class
*ctf_tc
;
203 /* Current declaration scope (top of the stack) (owned by this) */
204 struct ctx_decl_scope
*current_scope
;
206 /* True if trace declaration is visited */
207 bool is_trace_visited
;
209 /* True if this is an LTTng trace */
212 /* Config passed by the user */
213 struct ctf_metadata_decoder_config decoder_config
;
219 struct ctf_visitor_generate_ir
;
222 * Creates a new declaration scope.
224 * @param par_scope Parent scope (NULL if creating a root scope)
225 * @returns New declaration scope, or NULL on error
228 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx_decl_scope
*par_scope
)
230 struct ctx_decl_scope
*scope
;
232 scope
= g_new(struct ctx_decl_scope
, 1);
234 BT_LOGE_STR("Failed to allocate one declaration scope.");
238 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
239 NULL
, (GDestroyNotify
) ctf_field_class_destroy
);
240 scope
->parent_scope
= par_scope
;
247 * Destroys a declaration scope.
249 * This function does not destroy the parent scope.
251 * @param scope Scope to destroy
254 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
260 g_hash_table_destroy(scope
->decl_map
);
268 * Returns the GQuark of a prefixed alias.
270 * @param prefix Prefix character
272 * @returns Associated GQuark, or 0 on error
275 GQuark
get_prefixed_named_quark(char prefix
, const char *name
)
281 /* Prefix character + original string + '\0' */
282 char *prname
= g_new(char, strlen(name
) + 2);
284 BT_LOGE_STR("Failed to allocate a string.");
288 sprintf(prname
, "%c%s", prefix
, name
);
289 qname
= g_quark_from_string(prname
);
297 * Looks up a prefixed class alias within a declaration scope.
299 * @param scope Declaration scope
300 * @param prefix Prefix character
301 * @param name Alias name
302 * @param levels Number of levels to dig into (-1 means infinite)
303 * @param copy True to return a copy
304 * @returns Declaration (owned by caller if \p copy is true),
305 * or NULL if not found
308 struct ctf_field_class
*ctx_decl_scope_lookup_prefix_alias(
309 struct ctx_decl_scope
*scope
, char prefix
, const char *name
,
310 int levels
, bool copy
)
314 struct ctf_field_class
*decl
= NULL
;
315 struct ctx_decl_scope
*cur_scope
= scope
;
319 qname
= get_prefixed_named_quark(prefix
, name
);
328 while (cur_scope
&& cur_levels
< levels
) {
329 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
330 (gconstpointer
) GUINT_TO_POINTER(qname
));
332 /* Caller's reference */
334 decl
= ctf_field_class_copy(decl
);
341 cur_scope
= cur_scope
->parent_scope
;
350 * Looks up a class alias within a declaration scope.
352 * @param scope Declaration scope
353 * @param name Alias name
354 * @param levels Number of levels to dig into (-1 means infinite)
355 * @param copy True to return a copy
356 * @returns Declaration (owned by caller if \p copy is true),
357 * or NULL if not found
360 struct ctf_field_class
*ctx_decl_scope_lookup_alias(
361 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
364 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ALIAS
,
369 * Looks up an enumeration within a declaration scope.
371 * @param scope Declaration scope
372 * @param name Enumeration name
373 * @param levels Number of levels to dig into (-1 means infinite)
374 * @param copy True to return a copy
375 * @returns Declaration (owned by caller if \p copy is true),
376 * or NULL if not found
379 struct ctf_field_class_enum
*ctx_decl_scope_lookup_enum(
380 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
383 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ENUM
,
388 * Looks up a structure within a declaration scope.
390 * @param scope Declaration scope
391 * @param name Structure name
392 * @param levels Number of levels to dig into (-1 means infinite)
393 * @param copy True to return a copy
394 * @returns Declaration (owned by caller if \p copy is true),
395 * or NULL if not found
398 struct ctf_field_class_struct
*ctx_decl_scope_lookup_struct(
399 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
402 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
403 _PREFIX_STRUCT
, name
, levels
, copy
);
407 * Looks up a variant within a declaration scope.
409 * @param scope Declaration scope
410 * @param name Variant name
411 * @param levels Number of levels to dig into (-1 means infinite)
412 * @param copy True to return a copy
413 * @returns Declaration (owned by caller if \p copy is true),
414 * or NULL if not found
417 struct ctf_field_class_variant
*ctx_decl_scope_lookup_variant(
418 struct ctx_decl_scope
*scope
, const char *name
, int levels
,
421 return (void *) ctx_decl_scope_lookup_prefix_alias(scope
,
422 _PREFIX_VARIANT
, name
, levels
, copy
);
426 * Registers a prefixed class alias within a declaration scope.
428 * @param scope Declaration scope
429 * @param prefix Prefix character
430 * @param name Alias name (non-NULL)
431 * @param decl Field class to register (copied)
432 * @returns 0 if registration went okay, negative value otherwise
435 int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope
*scope
,
436 char prefix
, const char *name
, struct ctf_field_class
*decl
)
444 qname
= get_prefixed_named_quark(prefix
, name
);
450 /* Make sure alias does not exist in local scope */
451 if (ctx_decl_scope_lookup_prefix_alias(scope
, prefix
, name
, 1,
457 decl
= ctf_field_class_copy(decl
);
459 g_hash_table_insert(scope
->decl_map
, GUINT_TO_POINTER(qname
), decl
);
466 * Registers a class alias within a declaration scope.
468 * @param scope Declaration scope
469 * @param name Alias name (non-NULL)
470 * @param decl Field class to register (copied)
471 * @returns 0 if registration went okay, negative value otherwise
474 int ctx_decl_scope_register_alias(struct ctx_decl_scope
*scope
,
475 const char *name
, struct ctf_field_class
*decl
)
477 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ALIAS
,
478 name
, (void *) decl
);
482 * Registers an enumeration declaration within a declaration scope.
484 * @param scope Declaration scope
485 * @param name Enumeration name (non-NULL)
486 * @param decl Enumeration field class to register (copied)
487 * @returns 0 if registration went okay, negative value otherwise
490 int ctx_decl_scope_register_enum(struct ctx_decl_scope
*scope
,
491 const char *name
, struct ctf_field_class_enum
*decl
)
493 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ENUM
,
494 name
, (void *) decl
);
498 * Registers a structure declaration within a declaration scope.
500 * @param scope Declaration scope
501 * @param name Structure name (non-NULL)
502 * @param decl Structure field class to register (copied)
503 * @returns 0 if registration went okay, negative value otherwise
506 int ctx_decl_scope_register_struct(struct ctx_decl_scope
*scope
,
507 const char *name
, struct ctf_field_class_struct
*decl
)
509 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_STRUCT
,
510 name
, (void *) decl
);
514 * Registers a variant declaration within a declaration scope.
516 * @param scope Declaration scope
517 * @param name Variant name (non-NULL)
518 * @param decl Variant field class to register
519 * @returns 0 if registration went okay, negative value otherwise
522 int ctx_decl_scope_register_variant(struct ctx_decl_scope
*scope
,
523 const char *name
, struct ctf_field_class_variant
*decl
)
525 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_VARIANT
,
526 name
, (void *) decl
);
530 * Destroys a visitor context.
532 * @param ctx Visitor context to destroy
535 void ctx_destroy(struct ctx
*ctx
)
537 struct ctx_decl_scope
*scope
;
543 scope
= ctx
->current_scope
;
546 * Destroy all scopes, from current one to the root scope.
549 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
551 ctx_decl_scope_destroy(scope
);
552 scope
= parent_scope
;
555 bt_trace_class_put_ref(ctx
->trace_class
);
558 ctf_trace_class_destroy(ctx
->ctf_tc
);
568 * Creates a new visitor context.
570 * @param trace Associated trace
571 * @returns New visitor context, or NULL on error
574 struct ctx
*ctx_create(bt_self_component_source
*self_comp
,
575 const struct ctf_metadata_decoder_config
*decoder_config
)
577 struct ctx
*ctx
= NULL
;
579 BT_ASSERT(decoder_config
);
581 ctx
= g_new0(struct ctx
, 1);
583 BT_LOGE_STR("Failed to allocate one visitor context.");
588 ctx
->trace_class
= bt_trace_class_create(
589 bt_self_component_source_as_self_component(self_comp
));
590 if (!ctx
->trace_class
) {
591 BT_LOGE_STR("Cannot create empty trace class.");
594 ctx
->self_comp
= self_comp
;
597 ctx
->ctf_tc
= ctf_trace_class_create();
599 BT_LOGE_STR("Cannot create CTF trace class.");
603 /* Root declaration scope */
604 ctx
->current_scope
= ctx_decl_scope_create(NULL
);
605 if (!ctx
->current_scope
) {
606 BT_LOGE_STR("Cannot create declaration scope.");
610 ctx
->decoder_config
= *decoder_config
;
622 * Pushes a new declaration scope on top of a visitor context's
623 * declaration scope stack.
625 * @param ctx Visitor context
626 * @returns 0 on success, or a negative value on error
629 int ctx_push_scope(struct ctx
*ctx
)
632 struct ctx_decl_scope
*new_scope
;
635 new_scope
= ctx_decl_scope_create(ctx
->current_scope
);
637 BT_LOGE_STR("Cannot create declaration scope.");
642 ctx
->current_scope
= new_scope
;
649 void ctx_pop_scope(struct ctx
*ctx
)
651 struct ctx_decl_scope
*parent_scope
= NULL
;
655 if (!ctx
->current_scope
) {
659 parent_scope
= ctx
->current_scope
->parent_scope
;
660 ctx_decl_scope_destroy(ctx
->current_scope
);
661 ctx
->current_scope
= parent_scope
;
668 int visit_field_class_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
669 struct ctf_field_class
**decl
);
672 char *remove_underscores_from_field_ref(const char *field_ref
)
678 UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
,
679 UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
,
680 } state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
682 BT_ASSERT(field_ref
);
683 ret
= calloc(strlen(field_ref
) + 1, 1);
685 BT_LOGE("Failed to allocate a string: size=%zu",
686 strlen(field_ref
) + 1);
693 while (*in_ch
!= '\0') {
697 /* Remove whitespace */
701 if (state
== UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
) {
703 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
709 state
= UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE
;
712 state
= UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE
;
727 int is_unary_string(struct bt_list_head
*head
)
730 struct ctf_node
*node
;
732 bt_list_for_each_entry(node
, head
, siblings
) {
733 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
737 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
746 char *concatenate_unary_strings(struct bt_list_head
*head
)
750 struct ctf_node
*node
;
752 str
= g_string_new(NULL
);
755 bt_list_for_each_entry(node
, head
, siblings
) {
759 node
->type
!= NODE_UNARY_EXPRESSION
||
760 node
->u
.unary_expression
.type
!= UNARY_STRING
||
763 node
->u
.unary_expression
.link
!=
771 switch (node
->u
.unary_expression
.link
) {
773 g_string_append(str
, ".");
775 case UNARY_ARROWLINK
:
776 g_string_append(str
, "->");
778 case UNARY_DOTDOTDOT
:
779 g_string_append(str
, "...");
785 src_string
= node
->u
.unary_expression
.u
.string
;
786 g_string_append(str
, src_string
);
790 /* Destroys the container, returns the underlying string */
791 return g_string_free(str
, FALSE
);
794 /* This always returns NULL */
795 return g_string_free(str
, TRUE
);
799 const char *get_map_clock_name_value(struct bt_list_head
*head
)
802 struct ctf_node
*node
;
803 const char *name
= NULL
;
805 bt_list_for_each_entry(node
, head
, siblings
) {
807 int uexpr_type
= node
->u
.unary_expression
.type
;
808 int uexpr_link
= node
->u
.unary_expression
.link
;
809 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
810 uexpr_type
!= UNARY_STRING
||
811 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
816 /* Needs to be chained with . */
817 switch (node
->u
.unary_expression
.link
) {
820 case UNARY_ARROWLINK
:
821 case UNARY_DOTDOTDOT
:
827 src_string
= node
->u
.unary_expression
.u
.string
;
831 if (strcmp("clock", src_string
)) {
839 if (strcmp("value", src_string
)) {
844 /* Extra identifier, unknown */
858 int is_unary_unsigned(struct bt_list_head
*head
)
861 struct ctf_node
*node
;
863 bt_list_for_each_entry(node
, head
, siblings
) {
864 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
868 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
877 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
881 struct ctf_node
*node
;
885 if (bt_list_empty(head
)) {
890 bt_list_for_each_entry(node
, head
, siblings
) {
891 int uexpr_type
= node
->u
.unary_expression
.type
;
892 int uexpr_link
= node
->u
.unary_expression
.link
;
893 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
894 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
895 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
897 _BT_LOGE_NODE(node
, "Invalid constant unsigned integer.");
902 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
911 int is_unary_signed(struct bt_list_head
*head
)
914 struct ctf_node
*node
;
916 bt_list_for_each_entry(node
, head
, siblings
) {
917 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
921 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
930 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
934 struct ctf_node
*node
;
936 bt_list_for_each_entry(node
, head
, siblings
) {
937 int uexpr_type
= node
->u
.unary_expression
.type
;
938 int uexpr_link
= node
->u
.unary_expression
.link
;
939 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
940 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
941 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
942 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
948 switch (uexpr_type
) {
949 case UNARY_UNSIGNED_CONSTANT
:
951 node
->u
.unary_expression
.u
.unsigned_constant
;
953 case UNARY_SIGNED_CONSTANT
:
954 *value
= node
->u
.unary_expression
.u
.signed_constant
;
969 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
973 struct ctf_node
*node
;
975 bt_list_for_each_entry(node
, head
, siblings
) {
976 int uexpr_type
= node
->u
.unary_expression
.type
;
977 int uexpr_link
= node
->u
.unary_expression
.link
;
978 const char *src_string
;
980 if (node
->type
!= NODE_UNARY_EXPRESSION
||
981 uexpr_type
!= UNARY_STRING
||
982 uexpr_link
!= UNARY_LINK_UNKNOWN
||
988 src_string
= node
->u
.unary_expression
.u
.string
;
989 ret
= bt_uuid_parse(src_string
, uuid
);
992 "Cannot parse UUID: uuid=\"%s\"", src_string
);
1002 int get_boolean(struct ctf_node
*unary_expr
)
1006 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
1007 _BT_LOGE_NODE(unary_expr
,
1008 "Expecting unary expression: node-type=%d",
1014 switch (unary_expr
->u
.unary_expression
.type
) {
1015 case UNARY_UNSIGNED_CONSTANT
:
1016 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
1018 case UNARY_SIGNED_CONSTANT
:
1019 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
1023 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
1025 if (!strcmp(str
, "true") || !strcmp(str
, "TRUE")) {
1027 } else if (!strcmp(str
, "false") || !strcmp(str
, "FALSE")) {
1030 _BT_LOGE_NODE(unary_expr
,
1031 "Unexpected boolean value: value=\"%s\"", str
);
1038 _BT_LOGE_NODE(unary_expr
,
1039 "Unexpected unary expression type: node-type=%d",
1040 unary_expr
->u
.unary_expression
.type
);
1050 enum ctf_byte_order
byte_order_from_unary_expr(struct ctf_node
*unary_expr
)
1053 enum ctf_byte_order bo
= -1;
1055 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1056 _BT_LOGE_NODE(unary_expr
,
1057 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1061 str
= unary_expr
->u
.unary_expression
.u
.string
;
1063 if (!strcmp(str
, "be") || !strcmp(str
, "network")) {
1064 bo
= CTF_BYTE_ORDER_BIG
;
1065 } else if (!strcmp(str
, "le")) {
1066 bo
= CTF_BYTE_ORDER_LITTLE
;
1067 } else if (!strcmp(str
, "native")) {
1068 bo
= CTF_BYTE_ORDER_DEFAULT
;
1070 _BT_LOGE_NODE(unary_expr
,
1071 "Unexpected \"byte_order\" attribute value: "
1072 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1082 enum ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1083 struct ctf_node
*uexpr
)
1085 enum ctf_byte_order bo
= byte_order_from_unary_expr(uexpr
);
1087 if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
1088 bo
= ctx
->ctf_tc
->default_byte_order
;
1095 int is_align_valid(uint64_t align
)
1097 return (align
!= 0) && !(align
& (align
- UINT64_C(1)));
1101 int get_class_specifier_name(struct ctx
*ctx
, struct ctf_node
*cls_specifier
,
1106 if (cls_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1107 _BT_LOGE_NODE(cls_specifier
,
1108 "Unexpected node type: node-type=%d",
1109 cls_specifier
->type
);
1114 switch (cls_specifier
->u
.field_class_specifier
.type
) {
1116 g_string_append(str
, "void");
1119 g_string_append(str
, "char");
1121 case TYPESPEC_SHORT
:
1122 g_string_append(str
, "short");
1125 g_string_append(str
, "int");
1128 g_string_append(str
, "long");
1130 case TYPESPEC_FLOAT
:
1131 g_string_append(str
, "float");
1133 case TYPESPEC_DOUBLE
:
1134 g_string_append(str
, "double");
1136 case TYPESPEC_SIGNED
:
1137 g_string_append(str
, "signed");
1139 case TYPESPEC_UNSIGNED
:
1140 g_string_append(str
, "unsigned");
1143 g_string_append(str
, "bool");
1145 case TYPESPEC_COMPLEX
:
1146 g_string_append(str
, "_Complex");
1148 case TYPESPEC_IMAGINARY
:
1149 g_string_append(str
, "_Imaginary");
1151 case TYPESPEC_CONST
:
1152 g_string_append(str
, "const");
1154 case TYPESPEC_ID_TYPE
:
1155 if (cls_specifier
->u
.field_class_specifier
.id_type
) {
1156 g_string_append(str
,
1157 cls_specifier
->u
.field_class_specifier
.id_type
);
1160 case TYPESPEC_STRUCT
:
1162 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1164 if (!node
->u
._struct
.name
) {
1165 _BT_LOGE_NODE(node
, "Unexpected empty structure field class name.");
1170 g_string_append(str
, "struct ");
1171 g_string_append(str
, node
->u
._struct
.name
);
1174 case TYPESPEC_VARIANT
:
1176 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1178 if (!node
->u
.variant
.name
) {
1179 _BT_LOGE_NODE(node
, "Unexpected empty variant field class name.");
1184 g_string_append(str
, "variant ");
1185 g_string_append(str
, node
->u
.variant
.name
);
1190 struct ctf_node
*node
= cls_specifier
->u
.field_class_specifier
.node
;
1192 if (!node
->u
._enum
.enum_id
) {
1194 "Unexpected empty enumeration field class (`enum`) name.");
1199 g_string_append(str
, "enum ");
1200 g_string_append(str
, node
->u
._enum
.enum_id
);
1203 case TYPESPEC_FLOATING_POINT
:
1204 case TYPESPEC_INTEGER
:
1205 case TYPESPEC_STRING
:
1207 _BT_LOGE_NODE(cls_specifier
->u
.field_class_specifier
.node
,
1208 "Unexpected field class specifier type: %d",
1209 cls_specifier
->u
.field_class_specifier
.type
);
1219 int get_class_specifier_list_name(struct ctx
*ctx
,
1220 struct ctf_node
*cls_specifier_list
, GString
*str
)
1223 struct ctf_node
*iter
;
1224 int alias_item_nr
= 0;
1225 struct bt_list_head
*head
=
1226 &cls_specifier_list
->u
.field_class_specifier_list
.head
;
1228 bt_list_for_each_entry(iter
, head
, siblings
) {
1229 if (alias_item_nr
!= 0) {
1230 g_string_append(str
, " ");
1234 ret
= get_class_specifier_name(ctx
, iter
, str
);
1245 GQuark
create_class_alias_identifier(struct ctx
*ctx
,
1246 struct ctf_node
*cls_specifier_list
,
1247 struct ctf_node
*node_field_class_declarator
)
1253 struct ctf_node
*iter
;
1254 struct bt_list_head
*pointers
=
1255 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1257 str
= g_string_new("");
1258 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
1260 g_string_free(str
, TRUE
);
1264 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1265 g_string_append(str
, " *");
1267 if (iter
->u
.pointer
.const_qualifier
) {
1268 g_string_append(str
, " const");
1272 str_c
= g_string_free(str
, FALSE
);
1273 qalias
= g_quark_from_string(str_c
);
1281 int visit_field_class_declarator(struct ctx
*ctx
,
1282 struct ctf_node
*cls_specifier_list
,
1283 GQuark
*field_name
, struct ctf_node
*node_field_class_declarator
,
1284 struct ctf_field_class
**field_decl
,
1285 struct ctf_field_class
*nested_decl
)
1288 * During this whole function, nested_decl is always OURS,
1289 * whereas field_decl is an output which we create, but
1290 * belongs to the caller (it is moved).
1295 /* Validate field class declarator node */
1296 if (node_field_class_declarator
) {
1297 if (node_field_class_declarator
->u
.field_class_declarator
.type
==
1299 _BT_LOGE_NODE(node_field_class_declarator
,
1300 "Unexpected field class declarator type: type=%d",
1301 node_field_class_declarator
->u
.field_class_declarator
.type
);
1306 /* TODO: GCC bitfields not supported yet */
1307 if (node_field_class_declarator
->u
.field_class_declarator
.bitfield_len
!=
1309 _BT_LOGE_NODE(node_field_class_declarator
,
1310 "GCC bitfields are not supported as of this version.");
1316 /* Find the right nested declaration if not provided */
1318 struct bt_list_head
*pointers
=
1319 &node_field_class_declarator
->u
.field_class_declarator
.pointers
;
1321 if (node_field_class_declarator
&& !bt_list_empty(pointers
)) {
1325 * If we have a pointer declarator, it HAS to
1326 * be present in the field class aliases (else
1329 qalias
= create_class_alias_identifier(ctx
,
1330 cls_specifier_list
, node_field_class_declarator
);
1332 ctx_decl_scope_lookup_alias(ctx
->current_scope
,
1333 g_quark_to_string(qalias
), -1, true);
1335 _BT_LOGE_NODE(node_field_class_declarator
,
1336 "Cannot find class alias: name=\"%s\"",
1337 g_quark_to_string(qalias
));
1342 if (nested_decl
->type
== CTF_FIELD_CLASS_TYPE_INT
) {
1343 /* Pointer: force integer's base to 16 */
1344 struct ctf_field_class_int
*int_fc
=
1345 (void *) nested_decl
;
1348 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
1351 ret
= visit_field_class_specifier_list(ctx
,
1352 cls_specifier_list
, &nested_decl
);
1354 BT_ASSERT(!nested_decl
);
1360 BT_ASSERT(nested_decl
);
1362 if (!node_field_class_declarator
) {
1363 *field_decl
= nested_decl
;
1368 if (node_field_class_declarator
->u
.field_class_declarator
.type
== TYPEDEC_ID
) {
1369 if (node_field_class_declarator
->u
.field_class_declarator
.u
.id
) {
1371 node_field_class_declarator
->u
.field_class_declarator
.u
.id
;
1377 *field_name
= g_quark_from_string(id
);
1382 *field_decl
= nested_decl
;
1386 struct ctf_node
*first
;
1387 struct ctf_field_class
*decl
= NULL
;
1388 struct ctf_field_class
*outer_field_decl
= NULL
;
1389 struct bt_list_head
*length
=
1390 &node_field_class_declarator
->
1391 u
.field_class_declarator
.u
.nested
.length
;
1393 /* Create array/sequence, pass nested_decl as child */
1394 if (bt_list_empty(length
)) {
1395 _BT_LOGE_NODE(node_field_class_declarator
,
1396 "Expecting length field reference or value.");
1401 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1402 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1403 _BT_LOGE_NODE(first
,
1404 "Unexpected node type: node-type=%d",
1410 switch (first
->u
.unary_expression
.type
) {
1411 case UNARY_UNSIGNED_CONSTANT
:
1413 struct ctf_field_class_array
*array_decl
= NULL
;
1415 array_decl
= ctf_field_class_array_create();
1416 BT_ASSERT(array_decl
);
1417 array_decl
->length
=
1418 first
->u
.unary_expression
.u
.unsigned_constant
;
1419 array_decl
->base
.elem_fc
= nested_decl
;
1421 decl
= (void *) array_decl
;
1426 /* Lookup unsigned integer definition, create seq. */
1427 struct ctf_field_class_sequence
*seq_decl
= NULL
;
1428 char *length_name
= concatenate_unary_strings(length
);
1431 _BT_LOGE_NODE(node_field_class_declarator
,
1432 "Cannot concatenate unary strings.");
1437 if (strncmp(length_name
, "env.", 4) == 0) {
1438 /* This is, in fact, an array */
1439 const char *env_entry_name
= &length_name
[4];
1440 struct ctf_trace_class_env_entry
*env_entry
=
1441 ctf_trace_class_borrow_env_entry_by_name(
1442 ctx
->ctf_tc
, env_entry_name
);
1443 struct ctf_field_class_array
*array_decl
;
1446 _BT_LOGE_NODE(node_field_class_declarator
,
1447 "Cannot find environment entry: "
1448 "name=\"%s\"", env_entry_name
);
1453 if (env_entry
->type
!= CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
) {
1454 _BT_LOGE_NODE(node_field_class_declarator
,
1455 "Wrong environment entry type "
1456 "(expecting integer): "
1457 "name=\"%s\"", env_entry_name
);
1462 if (env_entry
->value
.i
< 0) {
1463 _BT_LOGE_NODE(node_field_class_declarator
,
1464 "Invalid, negative array length: "
1465 "env-entry-name=\"%s\", "
1468 env_entry
->value
.i
);
1473 array_decl
= ctf_field_class_array_create();
1474 BT_ASSERT(array_decl
);
1475 array_decl
->length
=
1476 (uint64_t) env_entry
->value
.i
;
1477 array_decl
->base
.elem_fc
= nested_decl
;
1479 decl
= (void *) array_decl
;
1481 char *length_name_no_underscore
=
1482 remove_underscores_from_field_ref(
1484 if (!length_name_no_underscore
) {
1486 * remove_underscores_from_field_ref()
1492 seq_decl
= ctf_field_class_sequence_create();
1493 BT_ASSERT(seq_decl
);
1494 seq_decl
->base
.elem_fc
= nested_decl
;
1496 g_string_assign(seq_decl
->length_ref
,
1497 length_name_no_underscore
);
1498 free(length_name_no_underscore
);
1499 decl
= (void *) seq_decl
;
1502 g_free(length_name
);
1510 BT_ASSERT(!nested_decl
);
1512 BT_ASSERT(!*field_decl
);
1515 * At this point, we found the next nested declaration.
1516 * We currently own this (and lost the ownership of
1517 * nested_decl in the meantime). Pass this next
1518 * nested declaration as the content of the outer
1519 * container, MOVING its ownership.
1521 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1523 node_field_class_declarator
->
1524 u
.field_class_declarator
.u
.nested
.field_class_declarator
,
1525 &outer_field_decl
, decl
);
1528 BT_ASSERT(!outer_field_decl
);
1533 BT_ASSERT(outer_field_decl
);
1534 *field_decl
= outer_field_decl
;
1535 outer_field_decl
= NULL
;
1538 BT_ASSERT(*field_decl
);
1542 ctf_field_class_destroy(*field_decl
);
1550 ctf_field_class_destroy(nested_decl
);
1556 int visit_struct_decl_field(struct ctx
*ctx
,
1557 struct ctf_field_class_struct
*struct_decl
,
1558 struct ctf_node
*cls_specifier_list
,
1559 struct bt_list_head
*field_class_declarators
)
1562 struct ctf_node
*iter
;
1563 struct ctf_field_class
*field_decl
= NULL
;
1565 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1568 const char *field_name
;
1570 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1571 &qfield_name
, iter
, &field_decl
, NULL
);
1573 BT_ASSERT(!field_decl
);
1574 _BT_LOGE_NODE(cls_specifier_list
,
1575 "Cannot visit field class declarator: ret=%d", ret
);
1579 BT_ASSERT(field_decl
);
1580 field_name
= g_quark_to_string(qfield_name
);
1582 /* Check if field with same name already exists */
1583 if (ctf_field_class_struct_borrow_member_by_name(
1584 struct_decl
, field_name
)) {
1585 _BT_LOGE_NODE(cls_specifier_list
,
1586 "Duplicate field in structure field class: "
1587 "field-name=\"%s\"", field_name
);
1592 /* Add field to structure */
1593 ctf_field_class_struct_append_member(struct_decl
,
1594 field_name
, field_decl
);
1601 ctf_field_class_destroy(field_decl
);
1607 int visit_variant_decl_field(struct ctx
*ctx
,
1608 struct ctf_field_class_variant
*variant_decl
,
1609 struct ctf_node
*cls_specifier_list
,
1610 struct bt_list_head
*field_class_declarators
)
1613 struct ctf_node
*iter
;
1614 struct ctf_field_class
*field_decl
= NULL
;
1616 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1619 const char *field_name
;
1621 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1622 &qfield_name
, iter
, &field_decl
, NULL
);
1624 BT_ASSERT(!field_decl
);
1625 _BT_LOGE_NODE(cls_specifier_list
,
1626 "Cannot visit field class declarator: ret=%d", ret
);
1630 BT_ASSERT(field_decl
);
1631 field_name
= g_quark_to_string(qfield_name
);
1633 /* Check if field with same name already exists */
1634 if (ctf_field_class_variant_borrow_option_by_name(
1635 variant_decl
, field_name
)) {
1636 _BT_LOGE_NODE(cls_specifier_list
,
1637 "Duplicate field in variant field class: "
1638 "field-name=\"%s\"", field_name
);
1643 /* Add field to structure */
1644 ctf_field_class_variant_append_option(variant_decl
,
1645 field_name
, field_decl
);
1652 ctf_field_class_destroy(field_decl
);
1658 int visit_field_class_def(struct ctx
*ctx
, struct ctf_node
*cls_specifier_list
,
1659 struct bt_list_head
*field_class_declarators
)
1663 struct ctf_node
*iter
;
1664 struct ctf_field_class
*class_decl
= NULL
;
1666 bt_list_for_each_entry(iter
, field_class_declarators
, siblings
) {
1667 ret
= visit_field_class_declarator(ctx
, cls_specifier_list
,
1668 &qidentifier
, iter
, &class_decl
, NULL
);
1671 "Cannot visit field class declarator: ret=%d", ret
);
1676 /* Do not allow field class def and alias of untagged variants */
1677 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1678 struct ctf_field_class_variant
*var_fc
=
1679 (void *) class_decl
;
1681 if (var_fc
->tag_path
.path
->len
== 0) {
1683 "Type definition of untagged variant field class is not allowed.");
1689 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1690 g_quark_to_string(qidentifier
), class_decl
);
1693 "Cannot register field class alias: name=\"%s\"",
1694 g_quark_to_string(qidentifier
));
1700 ctf_field_class_destroy(class_decl
);
1706 int visit_field_class_alias(struct ctx
*ctx
, struct ctf_node
*target
,
1707 struct ctf_node
*alias
)
1711 struct ctf_node
*node
;
1712 GQuark qdummy_field_name
;
1713 struct ctf_field_class
*class_decl
= NULL
;
1715 /* Create target field class */
1716 if (bt_list_empty(&target
->u
.field_class_alias_target
.field_class_declarators
)) {
1719 node
= _BT_LIST_FIRST_ENTRY(
1720 &target
->u
.field_class_alias_target
.field_class_declarators
,
1721 struct ctf_node
, siblings
);
1724 ret
= visit_field_class_declarator(ctx
,
1725 target
->u
.field_class_alias_target
.field_class_specifier_list
,
1726 &qdummy_field_name
, node
, &class_decl
, NULL
);
1728 BT_ASSERT(!class_decl
);
1730 "Cannot visit field class declarator: ret=%d", ret
);
1734 /* Do not allow field class def and alias of untagged variants */
1735 if (class_decl
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
1736 struct ctf_field_class_variant
*var_fc
= (void *) class_decl
;
1738 if (var_fc
->tag_path
.path
->len
== 0) {
1739 _BT_LOGE_NODE(target
,
1740 "Type definition of untagged variant field class is not allowed.");
1747 * The semantic validator does not check whether the target is
1748 * abstract or not (if it has an identifier). Check it here.
1750 if (qdummy_field_name
!= 0) {
1751 _BT_LOGE_NODE(target
,
1752 "Expecting empty identifier: id=\"%s\"",
1753 g_quark_to_string(qdummy_field_name
));
1758 /* Create alias identifier */
1759 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.field_class_alias_name
.field_class_declarators
,
1760 struct ctf_node
, siblings
);
1761 qalias
= create_class_alias_identifier(ctx
,
1762 alias
->u
.field_class_alias_name
.field_class_specifier_list
, node
);
1763 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1764 g_quark_to_string(qalias
), class_decl
);
1767 "Cannot register class alias: name=\"%s\"",
1768 g_quark_to_string(qalias
));
1773 ctf_field_class_destroy(class_decl
);
1779 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1780 struct ctf_field_class_struct
*struct_decl
)
1784 switch (entry_node
->type
) {
1786 ret
= visit_field_class_def(ctx
,
1787 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1788 &entry_node
->u
.field_class_def
.field_class_declarators
);
1790 _BT_LOGE_NODE(entry_node
,
1791 "Cannot add field class found in structure field class: ret=%d",
1796 case NODE_TYPEALIAS
:
1797 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1798 entry_node
->u
.field_class_alias
.alias
);
1800 _BT_LOGE_NODE(entry_node
,
1801 "Cannot add field class alias found in structure field class: ret=%d",
1806 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1808 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1809 entry_node
->u
.struct_or_variant_declaration
.
1810 field_class_specifier_list
,
1811 &entry_node
->u
.struct_or_variant_declaration
.
1812 field_class_declarators
);
1818 _BT_LOGE_NODE(entry_node
,
1819 "Unexpected node type: node-type=%d", entry_node
->type
);
1829 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1830 struct ctf_field_class_variant
*variant_decl
)
1834 switch (entry_node
->type
) {
1836 ret
= visit_field_class_def(ctx
,
1837 entry_node
->u
.field_class_def
.field_class_specifier_list
,
1838 &entry_node
->u
.field_class_def
.field_class_declarators
);
1840 _BT_LOGE_NODE(entry_node
,
1841 "Cannot add field class found in variant field class: ret=%d",
1846 case NODE_TYPEALIAS
:
1847 ret
= visit_field_class_alias(ctx
, entry_node
->u
.field_class_alias
.target
,
1848 entry_node
->u
.field_class_alias
.alias
);
1850 _BT_LOGE_NODE(entry_node
,
1851 "Cannot add field class alias found in variant field class: ret=%d",
1856 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1858 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1859 entry_node
->u
.struct_or_variant_declaration
.
1860 field_class_specifier_list
,
1861 &entry_node
->u
.struct_or_variant_declaration
.
1862 field_class_declarators
);
1868 _BT_LOGE_NODE(entry_node
,
1869 "Unexpected node type: node-type=%d",
1880 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1881 struct bt_list_head
*decl_list
, int has_body
,
1882 struct bt_list_head
*min_align
,
1883 struct ctf_field_class_struct
**struct_decl
)
1887 BT_ASSERT(struct_decl
);
1888 *struct_decl
= NULL
;
1890 /* For named struct (without body), lookup in declaration scope */
1893 BT_LOGE_STR("Bodyless structure field class: missing name.");
1898 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1900 if (!*struct_decl
) {
1901 BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
1907 struct ctf_node
*entry_node
;
1908 uint64_t min_align_value
= 0;
1911 if (ctx_decl_scope_lookup_struct(
1912 ctx
->current_scope
, name
, 1, false)) {
1913 BT_LOGE("Structure field class already declared in local scope: "
1914 "name=\"struct %s\"", name
);
1920 if (!bt_list_empty(min_align
)) {
1921 ret
= get_unary_unsigned(min_align
, &min_align_value
);
1923 BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1929 *struct_decl
= ctf_field_class_struct_create();
1930 BT_ASSERT(*struct_decl
);
1932 if (min_align_value
!= 0) {
1933 (*struct_decl
)->base
.alignment
= min_align_value
;
1936 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1938 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1939 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1942 _BT_LOGE_NODE(entry_node
,
1943 "Cannot visit structure field class entry: "
1953 ret
= ctx_decl_scope_register_struct(ctx
->current_scope
,
1954 name
, *struct_decl
);
1956 BT_LOGE("Cannot register structure field class in declaration scope: "
1957 "name=\"struct %s\", ret=%d", name
, ret
);
1966 ctf_field_class_destroy((void *) *struct_decl
);
1967 *struct_decl
= NULL
;
1972 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1973 const char *tag
, struct bt_list_head
*decl_list
,
1974 int has_body
, struct ctf_field_class_variant
**variant_decl
)
1977 struct ctf_field_class_variant
*untagged_variant_decl
= NULL
;
1979 BT_ASSERT(variant_decl
);
1980 *variant_decl
= NULL
;
1982 /* For named variant (without body), lookup in declaration scope */
1985 BT_LOGE_STR("Bodyless variant field class: missing name.");
1990 untagged_variant_decl
=
1991 ctx_decl_scope_lookup_variant(ctx
->current_scope
,
1993 if (!untagged_variant_decl
) {
1994 BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
2000 struct ctf_node
*entry_node
;
2003 if (ctx_decl_scope_lookup_variant(ctx
->current_scope
,
2005 BT_LOGE("Variant field class already declared in local scope: "
2006 "name=\"variant %s\"", name
);
2012 untagged_variant_decl
= ctf_field_class_variant_create();
2013 BT_ASSERT(untagged_variant_decl
);
2014 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
2016 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
2017 ret
= visit_variant_decl_entry(ctx
, entry_node
,
2018 untagged_variant_decl
);
2020 _BT_LOGE_NODE(entry_node
,
2021 "Cannot visit variant field class entry: "
2031 ret
= ctx_decl_scope_register_variant(
2032 ctx
->current_scope
, name
,
2033 untagged_variant_decl
);
2035 BT_LOGE("Cannot register variant field class in declaration scope: "
2036 "name=\"variant %s\", ret=%d", name
, ret
);
2043 * If tagged, create tagged variant and return; otherwise
2044 * return untagged variant.
2047 *variant_decl
= untagged_variant_decl
;
2048 untagged_variant_decl
= NULL
;
2051 * At this point, we have a fresh untagged variant; nobody
2052 * else owns it. Set its tag now.
2054 char *tag_no_underscore
=
2055 remove_underscores_from_field_ref(tag
);
2057 if (!tag_no_underscore
) {
2058 /* remove_underscores_from_field_ref() logs errors */
2062 g_string_assign(untagged_variant_decl
->tag_ref
,
2064 free(tag_no_underscore
);
2065 *variant_decl
= untagged_variant_decl
;
2066 untagged_variant_decl
= NULL
;
2069 BT_ASSERT(!untagged_variant_decl
);
2070 BT_ASSERT(*variant_decl
);
2074 ctf_field_class_destroy((void *) untagged_variant_decl
);
2075 untagged_variant_decl
= NULL
;
2076 ctf_field_class_destroy((void *) *variant_decl
);
2077 *variant_decl
= NULL
;
2090 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
2091 struct ctf_field_class_enum
*enum_decl
, struct uori
*last
)
2095 struct ctf_node
*iter
;
2096 struct uori start
= {
2104 const char *label
= enumerator
->u
.enumerator
.id
;
2105 const char *effective_label
= label
;
2106 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2108 bt_list_for_each_entry(iter
, values
, siblings
) {
2109 struct uori
*target
;
2111 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2113 "Wrong expression for enumeration field class label: "
2114 "node-type=%d, label=\"%s\"", iter
->type
,
2126 switch (iter
->u
.unary_expression
.type
) {
2127 case UNARY_SIGNED_CONSTANT
:
2128 target
->is_signed
= true;
2130 iter
->u
.unary_expression
.u
.signed_constant
;
2132 case UNARY_UNSIGNED_CONSTANT
:
2133 target
->is_signed
= false;
2135 iter
->u
.unary_expression
.u
.unsigned_constant
;
2139 "Invalid enumeration field class entry: "
2140 "expecting constant signed or unsigned integer: "
2141 "node-type=%d, label=\"%s\"",
2142 iter
->u
.unary_expression
.type
, label
);
2149 "Invalid enumeration field class entry: label=\"%s\"",
2166 if (end
.is_signed
) {
2167 last
->value
.i
= end
.value
.i
+ 1;
2169 last
->value
.u
= end
.value
.u
+ 1;
2172 if (label
[0] == '_') {
2174 * Strip the first underscore of any enumeration field
2175 * class's label in case this enumeration FC is used as
2176 * a variant FC tag later. The variant FC choice names
2177 * could also start with `_`, in which case the prefix
2178 * is removed, and it the resulting choice name needs to
2181 effective_label
= &label
[1];
2184 ctf_field_class_enum_append_mapping(enum_decl
, effective_label
,
2185 start
.value
.u
, end
.value
.u
);
2193 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2194 struct ctf_node
*container_cls
,
2195 struct bt_list_head
*enumerator_list
,
2196 int has_body
, struct ctf_field_class_enum
**enum_decl
)
2200 struct ctf_field_class_int
*integer_decl
= NULL
;
2202 BT_ASSERT(enum_decl
);
2205 /* For named enum (without body), lookup in declaration scope */
2208 BT_LOGE_STR("Bodyless enumeration field class: missing name.");
2213 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2216 BT_LOGE("Cannot find enumeration field class: "
2217 "name=\"enum %s\"", name
);
2222 struct ctf_node
*iter
;
2223 struct uori last_value
= {
2229 if (ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2231 BT_LOGE("Enumeration field class already declared in local scope: "
2232 "name=\"enum %s\"", name
);
2238 if (!container_cls
) {
2239 integer_decl
= (void *) ctx_decl_scope_lookup_alias(
2240 ctx
->current_scope
, "int", -1, true);
2241 if (!integer_decl
) {
2242 BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2247 ret
= visit_field_class_declarator(ctx
, container_cls
,
2248 &qdummy_id
, NULL
, (void *) &integer_decl
,
2251 BT_ASSERT(!integer_decl
);
2257 BT_ASSERT(integer_decl
);
2259 if (integer_decl
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
) {
2260 BT_LOGE("Container field class for enumeration field class is not an integer field class: "
2261 "fc-type=%d", integer_decl
->base
.base
.type
);
2266 *enum_decl
= ctf_field_class_enum_create();
2267 BT_ASSERT(*enum_decl
);
2268 (*enum_decl
)->base
.base
.base
.alignment
=
2269 integer_decl
->base
.base
.alignment
;
2270 ctf_field_class_int_copy_content((void *) *enum_decl
,
2271 (void *) integer_decl
);
2272 last_value
.is_signed
= (*enum_decl
)->base
.is_signed
;
2274 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2275 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2279 "Cannot visit enumeration field class entry: "
2286 ret
= ctx_decl_scope_register_enum(ctx
->current_scope
,
2289 BT_LOGE("Cannot register enumeration field class in declaration scope: "
2299 ctf_field_class_destroy((void *) *enum_decl
);
2303 ctf_field_class_destroy((void *) integer_decl
);
2304 integer_decl
= NULL
;
2309 int visit_field_class_specifier(struct ctx
*ctx
,
2310 struct ctf_node
*cls_specifier_list
,
2311 struct ctf_field_class
**decl
)
2314 GString
*str
= NULL
;
2317 str
= g_string_new("");
2318 ret
= get_class_specifier_list_name(ctx
, cls_specifier_list
, str
);
2320 _BT_LOGE_NODE(cls_specifier_list
,
2321 "Cannot get field class specifier list's name: ret=%d", ret
);
2325 *decl
= ctx_decl_scope_lookup_alias(ctx
->current_scope
, str
->str
, -1,
2328 _BT_LOGE_NODE(cls_specifier_list
,
2329 "Cannot find field class alias: name=\"%s\"", str
->str
);
2337 ctf_field_class_destroy(*decl
);
2342 g_string_free(str
, TRUE
);
2349 int visit_integer_decl(struct ctx
*ctx
,
2350 struct bt_list_head
*expressions
,
2351 struct ctf_field_class_int
**integer_decl
)
2356 struct ctf_node
*expression
;
2357 uint64_t alignment
= 0, size
= 0;
2358 struct ctf_clock_class
*mapped_clock_class
= NULL
;
2359 enum ctf_encoding encoding
= CTF_ENCODING_NONE
;
2360 bt_field_class_integer_preferred_display_base base
=
2361 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2362 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2364 *integer_decl
= NULL
;
2366 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2367 struct ctf_node
*left
, *right
;
2369 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2370 struct ctf_node
, siblings
);
2371 right
= _BT_LIST_FIRST_ENTRY(
2372 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2375 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2377 "Unexpected unary expression type: type=%d",
2378 left
->u
.unary_expression
.type
);
2383 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
2384 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2385 _BT_LOGE_DUP_ATTR(left
, "signed",
2386 "integer field class");
2391 signedness
= get_boolean(right
);
2392 if (signedness
< 0) {
2393 _BT_LOGE_NODE(right
,
2394 "Invalid boolean value for integer field class's `signed` attribute: "
2400 _SET(&set
, _INTEGER_SIGNED_SET
);
2401 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2403 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2404 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2405 "integer field class");
2410 byte_order
= get_real_byte_order(ctx
, right
);
2411 if (byte_order
== -1) {
2412 _BT_LOGE_NODE(right
,
2413 "Invalid `byte_order` attribute in integer field class: "
2419 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2420 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
2421 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2422 _BT_LOGE_DUP_ATTR(left
, "size",
2423 "integer field class");
2428 if (right
->u
.unary_expression
.type
!=
2429 UNARY_UNSIGNED_CONSTANT
) {
2430 _BT_LOGE_NODE(right
,
2431 "Invalid `size` attribute in integer field class: "
2432 "expecting unsigned constant integer: "
2434 right
->u
.unary_expression
.type
);
2439 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2441 _BT_LOGE_NODE(right
,
2442 "Invalid `size` attribute in integer field class: "
2443 "expecting positive constant integer: "
2444 "size=%" PRIu64
, size
);
2447 } else if (size
> 64) {
2448 _BT_LOGE_NODE(right
,
2449 "Invalid `size` attribute in integer field class: "
2450 "integer fields over 64 bits are not supported as of this version: "
2451 "size=%" PRIu64
, size
);
2456 _SET(&set
, _INTEGER_SIZE_SET
);
2457 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2459 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2460 _BT_LOGE_DUP_ATTR(left
, "align",
2461 "integer field class");
2466 if (right
->u
.unary_expression
.type
!=
2467 UNARY_UNSIGNED_CONSTANT
) {
2468 _BT_LOGE_NODE(right
,
2469 "Invalid `align` attribute in integer field class: "
2470 "expecting unsigned constant integer: "
2472 right
->u
.unary_expression
.type
);
2478 right
->u
.unary_expression
.u
.unsigned_constant
;
2479 if (!is_align_valid(alignment
)) {
2480 _BT_LOGE_NODE(right
,
2481 "Invalid `align` attribute in integer field class: "
2482 "expecting power of two: "
2483 "align=%" PRIu64
, alignment
);
2488 _SET(&set
, _INTEGER_ALIGN_SET
);
2489 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
2490 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2491 _BT_LOGE_DUP_ATTR(left
, "base",
2492 "integer field class");
2497 switch (right
->u
.unary_expression
.type
) {
2498 case UNARY_UNSIGNED_CONSTANT
:
2500 uint64_t constant
= right
->u
.unary_expression
.
2501 u
.unsigned_constant
;
2505 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2508 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2511 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2514 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2517 _BT_LOGE_NODE(right
,
2518 "Invalid `base` attribute in integer field class: "
2520 right
->u
.unary_expression
.u
.unsigned_constant
);
2528 char *s_right
= concatenate_unary_strings(
2529 &expression
->u
.ctf_expression
.right
);
2531 _BT_LOGE_NODE(right
,
2532 "Unexpected unary expression for integer field class's `base` attribute.");
2537 if (!strcmp(s_right
, "decimal") ||
2538 !strcmp(s_right
, "dec") ||
2539 !strcmp(s_right
, "d") ||
2540 !strcmp(s_right
, "i") ||
2541 !strcmp(s_right
, "u")) {
2542 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
2543 } else if (!strcmp(s_right
, "hexadecimal") ||
2544 !strcmp(s_right
, "hex") ||
2545 !strcmp(s_right
, "x") ||
2546 !strcmp(s_right
, "X") ||
2547 !strcmp(s_right
, "p")) {
2548 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
;
2549 } else if (!strcmp(s_right
, "octal") ||
2550 !strcmp(s_right
, "oct") ||
2551 !strcmp(s_right
, "o")) {
2552 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
;
2553 } else if (!strcmp(s_right
, "binary") ||
2554 !strcmp(s_right
, "b")) {
2555 base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
;
2557 _BT_LOGE_NODE(right
,
2558 "Unexpected unary expression for integer field class's `base` attribute: "
2559 "base=\"%s\"", s_right
);
2569 _BT_LOGE_NODE(right
,
2570 "Invalid `base` attribute in integer field class: "
2571 "expecting unsigned constant integer or unary string.");
2576 _SET(&set
, _INTEGER_BASE_SET
);
2577 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2581 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2582 _BT_LOGE_DUP_ATTR(left
, "encoding",
2583 "integer field class");
2588 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2589 _BT_LOGE_NODE(right
,
2590 "Invalid `encoding` attribute in integer field class: "
2591 "expecting unary string.");
2596 s_right
= concatenate_unary_strings(
2597 &expression
->u
.ctf_expression
.right
);
2599 _BT_LOGE_NODE(right
,
2600 "Unexpected unary expression for integer field class's `encoding` attribute.");
2605 if (!strcmp(s_right
, "UTF8") ||
2606 !strcmp(s_right
, "utf8") ||
2607 !strcmp(s_right
, "utf-8") ||
2608 !strcmp(s_right
, "UTF-8") ||
2609 !strcmp(s_right
, "ASCII") ||
2610 !strcmp(s_right
, "ascii")) {
2611 encoding
= CTF_ENCODING_UTF8
;
2612 } else if (!strcmp(s_right
, "none")) {
2613 encoding
= CTF_ENCODING_NONE
;
2615 _BT_LOGE_NODE(right
,
2616 "Invalid `encoding` attribute in integer field class: "
2617 "unknown encoding: encoding=\"%s\"",
2625 _SET(&set
, _INTEGER_ENCODING_SET
);
2626 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
2627 const char *clock_name
;
2629 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2630 _BT_LOGE_DUP_ATTR(left
, "map",
2631 "integer field class");
2636 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2637 _BT_LOGE_NODE(right
,
2638 "Invalid `map` attribute in integer field class: "
2639 "expecting unary string.");
2645 get_map_clock_name_value(
2646 &expression
->u
.ctf_expression
.right
);
2648 char *s_right
= concatenate_unary_strings(
2649 &expression
->u
.ctf_expression
.right
);
2652 _BT_LOGE_NODE(right
,
2653 "Unexpected unary expression for integer field class's `map` attribute.");
2658 _BT_LOGE_NODE(right
,
2659 "Invalid `map` attribute in integer field class: "
2660 "cannot find clock class at this point: name=\"%s\"",
2662 _SET(&set
, _INTEGER_MAP_SET
);
2667 mapped_clock_class
=
2668 ctf_trace_class_borrow_clock_class_by_name(
2669 ctx
->ctf_tc
, clock_name
);
2670 if (!mapped_clock_class
) {
2671 _BT_LOGE_NODE(right
,
2672 "Invalid `map` attribute in integer field class: "
2673 "cannot find clock class at this point: name=\"%s\"",
2679 _SET(&set
, _INTEGER_MAP_SET
);
2682 "Unknown attribute in integer field class: "
2684 left
->u
.unary_expression
.u
.string
);
2688 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2689 BT_LOGE_STR("Missing `size` attribute in integer field class.");
2694 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2695 if (size
% CHAR_BIT
) {
2696 /* Bit-packed alignment */
2699 /* Byte-packed alignment */
2700 alignment
= CHAR_BIT
;
2704 *integer_decl
= ctf_field_class_int_create();
2705 BT_ASSERT(*integer_decl
);
2706 (*integer_decl
)->base
.base
.alignment
= alignment
;
2707 (*integer_decl
)->base
.byte_order
= byte_order
;
2708 (*integer_decl
)->base
.size
= size
;
2709 (*integer_decl
)->is_signed
= (signedness
> 0);
2710 (*integer_decl
)->disp_base
= base
;
2711 (*integer_decl
)->encoding
= encoding
;
2712 (*integer_decl
)->mapped_clock_class
= mapped_clock_class
;
2716 ctf_field_class_destroy((void *) *integer_decl
);
2717 *integer_decl
= NULL
;
2722 int visit_floating_point_number_decl(struct ctx
*ctx
,
2723 struct bt_list_head
*expressions
,
2724 struct ctf_field_class_float
**float_decl
)
2728 struct ctf_node
*expression
;
2729 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2730 enum ctf_byte_order byte_order
= ctx
->ctf_tc
->default_byte_order
;
2734 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2735 struct ctf_node
*left
, *right
;
2737 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2738 struct ctf_node
, siblings
);
2739 right
= _BT_LIST_FIRST_ENTRY(
2740 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2743 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2745 "Unexpected unary expression type: type=%d",
2746 left
->u
.unary_expression
.type
);
2751 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
2752 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2753 _BT_LOGE_DUP_ATTR(left
, "byte_order",
2754 "floating point number field class");
2759 byte_order
= get_real_byte_order(ctx
, right
);
2760 if (byte_order
== -1) {
2761 _BT_LOGE_NODE(right
,
2762 "Invalid `byte_order` attribute in floating point number field class: "
2768 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2769 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2771 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2772 _BT_LOGE_DUP_ATTR(left
, "exp_dig",
2773 "floating point number field class");
2778 if (right
->u
.unary_expression
.type
!=
2779 UNARY_UNSIGNED_CONSTANT
) {
2780 _BT_LOGE_NODE(right
,
2781 "Invalid `exp_dig` attribute in floating point number field class: "
2782 "expecting unsigned constant integer: "
2784 right
->u
.unary_expression
.type
);
2789 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2790 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2791 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2793 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2794 _BT_LOGE_DUP_ATTR(left
, "mant_dig",
2795 "floating point number field class");
2800 if (right
->u
.unary_expression
.type
!=
2801 UNARY_UNSIGNED_CONSTANT
) {
2802 _BT_LOGE_NODE(right
,
2803 "Invalid `mant_dig` attribute in floating point number field class: "
2804 "expecting unsigned constant integer: "
2806 right
->u
.unary_expression
.type
);
2811 mant_dig
= right
->u
.unary_expression
.u
.
2813 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2814 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2816 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2817 _BT_LOGE_DUP_ATTR(left
, "align",
2818 "floating point number field class");
2823 if (right
->u
.unary_expression
.type
!=
2824 UNARY_UNSIGNED_CONSTANT
) {
2825 _BT_LOGE_NODE(right
,
2826 "Invalid `align` attribute in floating point number field class: "
2827 "expecting unsigned constant integer: "
2829 right
->u
.unary_expression
.type
);
2834 alignment
= right
->u
.unary_expression
.u
.
2837 if (!is_align_valid(alignment
)) {
2838 _BT_LOGE_NODE(right
,
2839 "Invalid `align` attribute in floating point number field class: "
2840 "expecting power of two: "
2841 "align=%" PRIu64
, alignment
);
2846 _SET(&set
, _FLOAT_ALIGN_SET
);
2849 "Unknown attribute in floating point number field class: "
2851 left
->u
.unary_expression
.u
.string
);
2855 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2856 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2861 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2862 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2867 if (mant_dig
!= 24 && mant_dig
!= 53) {
2868 BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2873 if (mant_dig
== 24 && exp_dig
!= 8) {
2874 BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2879 if (mant_dig
== 53 && exp_dig
!= 11) {
2880 BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2885 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2886 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2887 /* Bit-packed alignment */
2890 /* Byte-packed alignment */
2891 alignment
= CHAR_BIT
;
2895 *float_decl
= ctf_field_class_float_create();
2896 BT_ASSERT(*float_decl
);
2897 (*float_decl
)->base
.base
.alignment
= alignment
;
2898 (*float_decl
)->base
.byte_order
= byte_order
;
2899 (*float_decl
)->base
.size
= mant_dig
+ exp_dig
;
2903 ctf_field_class_destroy((void *) *float_decl
);
2909 int visit_string_decl(struct ctx
*ctx
,
2910 struct bt_list_head
*expressions
,
2911 struct ctf_field_class_string
**string_decl
)
2915 struct ctf_node
*expression
;
2916 enum ctf_encoding encoding
= CTF_ENCODING_UTF8
;
2918 *string_decl
= NULL
;
2920 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2921 struct ctf_node
*left
, *right
;
2923 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2924 struct ctf_node
, siblings
);
2925 right
= _BT_LIST_FIRST_ENTRY(
2926 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2929 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2931 "Unexpected unary expression type: type=%d",
2932 left
->u
.unary_expression
.type
);
2937 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
2940 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2941 _BT_LOGE_DUP_ATTR(left
, "encoding",
2942 "string field class");
2947 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2948 _BT_LOGE_NODE(right
,
2949 "Invalid `encoding` attribute in string field class: "
2950 "expecting unary string.");
2955 s_right
= concatenate_unary_strings(
2956 &expression
->u
.ctf_expression
.right
);
2958 _BT_LOGE_NODE(right
,
2959 "Unexpected unary expression for string field class's `encoding` attribute.");
2964 if (!strcmp(s_right
, "UTF8") ||
2965 !strcmp(s_right
, "utf8") ||
2966 !strcmp(s_right
, "utf-8") ||
2967 !strcmp(s_right
, "UTF-8") ||
2968 !strcmp(s_right
, "ASCII") ||
2969 !strcmp(s_right
, "ascii")) {
2970 encoding
= CTF_ENCODING_UTF8
;
2971 } else if (!strcmp(s_right
, "none")) {
2972 encoding
= CTF_ENCODING_NONE
;
2974 _BT_LOGE_NODE(right
,
2975 "Invalid `encoding` attribute in string field class: "
2976 "unknown encoding: encoding=\"%s\"",
2984 _SET(&set
, _STRING_ENCODING_SET
);
2987 "Unknown attribute in string field class: "
2989 left
->u
.unary_expression
.u
.string
);
2993 *string_decl
= ctf_field_class_string_create();
2994 BT_ASSERT(*string_decl
);
2995 (*string_decl
)->encoding
= encoding
;
2999 ctf_field_class_destroy((void *) *string_decl
);
3000 *string_decl
= NULL
;
3005 int visit_field_class_specifier_list(struct ctx
*ctx
,
3006 struct ctf_node
*ts_list
, struct ctf_field_class
**decl
)
3009 struct ctf_node
*first
, *node
;
3013 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
3014 _BT_LOGE_NODE(ts_list
,
3015 "Unexpected node type: node-type=%d", ts_list
->type
);
3020 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.field_class_specifier_list
.head
,
3021 struct ctf_node
, siblings
);
3022 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
3023 _BT_LOGE_NODE(first
,
3024 "Unexpected node type: node-type=%d", first
->type
);
3029 node
= first
->u
.field_class_specifier
.node
;
3031 switch (first
->u
.field_class_specifier
.type
) {
3032 case TYPESPEC_INTEGER
:
3033 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
3040 case TYPESPEC_FLOATING_POINT
:
3041 ret
= visit_floating_point_number_decl(ctx
,
3042 &node
->u
.floating_point
.expressions
, (void *) decl
);
3048 case TYPESPEC_STRING
:
3049 ret
= visit_string_decl(ctx
,
3050 &node
->u
.string
.expressions
, (void *) decl
);
3056 case TYPESPEC_STRUCT
:
3057 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
3058 &node
->u
._struct
.declaration_list
,
3059 node
->u
._struct
.has_body
,
3060 &node
->u
._struct
.min_align
, (void *) decl
);
3066 case TYPESPEC_VARIANT
:
3067 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
3068 node
->u
.variant
.choice
,
3069 &node
->u
.variant
.declaration_list
,
3070 node
->u
.variant
.has_body
, (void *) decl
);
3077 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
3078 node
->u
._enum
.container_field_class
,
3079 &node
->u
._enum
.enumerator_list
,
3080 node
->u
._enum
.has_body
, (void *) decl
);
3088 case TYPESPEC_SHORT
:
3091 case TYPESPEC_FLOAT
:
3092 case TYPESPEC_DOUBLE
:
3093 case TYPESPEC_SIGNED
:
3094 case TYPESPEC_UNSIGNED
:
3096 case TYPESPEC_COMPLEX
:
3097 case TYPESPEC_IMAGINARY
:
3098 case TYPESPEC_CONST
:
3099 case TYPESPEC_ID_TYPE
:
3100 ret
= visit_field_class_specifier(ctx
, ts_list
, decl
);
3102 _BT_LOGE_NODE(first
,
3103 "Cannot visit field class specifier: ret=%d",
3110 _BT_LOGE_NODE(first
,
3111 "Unexpected field class specifier type: node-type=%d",
3112 first
->u
.field_class_specifier
.type
);
3121 ctf_field_class_destroy((void *) *decl
);
3127 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3128 struct ctf_event_class
*event_class
, uint64_t *stream_id
,
3134 switch (node
->type
) {
3136 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3137 &node
->u
.field_class_def
.field_class_declarators
);
3140 "Cannot add field class found in event class.");
3144 case NODE_TYPEALIAS
:
3145 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3146 node
->u
.field_class_alias
.alias
);
3149 "Cannot add field class alias found in event class.");
3153 case NODE_CTF_EXPRESSION
:
3155 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3157 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3162 if (!strcmp(left
, "name")) {
3163 /* This is already known at this stage */
3164 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3165 _BT_LOGE_DUP_ATTR(node
, "name", "event class");
3170 _SET(set
, _EVENT_NAME_SET
);
3171 } else if (!strcmp(left
, "id")) {
3174 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3175 _BT_LOGE_DUP_ATTR(node
, "id", "event class");
3180 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3182 /* Only read "id" if get_unary_unsigned() succeeded. */
3183 if (ret
|| (!ret
&& id
< 0)) {
3185 "Unexpected unary expression for event class's `id` attribute.");
3190 event_class
->id
= id
;
3191 _SET(set
, _EVENT_ID_SET
);
3192 } else if (!strcmp(left
, "stream_id")) {
3193 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3194 _BT_LOGE_DUP_ATTR(node
, "stream_id",
3200 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3204 * Only read "stream_id" if get_unary_unsigned()
3209 "Unexpected unary expression for event class's `stream_id` attribute.");
3214 _SET(set
, _EVENT_STREAM_ID_SET
);
3215 } else if (!strcmp(left
, "context")) {
3216 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3218 "Duplicate `context` entry in event class.");
3223 ret
= visit_field_class_specifier_list(ctx
,
3224 _BT_LIST_FIRST_ENTRY(
3225 &node
->u
.ctf_expression
.right
,
3226 struct ctf_node
, siblings
),
3227 &event_class
->spec_context_fc
);
3230 "Cannot create event class's context field class.");
3234 BT_ASSERT(event_class
->spec_context_fc
);
3235 _SET(set
, _EVENT_CONTEXT_SET
);
3236 } else if (!strcmp(left
, "fields")) {
3237 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3239 "Duplicate `fields` entry in event class.");
3244 ret
= visit_field_class_specifier_list(ctx
,
3245 _BT_LIST_FIRST_ENTRY(
3246 &node
->u
.ctf_expression
.right
,
3247 struct ctf_node
, siblings
),
3248 &event_class
->payload_fc
);
3251 "Cannot create event class's payload field class.");
3255 BT_ASSERT(event_class
->payload_fc
);
3256 _SET(set
, _EVENT_FIELDS_SET
);
3257 } else if (!strcmp(left
, "loglevel")) {
3258 uint64_t loglevel_value
;
3259 bt_event_class_log_level log_level
= -1;
3261 if (_IS_SET(set
, _EVENT_LOG_LEVEL_SET
)) {
3262 _BT_LOGE_DUP_ATTR(node
, "loglevel",
3268 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3272 "Unexpected unary expression for event class's `loglevel` attribute.");
3277 switch (loglevel_value
) {
3279 log_level
= BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
;
3282 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ALERT
;
3285 log_level
= BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
;
3288 log_level
= BT_EVENT_CLASS_LOG_LEVEL_ERROR
;
3291 log_level
= BT_EVENT_CLASS_LOG_LEVEL_WARNING
;
3294 log_level
= BT_EVENT_CLASS_LOG_LEVEL_NOTICE
;
3297 log_level
= BT_EVENT_CLASS_LOG_LEVEL_INFO
;
3300 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
;
3303 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
;
3306 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
;
3309 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
;
3312 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
;
3315 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
;
3318 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
;
3321 log_level
= BT_EVENT_CLASS_LOG_LEVEL_DEBUG
;
3324 _BT_LOGW_NODE(node
, "Not setting event class's log level because its value is unknown: "
3325 "log-level=%" PRIu64
, loglevel_value
);
3328 if (log_level
!= -1) {
3329 event_class
->log_level
= log_level
;
3332 _SET(set
, _EVENT_LOG_LEVEL_SET
);
3333 } else if (!strcmp(left
, "model.emf.uri")) {
3336 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3337 _BT_LOGE_DUP_ATTR(node
, "model.emf.uri",
3343 right
= concatenate_unary_strings(
3344 &node
->u
.ctf_expression
.right
);
3347 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3352 if (strlen(right
) == 0) {
3354 "Not setting event class's EMF URI because it's empty.");
3356 g_string_assign(event_class
->emf_uri
,
3361 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3364 "Unknown attribute in event class: "
3365 "attr-name=\"%s\"", left
);
3389 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3393 struct ctf_node
*iter
;
3394 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3396 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3397 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3401 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3404 "Cannot concatenate unary strings.");
3408 if (!strcmp(left
, "name")) {
3409 name
= concatenate_unary_strings(
3410 &iter
->u
.ctf_expression
.right
);
3413 "Unexpected unary expression for event class's `name` attribute.");
3434 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3438 struct ctf_node
*iter
;
3439 uint64_t stream_id
= 0;
3440 char *event_name
= NULL
;
3441 struct ctf_event_class
*event_class
= NULL
;
3442 struct ctf_stream_class
*stream_class
= NULL
;
3443 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3444 bool pop_scope
= false;
3446 if (node
->visited
) {
3450 node
->visited
= TRUE
;
3451 event_name
= get_event_decl_name(ctx
, node
);
3454 "Missing `name` attribute in event class.");
3459 event_class
= ctf_event_class_create();
3460 BT_ASSERT(event_class
);
3461 g_string_assign(event_class
->name
, event_name
);
3462 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3465 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3466 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3469 _BT_LOGE_NODE(iter
, "Cannot visit event class's entry: "
3475 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3477 * Allow missing stream_id if there is only a single
3480 switch (ctx
->ctf_tc
->stream_classes
->len
) {
3482 /* Create implicit stream class if there's none */
3484 stream_class
= ctf_stream_class_create();
3485 BT_ASSERT(stream_class
);
3486 stream_class
->id
= stream_id
;
3487 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
,
3491 /* Single stream class: get its ID */
3492 stream_class
= ctx
->ctf_tc
->stream_classes
->pdata
[0];
3493 stream_id
= stream_class
->id
;
3497 "Missing `stream_id` attribute in event class.");
3503 /* We have the stream ID now; get the stream class if found */
3504 if (!stream_class
) {
3505 stream_class
= ctf_trace_class_borrow_stream_class_by_id(
3506 ctx
->ctf_tc
, stream_id
);
3507 if (!stream_class
) {
3509 "Cannot find stream class at this point: "
3510 "id=%" PRId64
, stream_id
);
3516 BT_ASSERT(stream_class
);
3518 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3519 /* Allow only one event without ID per stream */
3520 if (stream_class
->event_classes
->len
!= 0) {
3522 "Missing `id` attribute in event class.");
3528 event_class
->id
= 0;
3531 if (ctf_stream_class_borrow_event_class_by_id(stream_class
,
3534 "Duplicate event class (same ID) in the same stream class: "
3535 "id=%" PRId64
, event_class
->id
);
3540 ctf_stream_class_append_event_class(stream_class
, event_class
);
3545 ctf_event_class_destroy(event_class
);
3565 int auto_map_field_to_trace_clock_class(struct ctx
*ctx
,
3566 struct ctf_field_class
*fc
)
3568 struct ctf_clock_class
*clock_class_to_map_to
= NULL
;
3569 struct ctf_field_class_int
*int_fc
= (void *) fc
;
3571 uint64_t clock_class_count
;
3577 if (fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3578 fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3582 if (int_fc
->mapped_clock_class
) {
3583 /* Already mapped */
3587 clock_class_count
= ctx
->ctf_tc
->clock_classes
->len
;
3589 switch (clock_class_count
) {
3592 * No clock class exists in the trace at this point. Create an
3593 * implicit one at 1 GHz, named `default`, and use this clock
3596 clock_class_to_map_to
= ctf_clock_class_create();
3597 BT_ASSERT(clock_class_to_map_to
);
3598 clock_class_to_map_to
->frequency
= UINT64_C(1000000000);
3599 g_string_assign(clock_class_to_map_to
->name
, "default");
3600 BT_ASSERT(ret
== 0);
3601 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
,
3602 clock_class_to_map_to
);
3606 * Only one clock class exists in the trace at this point: use
3609 clock_class_to_map_to
= ctx
->ctf_tc
->clock_classes
->pdata
[0];
3613 * Timestamp field not mapped to a clock class and there's more
3614 * than one clock class in the trace: this is an error.
3616 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3617 "but there's more than one clock class in the trace at this point.");
3622 BT_ASSERT(clock_class_to_map_to
);
3623 int_fc
->mapped_clock_class
= clock_class_to_map_to
;
3630 int auto_map_fields_to_trace_clock_class(struct ctx
*ctx
,
3631 struct ctf_field_class
*root_fc
, const char *field_name
)
3635 struct ctf_field_class_struct
*struct_fc
= (void *) root_fc
;
3636 struct ctf_field_class_variant
*var_fc
= (void *) root_fc
;
3642 if (root_fc
->type
!= CTF_FIELD_CLASS_TYPE_STRUCT
&&
3643 root_fc
->type
!= CTF_FIELD_CLASS_TYPE_VARIANT
) {
3647 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3648 count
= struct_fc
->members
->len
;
3650 count
= var_fc
->options
->len
;
3653 for (i
= 0; i
< count
; i
++) {
3654 struct ctf_named_field_class
*named_fc
= NULL
;
3656 if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_STRUCT
) {
3657 named_fc
= ctf_field_class_struct_borrow_member_by_index(
3659 } else if (root_fc
->type
== CTF_FIELD_CLASS_TYPE_VARIANT
) {
3660 named_fc
= ctf_field_class_variant_borrow_option_by_index(
3664 if (strcmp(named_fc
->name
->str
, field_name
) == 0) {
3665 ret
= auto_map_field_to_trace_clock_class(ctx
,
3668 BT_LOGE("Cannot automatically map field to trace's clock class: "
3669 "field-name=\"%s\"", field_name
);
3674 ret
= auto_map_fields_to_trace_clock_class(ctx
, named_fc
->fc
,
3677 BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3678 "field-name=\"%s\", root-field-name=\"%s\"",
3679 field_name
, named_fc
->name
->str
);
3689 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3690 struct ctf_stream_class
*stream_class
, int *set
)
3695 switch (node
->type
) {
3697 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3698 &node
->u
.field_class_def
.field_class_declarators
);
3701 "Cannot add field class found in stream class.");
3705 case NODE_TYPEALIAS
:
3706 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3707 node
->u
.field_class_alias
.alias
);
3710 "Cannot add field class alias found in stream class.");
3714 case NODE_CTF_EXPRESSION
:
3716 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3718 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3723 if (!strcmp(left
, "id")) {
3726 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3727 _BT_LOGE_DUP_ATTR(node
, "id",
3728 "stream declaration");
3733 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3736 /* Only read "id" if get_unary_unsigned() succeeded. */
3737 if (ret
|| (!ret
&& id
< 0)) {
3739 "Unexpected unary expression for stream class's `id` attribute.");
3744 if (ctf_trace_class_borrow_stream_class_by_id(
3747 "Duplicate stream class (same ID): id=%" PRId64
,
3753 stream_class
->id
= id
;
3754 _SET(set
, _STREAM_ID_SET
);
3755 } else if (!strcmp(left
, "event.header")) {
3756 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3758 "Duplicate `event.header` entry in stream class.");
3763 ret
= visit_field_class_specifier_list(ctx
,
3764 _BT_LIST_FIRST_ENTRY(
3765 &node
->u
.ctf_expression
.right
,
3766 struct ctf_node
, siblings
),
3767 &stream_class
->event_header_fc
);
3770 "Cannot create stream class's event header field class.");
3774 BT_ASSERT(stream_class
->event_header_fc
);
3775 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3776 stream_class
->event_header_fc
, "timestamp");
3779 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3783 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3784 } else if (!strcmp(left
, "event.context")) {
3785 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3787 "Duplicate `event.context` entry in stream class.");
3792 ret
= visit_field_class_specifier_list(ctx
,
3793 _BT_LIST_FIRST_ENTRY(
3794 &node
->u
.ctf_expression
.right
,
3795 struct ctf_node
, siblings
),
3796 &stream_class
->event_common_context_fc
);
3799 "Cannot create stream class's event context field class.");
3803 BT_ASSERT(stream_class
->event_common_context_fc
);
3804 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3805 } else if (!strcmp(left
, "packet.context")) {
3806 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3808 "Duplicate `packet.context` entry in stream class.");
3813 ret
= visit_field_class_specifier_list(ctx
,
3814 _BT_LIST_FIRST_ENTRY(
3815 &node
->u
.ctf_expression
.right
,
3816 struct ctf_node
, siblings
),
3817 &stream_class
->packet_context_fc
);
3820 "Cannot create stream class's packet context field class.");
3824 BT_ASSERT(stream_class
->packet_context_fc
);
3825 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3826 stream_class
->packet_context_fc
,
3830 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3834 ret
= auto_map_fields_to_trace_clock_class(ctx
,
3835 stream_class
->packet_context_fc
,
3839 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3843 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3846 "Unknown attribute in stream class: "
3847 "attr-name=\"%s\"", left
);
3868 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3872 struct ctf_node
*iter
;
3873 struct ctf_stream_class
*stream_class
= NULL
;
3874 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3876 if (node
->visited
) {
3880 node
->visited
= TRUE
;
3881 stream_class
= ctf_stream_class_create();
3882 BT_ASSERT(stream_class
);
3883 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3885 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3886 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3889 "Cannot visit stream class's entry: "
3898 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3899 /* Check that packet header has `stream_id` field */
3900 struct ctf_named_field_class
*named_fc
= NULL
;
3902 if (!ctx
->ctf_tc
->packet_header_fc
) {
3904 "Stream class has a `id` attribute, "
3905 "but trace has no packet header field class.");
3909 named_fc
= ctf_field_class_struct_borrow_member_by_name(
3910 (void *) ctx
->ctf_tc
->packet_header_fc
, "stream_id");
3913 "Stream class has a `id` attribute, "
3914 "but trace's packet header field class has no `stream_id` field.");
3918 if (named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_INT
&&
3919 named_fc
->fc
->type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
3921 "Stream class has a `id` attribute, "
3922 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3926 /* Allow only _one_ ID-less stream */
3927 if (ctx
->ctf_tc
->stream_classes
->len
!= 0) {
3929 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3934 /* Automatic ID: 0 */
3935 stream_class
->id
= 0;
3939 * Make sure that this stream class's ID is currently unique in
3942 if (ctf_trace_class_borrow_stream_class_by_id(ctx
->ctf_tc
,
3943 stream_class
->id
)) {
3945 "Duplicate stream class (same ID): id=%" PRId64
,
3951 g_ptr_array_add(ctx
->ctf_tc
->stream_classes
, stream_class
);
3952 stream_class
= NULL
;
3956 ctf_stream_class_destroy(stream_class
);
3957 stream_class
= NULL
;
3964 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3970 switch (node
->type
) {
3972 ret
= visit_field_class_def(ctx
, node
->u
.field_class_def
.field_class_specifier_list
,
3973 &node
->u
.field_class_def
.field_class_declarators
);
3976 "Cannot add field class found in trace (`trace` block).");
3980 case NODE_TYPEALIAS
:
3981 ret
= visit_field_class_alias(ctx
, node
->u
.field_class_alias
.target
,
3982 node
->u
.field_class_alias
.alias
);
3985 "Cannot add field class alias found in trace (`trace` block).");
3989 case NODE_CTF_EXPRESSION
:
3991 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3993 _BT_LOGE_NODE(node
, "Cannot concatenate unary strings.");
3998 if (!strcmp(left
, "major")) {
3999 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
4000 _BT_LOGE_DUP_ATTR(node
, "major", "trace");
4005 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4009 "Unexpected unary expression for trace's `major` attribute.");
4016 "Invalid trace's `minor` attribute: expecting 1.");
4020 ctx
->ctf_tc
->major
= val
;
4021 _SET(set
, _TRACE_MAJOR_SET
);
4022 } else if (!strcmp(left
, "minor")) {
4023 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
4024 _BT_LOGE_DUP_ATTR(node
, "minor", "trace");
4029 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
4033 "Unexpected unary expression for trace's `minor` attribute.");
4040 "Invalid trace's `minor` attribute: expecting 8.");
4044 ctx
->ctf_tc
->minor
= val
;
4045 _SET(set
, _TRACE_MINOR_SET
);
4046 } else if (!strcmp(left
, "uuid")) {
4047 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
4048 _BT_LOGE_DUP_ATTR(node
, "uuid", "trace");
4053 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
,
4057 "Invalid trace's `uuid` attribute.");
4061 ctx
->ctf_tc
->is_uuid_set
= true;
4062 _SET(set
, _TRACE_UUID_SET
);
4063 } else if (!strcmp(left
, "byte_order")) {
4064 /* Default byte order is already known at this stage */
4065 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
4066 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4072 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
!= -1);
4073 _SET(set
, _TRACE_BYTE_ORDER_SET
);
4074 } else if (!strcmp(left
, "packet.header")) {
4075 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
4077 "Duplicate `packet.header` entry in trace.");
4082 ret
= visit_field_class_specifier_list(ctx
,
4083 _BT_LIST_FIRST_ENTRY(
4084 &node
->u
.ctf_expression
.right
,
4085 struct ctf_node
, siblings
),
4086 &ctx
->ctf_tc
->packet_header_fc
);
4089 "Cannot create trace's packet header field class.");
4093 BT_ASSERT(ctx
->ctf_tc
->packet_header_fc
);
4094 _SET(set
, _TRACE_PACKET_HEADER_SET
);
4097 "Unknown attribute in stream class: "
4098 "attr-name=\"%s\"", left
);
4106 _BT_LOGE_NODE(node
, "Unknown expression in trace.");
4119 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
4123 struct ctf_node
*iter
;
4124 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
4126 if (node
->visited
) {
4130 node
->visited
= TRUE
;
4132 if (ctx
->is_trace_visited
) {
4133 _BT_LOGE_NODE(node
, "Duplicate trace (`trace` block).");
4138 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4140 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
4141 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
4143 _BT_LOGE_NODE(iter
, "Cannot visit trace's entry (`trace` block): "
4152 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
4154 "Missing `major` attribute in trace (`trace` block).");
4159 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
4161 "Missing `minor` attribute in trace (`trace` block).");
4166 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4168 "Missing `byte_order` attribute in trace (`trace` block).");
4173 ctx
->is_trace_visited
= true;
4183 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
4187 struct ctf_node
*entry_node
;
4188 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
4190 if (node
->visited
) {
4194 node
->visited
= TRUE
;
4196 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4197 struct bt_list_head
*right_head
=
4198 &entry_node
->u
.ctf_expression
.right
;
4200 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4201 _BT_LOGE_NODE(entry_node
,
4202 "Wrong expression in environment entry: "
4203 "node-type=%d", entry_node
->type
);
4208 left
= concatenate_unary_strings(
4209 &entry_node
->u
.ctf_expression
.left
);
4211 _BT_LOGE_NODE(entry_node
,
4212 "Cannot get environment entry's name.");
4217 if (is_unary_string(right_head
)) {
4218 char *right
= concatenate_unary_strings(right_head
);
4221 _BT_LOGE_NODE(entry_node
,
4222 "Unexpected unary expression for environment entry's value: "
4223 "name=\"%s\"", left
);
4228 if (strcmp(left
, "tracer_name") == 0) {
4229 if (strncmp(right
, "lttng", 5) == 0) {
4230 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4231 "tracer-name=\"%s\"",
4233 ctx
->is_lttng
= true;
4237 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4238 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
4241 } else if (is_unary_unsigned(right_head
) ||
4242 is_unary_signed(right_head
)) {
4245 if (is_unary_unsigned(right_head
)) {
4246 ret
= get_unary_unsigned(right_head
,
4249 ret
= get_unary_signed(right_head
, &v
);
4252 _BT_LOGE_NODE(entry_node
,
4253 "Unexpected unary expression for environment entry's value: "
4254 "name=\"%s\"", left
);
4259 ctf_trace_class_append_env_entry(ctx
->ctf_tc
,
4260 left
, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
4263 _BT_LOGW_NODE(entry_node
,
4264 "Environment entry has unknown type: "
4265 "name=\"%s\"", left
);
4281 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4286 struct ctf_node
*node
;
4287 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4289 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4290 if (node
->type
== NODE_CTF_EXPRESSION
) {
4291 struct ctf_node
*right_node
;
4293 left
= concatenate_unary_strings(
4294 &node
->u
.ctf_expression
.left
);
4297 "Cannot concatenate unary strings.");
4302 if (!strcmp(left
, "byte_order")) {
4303 enum ctf_byte_order bo
;
4305 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4306 _BT_LOGE_DUP_ATTR(node
, "byte_order",
4312 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4313 right_node
= _BT_LIST_FIRST_ENTRY(
4314 &node
->u
.ctf_expression
.right
,
4315 struct ctf_node
, siblings
);
4316 bo
= byte_order_from_unary_expr(right_node
);
4319 "Invalid `byte_order` attribute in trace (`trace` block): "
4320 "expecting `le`, `be`, or `network`.");
4323 } else if (bo
== CTF_BYTE_ORDER_DEFAULT
) {
4325 "Invalid `byte_order` attribute in trace (`trace` block): "
4326 "cannot be set to `native` here.");
4331 ctx
->ctf_tc
->default_byte_order
= bo
;
4339 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4340 _BT_LOGE_NODE(trace_node
,
4341 "Missing `byte_order` attribute in trace (`trace` block).");
4354 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4355 struct ctf_clock_class
*clock
, int *set
, int64_t *offset_seconds
,
4356 uint64_t *offset_cycles
)
4361 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4362 _BT_LOGE_NODE(entry_node
,
4363 "Unexpected node type: node-type=%d",
4369 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4371 _BT_LOGE_NODE(entry_node
, "Cannot concatenate unary strings.");
4376 if (!strcmp(left
, "name")) {
4379 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4380 _BT_LOGE_DUP_ATTR(entry_node
, "name", "clock class");
4385 right
= concatenate_unary_strings(
4386 &entry_node
->u
.ctf_expression
.right
);
4388 _BT_LOGE_NODE(entry_node
,
4389 "Unexpected unary expression for clock class's `name` attribute.");
4394 g_string_assign(clock
->name
, right
);
4396 _SET(set
, _CLOCK_NAME_SET
);
4397 } else if (!strcmp(left
, "uuid")) {
4398 uint8_t uuid
[BABELTRACE_UUID_LEN
];
4400 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4401 _BT_LOGE_DUP_ATTR(entry_node
, "uuid", "clock class");
4406 ret
= get_unary_uuid(&entry_node
->u
.ctf_expression
.right
, uuid
);
4408 _BT_LOGE_NODE(entry_node
,
4409 "Invalid clock class's `uuid` attribute.");
4413 clock
->has_uuid
= true;
4414 memcpy(&clock
->uuid
[0], uuid
, 16);
4415 _SET(set
, _CLOCK_UUID_SET
);
4416 } else if (!strcmp(left
, "description")) {
4419 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4420 _BT_LOGE_DUP_ATTR(entry_node
, "description",
4426 right
= concatenate_unary_strings(
4427 &entry_node
->u
.ctf_expression
.right
);
4429 _BT_LOGE_NODE(entry_node
,
4430 "Unexpected unary expression for clock class's `description` attribute.");
4435 g_string_assign(clock
->description
, right
);
4437 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4438 } else if (!strcmp(left
, "freq")) {
4439 uint64_t freq
= UINT64_C(-1);
4441 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4442 _BT_LOGE_DUP_ATTR(entry_node
, "freq", "clock class");
4447 ret
= get_unary_unsigned(
4448 &entry_node
->u
.ctf_expression
.right
, &freq
);
4450 _BT_LOGE_NODE(entry_node
,
4451 "Unexpected unary expression for clock class's `freq` attribute.");
4456 if (freq
== UINT64_C(-1) || freq
== 0) {
4457 _BT_LOGE_NODE(entry_node
,
4458 "Invalid clock class frequency: freq=%" PRIu64
,
4464 clock
->frequency
= freq
;
4465 _SET(set
, _CLOCK_FREQ_SET
);
4466 } else if (!strcmp(left
, "precision")) {
4469 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4470 _BT_LOGE_DUP_ATTR(entry_node
, "precision",
4476 ret
= get_unary_unsigned(
4477 &entry_node
->u
.ctf_expression
.right
, &precision
);
4479 _BT_LOGE_NODE(entry_node
,
4480 "Unexpected unary expression for clock class's `precision` attribute.");
4485 clock
->precision
= precision
;
4486 _SET(set
, _CLOCK_PRECISION_SET
);
4487 } else if (!strcmp(left
, "offset_s")) {
4488 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4489 _BT_LOGE_DUP_ATTR(entry_node
, "offset_s",
4495 ret
= get_unary_signed(
4496 &entry_node
->u
.ctf_expression
.right
, offset_seconds
);
4498 _BT_LOGE_NODE(entry_node
,
4499 "Unexpected unary expression for clock class's `offset_s` attribute.");
4504 _SET(set
, _CLOCK_OFFSET_S_SET
);
4505 } else if (!strcmp(left
, "offset")) {
4506 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4507 _BT_LOGE_DUP_ATTR(entry_node
, "offset", "clock class");
4512 ret
= get_unary_unsigned(
4513 &entry_node
->u
.ctf_expression
.right
, offset_cycles
);
4515 _BT_LOGE_NODE(entry_node
,
4516 "Unexpected unary expression for clock class's `offset` attribute.");
4521 _SET(set
, _CLOCK_OFFSET_SET
);
4522 } else if (!strcmp(left
, "absolute")) {
4523 struct ctf_node
*right
;
4525 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4526 _BT_LOGE_DUP_ATTR(entry_node
, "absolute",
4532 right
= _BT_LIST_FIRST_ENTRY(
4533 &entry_node
->u
.ctf_expression
.right
,
4534 struct ctf_node
, siblings
);
4535 ret
= get_boolean(right
);
4537 _BT_LOGE_NODE(entry_node
,
4538 "Unexpected unary expression for clock class's `absolute` attribute.");
4543 clock
->is_absolute
= ret
;
4544 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4546 _BT_LOGW_NODE(entry_node
,
4547 "Unknown attribute in clock class: attr-name=\"%s\"",
4561 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4566 if (frequency
== UINT64_C(1000000000)) {
4569 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4576 void calibrate_clock_class_offsets(int64_t *offset_seconds
,
4577 uint64_t *offset_cycles
, uint64_t freq
)
4579 if (*offset_cycles
>= freq
) {
4580 const uint64_t s_in_offset_cycles
= *offset_cycles
/ freq
;
4582 *offset_seconds
+= (int64_t) s_in_offset_cycles
;
4583 *offset_cycles
-= (s_in_offset_cycles
* freq
);
4588 void apply_clock_class_offset(struct ctx
*ctx
,
4589 struct ctf_clock_class
*clock
)
4592 int64_t offset_s_to_apply
= ctx
->decoder_config
.clock_class_offset_s
;
4593 uint64_t offset_ns_to_apply
;
4594 int64_t cur_offset_s
;
4595 uint64_t cur_offset_cycles
;
4597 if (ctx
->decoder_config
.clock_class_offset_s
== 0 &&
4598 ctx
->decoder_config
.clock_class_offset_ns
== 0) {
4602 /* Transfer nanoseconds to seconds as much as possible */
4603 if (ctx
->decoder_config
.clock_class_offset_ns
< 0) {
4604 const int64_t abs_ns
= -ctx
->decoder_config
.clock_class_offset_ns
;
4605 const int64_t abs_extra_s
= abs_ns
/ INT64_C(1000000000) + 1;
4606 const int64_t extra_s
= -abs_extra_s
;
4607 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4608 (extra_s
* INT64_C(1000000000));
4610 BT_ASSERT(offset_ns
> 0);
4611 offset_ns_to_apply
= (uint64_t) offset_ns
;
4612 offset_s_to_apply
+= extra_s
;
4614 const int64_t extra_s
= ctx
->decoder_config
.clock_class_offset_ns
/
4615 INT64_C(1000000000);
4616 const int64_t offset_ns
= ctx
->decoder_config
.clock_class_offset_ns
-
4617 (extra_s
* INT64_C(1000000000));
4619 BT_ASSERT(offset_ns
>= 0);
4620 offset_ns_to_apply
= (uint64_t) offset_ns
;
4621 offset_s_to_apply
+= extra_s
;
4624 freq
= clock
->frequency
;
4625 cur_offset_s
= clock
->offset_seconds
;
4626 cur_offset_cycles
= clock
->offset_cycles
;
4629 cur_offset_s
+= offset_s_to_apply
;
4630 cur_offset_cycles
+= cycles_from_ns(freq
, offset_ns_to_apply
);
4633 * Recalibrate offsets because the part in cycles can be greater
4634 * than the frequency at this point.
4636 calibrate_clock_class_offsets(&cur_offset_s
, &cur_offset_cycles
, freq
);
4638 /* Set final offsets */
4639 clock
->offset_seconds
= cur_offset_s
;
4640 clock
->offset_cycles
= cur_offset_cycles
;
4647 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
)
4651 struct ctf_clock_class
*clock
;
4652 struct ctf_node
*entry_node
;
4653 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4654 const char *clock_class_name
;
4655 int64_t offset_seconds
= 0;
4656 uint64_t offset_cycles
= 0;
4659 if (clock_node
->visited
) {
4663 clock_node
->visited
= TRUE
;
4665 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4666 clock
= ctf_clock_class_create();
4668 _BT_LOGE_NODE(clock_node
,
4669 "Cannot create default clock class.");
4674 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4675 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
,
4676 &offset_seconds
, &offset_cycles
);
4678 _BT_LOGE_NODE(entry_node
,
4679 "Cannot visit clock class's entry: ret=%d",
4685 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4686 _BT_LOGE_NODE(clock_node
,
4687 "Missing `name` attribute in clock class.");
4692 clock_class_name
= clock
->name
->str
;
4693 BT_ASSERT(clock_class_name
);
4694 if (ctx
->is_lttng
&& strcmp(clock_class_name
, "monotonic") == 0) {
4696 * Old versions of LTTng forgot to set its clock class
4697 * as absolute, even if it is. This is important because
4698 * it's a condition to be able to sort messages
4699 * from different sources.
4701 clock
->is_absolute
= true;
4705 * Adjust offsets so that the part in cycles is less than the
4706 * frequency (move to the part in seconds).
4708 freq
= clock
->frequency
;
4709 calibrate_clock_class_offsets(&offset_seconds
, &offset_cycles
, freq
);
4710 BT_ASSERT(offset_cycles
< clock
->frequency
);
4711 clock
->offset_seconds
= offset_seconds
;
4712 clock
->offset_cycles
= offset_cycles
;
4713 apply_clock_class_offset(ctx
, clock
);
4714 g_ptr_array_add(ctx
->ctf_tc
->clock_classes
, clock
);
4719 ctf_clock_class_destroy(clock
);
4726 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4730 if (root_decl_node
->visited
) {
4734 root_decl_node
->visited
= TRUE
;
4736 switch (root_decl_node
->type
) {
4738 ret
= visit_field_class_def(ctx
,
4739 root_decl_node
->u
.field_class_def
.field_class_specifier_list
,
4740 &root_decl_node
->u
.field_class_def
.field_class_declarators
);
4742 _BT_LOGE_NODE(root_decl_node
,
4743 "Cannot add field class found in root scope.");
4747 case NODE_TYPEALIAS
:
4748 ret
= visit_field_class_alias(ctx
, root_decl_node
->u
.field_class_alias
.target
,
4749 root_decl_node
->u
.field_class_alias
.alias
);
4751 _BT_LOGE_NODE(root_decl_node
,
4752 "Cannot add field class alias found in root scope.");
4756 case NODE_TYPE_SPECIFIER_LIST
:
4758 struct ctf_field_class
*decl
= NULL
;
4761 * Just add the field class specifier to the root
4762 * declaration scope. Put local reference.
4764 ret
= visit_field_class_specifier_list(ctx
, root_decl_node
, &decl
);
4766 _BT_LOGE_NODE(root_decl_node
,
4767 "Cannot visit root scope's field class: "
4773 ctf_field_class_destroy(decl
);
4778 _BT_LOGE_NODE(root_decl_node
,
4779 "Unexpected node type: node-type=%d",
4780 root_decl_node
->type
);
4790 struct ctf_visitor_generate_ir
*ctf_visitor_generate_ir_create(
4791 bt_self_component_source
*self_comp
,
4792 const struct ctf_metadata_decoder_config
*decoder_config
)
4794 struct ctx
*ctx
= NULL
;
4796 /* Create visitor's context */
4797 ctx
= ctx_create(self_comp
, decoder_config
);
4799 BT_LOGE_STR("Cannot create visitor's context.");
4810 return (void *) ctx
;
4814 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir
*visitor
)
4816 ctx_destroy((void *) visitor
);
4820 bt_trace_class
*ctf_visitor_generate_ir_get_ir_trace_class(
4821 struct ctf_visitor_generate_ir
*visitor
)
4823 struct ctx
*ctx
= (void *) visitor
;
4827 if (ctx
->trace_class
) {
4828 bt_trace_class_get_ref(ctx
->trace_class
);
4831 return ctx
->trace_class
;
4835 struct ctf_trace_class
*ctf_visitor_generate_ir_borrow_ctf_trace_class(
4836 struct ctf_visitor_generate_ir
*visitor
)
4838 struct ctx
*ctx
= (void *) visitor
;
4841 BT_ASSERT(ctx
->ctf_tc
);
4846 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir
*visitor
,
4847 struct ctf_node
*node
)
4850 struct ctx
*ctx
= (void *) visitor
;
4852 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4854 switch (node
->type
) {
4857 struct ctf_node
*iter
;
4858 bool got_trace_decl
= false;
4861 * The first thing we need is the native byte order of
4862 * the trace block, because early class aliases can have
4863 * a `byte_order` attribute set to `native`. If we don't
4864 * have the native byte order yet, and we don't have any
4865 * trace block yet, then fail with EINCOMPLETE.
4867 if (ctx
->ctf_tc
->default_byte_order
== -1) {
4868 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4869 if (got_trace_decl
) {
4871 "Duplicate trace (`trace` block).");
4876 ret
= set_trace_byte_order(ctx
, iter
);
4879 "Cannot set trace's native byte order: "
4884 got_trace_decl
= true;
4887 if (!got_trace_decl
) {
4888 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4894 BT_ASSERT(ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_LITTLE
||
4895 ctx
->ctf_tc
->default_byte_order
== CTF_BYTE_ORDER_BIG
);
4896 BT_ASSERT(ctx
->current_scope
&&
4897 ctx
->current_scope
->parent_scope
== NULL
);
4900 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4901 ret
= visit_env(ctx
, iter
);
4904 "Cannot visit trace's environment (`env` block) entry: "
4910 BT_ASSERT(ctx
->current_scope
&&
4911 ctx
->current_scope
->parent_scope
== NULL
);
4914 * Visit clock blocks.
4916 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4917 ret
= visit_clock_decl(ctx
, iter
);
4920 "Cannot visit clock class: ret=%d",
4926 BT_ASSERT(ctx
->current_scope
&&
4927 ctx
->current_scope
->parent_scope
== NULL
);
4930 * Visit root declarations next, as they can be used by any
4933 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4935 ret
= visit_root_decl(ctx
, iter
);
4938 "Cannot visit root entry: ret=%d",
4944 BT_ASSERT(ctx
->current_scope
&&
4945 ctx
->current_scope
->parent_scope
== NULL
);
4947 /* Callsite blocks are not supported */
4948 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4950 "\"callsite\" blocks are not supported as of this version.");
4953 BT_ASSERT(ctx
->current_scope
&&
4954 ctx
->current_scope
->parent_scope
== NULL
);
4957 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4958 ret
= visit_trace_decl(ctx
, iter
);
4961 "Cannot visit trace (`trace` block): "
4967 BT_ASSERT(ctx
->current_scope
&&
4968 ctx
->current_scope
->parent_scope
== NULL
);
4971 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4972 ret
= visit_stream_decl(ctx
, iter
);
4975 "Cannot visit stream class: ret=%d",
4981 BT_ASSERT(ctx
->current_scope
&&
4982 ctx
->current_scope
->parent_scope
== NULL
);
4985 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4986 ret
= visit_event_decl(ctx
, iter
);
4989 "Cannot visit event class: ret=%d",
4995 BT_ASSERT(ctx
->current_scope
&&
4996 ctx
->current_scope
->parent_scope
== NULL
);
5001 "Unexpected node type: node-type=%d",
5007 /* Update default clock classes */
5008 ret
= ctf_trace_class_update_default_clock_classes(ctx
->ctf_tc
);
5014 /* Update trace class meanings */
5015 ret
= ctf_trace_class_update_meanings(ctx
->ctf_tc
);
5021 /* Update stream class configuration */
5022 ret
= ctf_trace_class_update_stream_class_config(ctx
->ctf_tc
);
5028 /* Update text arrays and sequences */
5029 ret
= ctf_trace_class_update_text_array_sequence(ctx
->ctf_tc
);
5035 /* Resolve sequence lengths and variant tags */
5036 ret
= ctf_trace_class_resolve_field_classes(ctx
->ctf_tc
);
5042 if (ctx
->trace_class
) {
5044 * Update "in IR" for field classes.
5046 * If we have no IR trace class, then we'll have no way
5047 * to create IR fields anyway, so we leave all the
5048 * `in_ir` members false.
5050 ret
= ctf_trace_class_update_in_ir(ctx
->ctf_tc
);
5057 /* Update saved value indexes */
5058 ret
= ctf_trace_class_update_value_storing_indexes(ctx
->ctf_tc
);
5064 /* Validate what we have so far */
5065 ret
= ctf_trace_class_validate(ctx
->ctf_tc
);
5072 * If there are fields which are not related to the CTF format
5073 * itself in the packet header and in event header field
5074 * classes, warn about it because they are never translated.
5076 ctf_trace_class_warn_meaningless_header_fields(ctx
->ctf_tc
);
5078 if (ctx
->trace_class
) {
5079 /* Copy new CTF metadata -> new IR metadata */
5080 ret
= ctf_trace_class_translate(ctx
->self_comp
,
5081 ctx
->trace_class
, ctx
->ctf_tc
);