* Common Trace Format metadata visitor (generates CTF IR objects).
*/
-#define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp)
+#define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp)
#define BT_COMP_LOG_SELF_COMP_CLASS (ctx->log_cfg.self_comp_class)
-#define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level)
-#define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
+#define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level)
+#define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR"
#include "logging/comp-logging.h"
#include <stdio.h>
#include "ctf-meta-visitors.hpp"
/* Bit value (left shift) */
-#define _BV(_val) (1 << (_val))
+#define _BV(_val) (1 << (_val))
/* Bit is set in a set of bits */
-#define _IS_SET(_set, _mask) (*(_set) & (_mask))
+#define _IS_SET(_set, _mask) (*(_set) & (_mask))
/* Set bit in a set of bits */
-#define _SET(_set, _mask) (*(_set) |= (_mask))
+#define _SET(_set, _mask) (*(_set) |= (_mask))
/* Try to push scope, or go to the `error` label */
-#define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
- do { \
- ret = ctx_push_scope(ctx); \
- if (ret) { \
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push scope."); \
- goto error; \
- } \
- } while (0)
+#define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
+ do { \
+ ret = ctx_push_scope(ctx); \
+ if (ret) { \
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push scope."); \
+ goto error; \
+ } \
+ } while (0)
/* Bits for verifying existing attributes in various declarations */
-enum {
- _CLOCK_NAME_SET = _BV(0),
- _CLOCK_UUID_SET = _BV(1),
- _CLOCK_FREQ_SET = _BV(2),
- _CLOCK_PRECISION_SET = _BV(3),
- _CLOCK_OFFSET_S_SET = _BV(4),
- _CLOCK_OFFSET_SET = _BV(5),
- _CLOCK_ABSOLUTE_SET = _BV(6),
- _CLOCK_DESCRIPTION_SET = _BV(7),
+enum
+{
+ _CLOCK_NAME_SET = _BV(0),
+ _CLOCK_UUID_SET = _BV(1),
+ _CLOCK_FREQ_SET = _BV(2),
+ _CLOCK_PRECISION_SET = _BV(3),
+ _CLOCK_OFFSET_S_SET = _BV(4),
+ _CLOCK_OFFSET_SET = _BV(5),
+ _CLOCK_ABSOLUTE_SET = _BV(6),
+ _CLOCK_DESCRIPTION_SET = _BV(7),
};
-enum {
- _INTEGER_ALIGN_SET = _BV(0),
- _INTEGER_SIZE_SET = _BV(1),
- _INTEGER_BASE_SET = _BV(2),
- _INTEGER_ENCODING_SET = _BV(3),
- _INTEGER_BYTE_ORDER_SET = _BV(4),
- _INTEGER_SIGNED_SET = _BV(5),
- _INTEGER_MAP_SET = _BV(6),
+enum
+{
+ _INTEGER_ALIGN_SET = _BV(0),
+ _INTEGER_SIZE_SET = _BV(1),
+ _INTEGER_BASE_SET = _BV(2),
+ _INTEGER_ENCODING_SET = _BV(3),
+ _INTEGER_BYTE_ORDER_SET = _BV(4),
+ _INTEGER_SIGNED_SET = _BV(5),
+ _INTEGER_MAP_SET = _BV(6),
};
-enum {
- _FLOAT_ALIGN_SET = _BV(0),
- _FLOAT_MANT_DIG_SET = _BV(1),
- _FLOAT_EXP_DIG_SET = _BV(2),
- _FLOAT_BYTE_ORDER_SET = _BV(3),
+enum
+{
+ _FLOAT_ALIGN_SET = _BV(0),
+ _FLOAT_MANT_DIG_SET = _BV(1),
+ _FLOAT_EXP_DIG_SET = _BV(2),
+ _FLOAT_BYTE_ORDER_SET = _BV(3),
};
-enum {
- _STRING_ENCODING_SET = _BV(0),
+enum
+{
+ _STRING_ENCODING_SET = _BV(0),
};
-enum {
- _TRACE_MINOR_SET = _BV(0),
- _TRACE_MAJOR_SET = _BV(1),
- _TRACE_BYTE_ORDER_SET = _BV(2),
- _TRACE_UUID_SET = _BV(3),
- _TRACE_PACKET_HEADER_SET = _BV(4),
+enum
+{
+ _TRACE_MINOR_SET = _BV(0),
+ _TRACE_MAJOR_SET = _BV(1),
+ _TRACE_BYTE_ORDER_SET = _BV(2),
+ _TRACE_UUID_SET = _BV(3),
+ _TRACE_PACKET_HEADER_SET = _BV(4),
};
-enum {
- _STREAM_ID_SET = _BV(0),
- _STREAM_PACKET_CONTEXT_SET = _BV(1),
- _STREAM_EVENT_HEADER_SET = _BV(2),
- _STREAM_EVENT_CONTEXT_SET = _BV(3),
+enum
+{
+ _STREAM_ID_SET = _BV(0),
+ _STREAM_PACKET_CONTEXT_SET = _BV(1),
+ _STREAM_EVENT_HEADER_SET = _BV(2),
+ _STREAM_EVENT_CONTEXT_SET = _BV(3),
};
-enum {
- _EVENT_NAME_SET = _BV(0),
- _EVENT_ID_SET = _BV(1),
- _EVENT_MODEL_EMF_URI_SET = _BV(2),
- _EVENT_STREAM_ID_SET = _BV(3),
- _EVENT_LOG_LEVEL_SET = _BV(4),
- _EVENT_CONTEXT_SET = _BV(5),
- _EVENT_FIELDS_SET = _BV(6),
+enum
+{
+ _EVENT_NAME_SET = _BV(0),
+ _EVENT_ID_SET = _BV(1),
+ _EVENT_MODEL_EMF_URI_SET = _BV(2),
+ _EVENT_STREAM_ID_SET = _BV(3),
+ _EVENT_LOG_LEVEL_SET = _BV(4),
+ _EVENT_CONTEXT_SET = _BV(5),
+ _EVENT_FIELDS_SET = _BV(6),
};
-enum loglevel {
- LOG_LEVEL_EMERG = 0,
- LOG_LEVEL_ALERT = 1,
- LOG_LEVEL_CRIT = 2,
- LOG_LEVEL_ERR = 3,
- LOG_LEVEL_WARNING = 4,
- LOG_LEVEL_NOTICE = 5,
- LOG_LEVEL_INFO = 6,
- LOG_LEVEL_DEBUG_SYSTEM = 7,
- LOG_LEVEL_DEBUG_PROGRAM = 8,
- LOG_LEVEL_DEBUG_PROCESS = 9,
- LOG_LEVEL_DEBUG_MODULE = 10,
- LOG_LEVEL_DEBUG_UNIT = 11,
- LOG_LEVEL_DEBUG_FUNCTION = 12,
- LOG_LEVEL_DEBUG_LINE = 13,
- LOG_LEVEL_DEBUG = 14,
- _NR_LOGLEVELS = 15,
+enum loglevel
+{
+ LOG_LEVEL_EMERG = 0,
+ LOG_LEVEL_ALERT = 1,
+ LOG_LEVEL_CRIT = 2,
+ LOG_LEVEL_ERR = 3,
+ LOG_LEVEL_WARNING = 4,
+ LOG_LEVEL_NOTICE = 5,
+ LOG_LEVEL_INFO = 6,
+ LOG_LEVEL_DEBUG_SYSTEM = 7,
+ LOG_LEVEL_DEBUG_PROGRAM = 8,
+ LOG_LEVEL_DEBUG_PROCESS = 9,
+ LOG_LEVEL_DEBUG_MODULE = 10,
+ LOG_LEVEL_DEBUG_UNIT = 11,
+ LOG_LEVEL_DEBUG_FUNCTION = 12,
+ LOG_LEVEL_DEBUG_LINE = 13,
+ LOG_LEVEL_DEBUG = 14,
+ _NR_LOGLEVELS = 15,
};
/* Prefixes of class aliases */
-#define _PREFIX_ALIAS 'a'
-#define _PREFIX_ENUM 'e'
-#define _PREFIX_STRUCT 's'
-#define _PREFIX_VARIANT 'v'
+#define _PREFIX_ALIAS 'a'
+#define _PREFIX_ENUM 'e'
+#define _PREFIX_STRUCT 's'
+#define _PREFIX_VARIANT 'v'
/* First entry in a BT list */
-#define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
- bt_list_entry((_ptr)->next, _class, _member)
+#define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) bt_list_entry((_ptr)->next, _class, _member)
-#define _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(_node, _attr, _entity) \
- _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, \
- "Duplicate attribute in %s: attr-name=\"%s\"", \
- _entity, _attr)
+#define _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(_node, _attr, _entity) \
+ _BT_COMP_LOGE_APPEND_CAUSE_LINENO( \
+ (_node)->lineno, "Duplicate attribute in %s: attr-name=\"%s\"", _entity, _attr)
-#define _BT_COMP_LOGE_NODE(_node, _msg, args...) \
- _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args)
+#define _BT_COMP_LOGE_NODE(_node, _msg, args...) _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ##args)
-#define _BT_COMP_LOGE_APPEND_CAUSE_NODE(_node, _msg, args...) \
- _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, _msg, ## args)
+#define _BT_COMP_LOGE_APPEND_CAUSE_NODE(_node, _msg, args...) \
+ _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, _msg, ##args)
-#define _BT_COMP_LOGW_NODE(_node, _msg, args...) \
- _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args)
+#define _BT_COMP_LOGW_NODE(_node, _msg, args...) _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ##args)
-#define _BT_COMP_LOGT_NODE(_node, _msg, args...) \
- _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args)
+#define _BT_COMP_LOGT_NODE(_node, _msg, args...) _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ##args)
/*
* Declaration scope of a visitor context. This represents a TSDL
* lexical scope, so that aliases and named structures, variants,
* and enumerations may be registered and looked up hierarchically.
*/
-struct ctx_decl_scope {
- /*
- * Alias name to field class.
- *
- * GQuark -> struct ctf_field_class * (owned by this)
- */
- GHashTable *decl_map;
-
- /* Parent scope; NULL if this is the root declaration scope */
- struct ctx_decl_scope *parent_scope;
+struct ctx_decl_scope
+{
+ /*
+ * Alias name to field class.
+ *
+ * GQuark -> struct ctf_field_class * (owned by this)
+ */
+ GHashTable *decl_map;
+
+ /* Parent scope; NULL if this is the root declaration scope */
+ struct ctx_decl_scope *parent_scope;
};
/*
* Visitor context (private).
*/
-struct ctf_visitor_generate_ir {
- struct meta_log_config log_cfg;
+struct ctf_visitor_generate_ir
+{
+ struct meta_log_config log_cfg;
- /* Trace IR trace class being filled (owned by this) */
- bt_trace_class *trace_class;
+ /* Trace IR trace class being filled (owned by this) */
+ bt_trace_class *trace_class;
- /* CTF meta trace being filled (owned by this) */
- struct ctf_trace_class *ctf_tc;
+ /* CTF meta trace being filled (owned by this) */
+ struct ctf_trace_class *ctf_tc;
- /* Current declaration scope (top of the stack) (owned by this) */
- struct ctx_decl_scope *current_scope;
+ /* Current declaration scope (top of the stack) (owned by this) */
+ struct ctx_decl_scope *current_scope;
- /* True if trace declaration is visited */
- bool is_trace_visited;
+ /* True if trace declaration is visited */
+ bool is_trace_visited;
- /* True if this is an LTTng trace */
- bool is_lttng;
+ /* True if this is an LTTng trace */
+ bool is_lttng;
- /* Config passed by the user */
- struct ctf_metadata_decoder_config decoder_config;
+ /* Config passed by the user */
+ struct ctf_metadata_decoder_config decoder_config;
};
/*
* @param par_scope Parent scope (NULL if creating a root scope)
* @returns New declaration scope, or NULL on error
*/
-static
-struct ctx_decl_scope *ctx_decl_scope_create(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *par_scope)
+static struct ctx_decl_scope *ctx_decl_scope_create(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *par_scope)
{
- struct ctx_decl_scope *scope;
+ struct ctx_decl_scope *scope;
- scope = g_new(struct ctx_decl_scope, 1);
- if (!scope) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one declaration scope.");
- goto end;
- }
+ scope = g_new(struct ctx_decl_scope, 1);
+ if (!scope) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one declaration scope.");
+ goto end;
+ }
- scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify) ctf_field_class_destroy);
- scope->parent_scope = par_scope;
+ scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+ (GDestroyNotify) ctf_field_class_destroy);
+ scope->parent_scope = par_scope;
end:
- return scope;
+ return scope;
}
/**
*
* @param scope Scope to destroy
*/
-static
-void ctx_decl_scope_destroy(struct ctx_decl_scope *scope)
+static void ctx_decl_scope_destroy(struct ctx_decl_scope *scope)
{
- if (!scope) {
- goto end;
- }
+ if (!scope) {
+ goto end;
+ }
- g_hash_table_destroy(scope->decl_map);
- g_free(scope);
+ g_hash_table_destroy(scope->decl_map);
+ g_free(scope);
end:
- return;
+ return;
}
/**
* @param name Name
* @returns Associated GQuark, or 0 on error
*/
-static
-GQuark get_prefixed_named_quark(struct ctf_visitor_generate_ir *ctx, char prefix,
- const char *name)
+static GQuark get_prefixed_named_quark(struct ctf_visitor_generate_ir *ctx, char prefix,
+ const char *name)
{
- GQuark qname = 0;
+ GQuark qname = 0;
- BT_ASSERT(name);
+ BT_ASSERT(name);
- /* Prefix character + original string + '\0' */
- char *prname = g_new(char, strlen(name) + 2);
- if (!prname) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate a string.");
- goto end;
- }
+ /* Prefix character + original string + '\0' */
+ char *prname = g_new(char, strlen(name) + 2);
+ if (!prname) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate a string.");
+ goto end;
+ }
- sprintf(prname, "%c%s", prefix, name);
- qname = g_quark_from_string(prname);
- g_free(prname);
+ sprintf(prname, "%c%s", prefix, name);
+ qname = g_quark_from_string(prname);
+ g_free(prname);
end:
- return qname;
+ return qname;
}
/**
* @returns Declaration (owned by caller if \p copy is true),
* or NULL if not found
*/
-static
-struct ctf_field_class *ctx_decl_scope_lookup_prefix_alias(
- struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope, char prefix,
- const char *name, int levels, bool copy)
+static struct ctf_field_class *
+ctx_decl_scope_lookup_prefix_alias(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, char prefix, const char *name,
+ int levels, bool copy)
{
- GQuark qname = 0;
- int cur_levels = 0;
- struct ctf_field_class *decl = NULL;
- struct ctx_decl_scope *cur_scope = scope;
-
- BT_ASSERT(scope);
- BT_ASSERT(name);
- qname = get_prefixed_named_quark(ctx, prefix, name);
- if (!qname) {
- goto end;
- }
-
- if (levels < 0) {
- levels = INT_MAX;
- }
-
- while (cur_scope && cur_levels < levels) {
- decl = (ctf_field_class *) g_hash_table_lookup(cur_scope->decl_map,
- (gconstpointer) GUINT_TO_POINTER(qname));
- if (decl) {
- /* Caller's reference */
- if (copy) {
- decl = ctf_field_class_copy(decl);
- BT_ASSERT(decl);
- }
-
- goto end;
- }
-
- cur_scope = cur_scope->parent_scope;
- cur_levels++;
- }
+ GQuark qname = 0;
+ int cur_levels = 0;
+ struct ctf_field_class *decl = NULL;
+ struct ctx_decl_scope *cur_scope = scope;
+
+ BT_ASSERT(scope);
+ BT_ASSERT(name);
+ qname = get_prefixed_named_quark(ctx, prefix, name);
+ if (!qname) {
+ goto end;
+ }
+
+ if (levels < 0) {
+ levels = INT_MAX;
+ }
+
+ while (cur_scope && cur_levels < levels) {
+ decl = (ctf_field_class *) g_hash_table_lookup(cur_scope->decl_map,
+ (gconstpointer) GUINT_TO_POINTER(qname));
+ if (decl) {
+ /* Caller's reference */
+ if (copy) {
+ decl = ctf_field_class_copy(decl);
+ BT_ASSERT(decl);
+ }
+
+ goto end;
+ }
+
+ cur_scope = cur_scope->parent_scope;
+ cur_levels++;
+ }
end:
- return decl;
+ return decl;
}
/**
* @returns Declaration (owned by caller if \p copy is true),
* or NULL if not found
*/
-static
-struct ctf_field_class *ctx_decl_scope_lookup_alias(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name, int levels,
- bool copy)
+static struct ctf_field_class *ctx_decl_scope_lookup_alias(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope,
+ const char *name, int levels, bool copy)
{
- return ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ALIAS,
- name, levels, copy);
+ return ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ALIAS, name, levels, copy);
}
/**
* @returns Declaration (owned by caller if \p copy is true),
* or NULL if not found
*/
-static
-struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name, int levels,
- bool copy)
+static struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope,
+ const char *name, int levels,
+ bool copy)
{
- return ctf_field_class_as_enum(ctx_decl_scope_lookup_prefix_alias(ctx, scope,
- _PREFIX_ENUM, name, levels, copy));
+ return ctf_field_class_as_enum(
+ ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ENUM, name, levels, copy));
}
/**
* @returns Declaration (owned by caller if \p copy is true),
* or NULL if not found
*/
-static
-struct ctf_field_class_struct *ctx_decl_scope_lookup_struct(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name, int levels,
- bool copy)
+static struct ctf_field_class_struct *
+ctx_decl_scope_lookup_struct(struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope,
+ const char *name, int levels, bool copy)
{
- return ctf_field_class_as_struct(ctx_decl_scope_lookup_prefix_alias(ctx, scope,
- _PREFIX_STRUCT, name, levels, copy));
+ return ctf_field_class_as_struct(
+ ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_STRUCT, name, levels, copy));
}
/**
* @returns Declaration (owned by caller if \p copy is true),
* or NULL if not found
*/
-static
-struct ctf_field_class_variant *ctx_decl_scope_lookup_variant(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name, int levels,
- bool copy)
+static struct ctf_field_class_variant *
+ctx_decl_scope_lookup_variant(struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope,
+ const char *name, int levels, bool copy)
{
- return ctf_field_class_as_variant(ctx_decl_scope_lookup_prefix_alias(ctx, scope,
- _PREFIX_VARIANT, name, levels, copy));
+ return ctf_field_class_as_variant(
+ ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_VARIANT, name, levels, copy));
}
/**
* @param decl Field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
-static
-int ctx_decl_scope_register_prefix_alias(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, char prefix, const char *name,
- struct ctf_field_class *decl)
+static int ctx_decl_scope_register_prefix_alias(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, char prefix,
+ const char *name, struct ctf_field_class *decl)
{
- int ret = 0;
- GQuark qname = 0;
-
- BT_ASSERT(scope);
- BT_ASSERT(name);
- BT_ASSERT(decl);
- qname = get_prefixed_named_quark(ctx, prefix, name);
- if (!qname) {
- ret = -ENOMEM;
- goto end;
- }
-
- /* Make sure alias does not exist in local scope */
- if (ctx_decl_scope_lookup_prefix_alias(ctx, scope, prefix, name, 1,
- false)) {
- ret = -EEXIST;
- goto end;
- }
-
- decl = ctf_field_class_copy(decl);
- BT_ASSERT(decl);
- g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl);
+ int ret = 0;
+ GQuark qname = 0;
+
+ BT_ASSERT(scope);
+ BT_ASSERT(name);
+ BT_ASSERT(decl);
+ qname = get_prefixed_named_quark(ctx, prefix, name);
+ if (!qname) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ /* Make sure alias does not exist in local scope */
+ if (ctx_decl_scope_lookup_prefix_alias(ctx, scope, prefix, name, 1, false)) {
+ ret = -EEXIST;
+ goto end;
+ }
+
+ decl = ctf_field_class_copy(decl);
+ BT_ASSERT(decl);
+ g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl);
end:
- return ret;
+ return ret;
}
/**
* @param decl Field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
-static
-int ctx_decl_scope_register_alias(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name, struct ctf_field_class *decl)
+static int ctx_decl_scope_register_alias(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, const char *name,
+ struct ctf_field_class *decl)
{
- return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ALIAS,
- name, decl);
+ return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ALIAS, name, decl);
}
/**
* @param decl Enumeration field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
-static
-int ctx_decl_scope_register_enum(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name,
- struct ctf_field_class_enum *decl)
+static int ctx_decl_scope_register_enum(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, const char *name,
+ struct ctf_field_class_enum *decl)
{
- return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ENUM,
- name, &decl->base.base.base);
+ return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ENUM, name,
+ &decl->base.base.base);
}
/**
* @param decl Structure field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
-static
-int ctx_decl_scope_register_struct(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name,
- struct ctf_field_class_struct *decl)
+static int ctx_decl_scope_register_struct(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, const char *name,
+ struct ctf_field_class_struct *decl)
{
- return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_STRUCT,
- name, &decl->base);
+ return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_STRUCT, name, &decl->base);
}
/**
* @param decl Variant field class to register
* @returns 0 if registration went okay, negative value otherwise
*/
-static
-int ctx_decl_scope_register_variant(struct ctf_visitor_generate_ir *ctx,
- struct ctx_decl_scope *scope, const char *name,
- struct ctf_field_class_variant *decl)
+static int ctx_decl_scope_register_variant(struct ctf_visitor_generate_ir *ctx,
+ struct ctx_decl_scope *scope, const char *name,
+ struct ctf_field_class_variant *decl)
{
- return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_VARIANT,
- name, &decl->base);
+ return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_VARIANT, name, &decl->base);
}
/**
*
* @param ctx Visitor context to destroy
*/
-static
-void ctx_destroy(struct ctf_visitor_generate_ir *ctx)
+static void ctx_destroy(struct ctf_visitor_generate_ir *ctx)
{
- struct ctx_decl_scope *scope;
+ struct ctx_decl_scope *scope;
- if (!ctx) {
- goto end;
- }
+ if (!ctx) {
+ goto end;
+ }
- scope = ctx->current_scope;
+ scope = ctx->current_scope;
- /*
- * Destroy all scopes, from current one to the root scope.
- */
- while (scope) {
- struct ctx_decl_scope *parent_scope = scope->parent_scope;
+ /*
+ * Destroy all scopes, from current one to the root scope.
+ */
+ while (scope) {
+ struct ctx_decl_scope *parent_scope = scope->parent_scope;
- ctx_decl_scope_destroy(scope);
- scope = parent_scope;
- }
+ ctx_decl_scope_destroy(scope);
+ scope = parent_scope;
+ }
- bt_trace_class_put_ref(ctx->trace_class);
+ bt_trace_class_put_ref(ctx->trace_class);
- if (ctx->ctf_tc) {
- ctf_trace_class_destroy(ctx->ctf_tc);
- }
+ if (ctx->ctf_tc) {
+ ctf_trace_class_destroy(ctx->ctf_tc);
+ }
- g_free(ctx);
+ g_free(ctx);
end:
- return;
+ return;
}
/**
* @param trace Associated trace
* @returns New visitor context, or NULL on error
*/
-static
-struct ctf_visitor_generate_ir *ctx_create(
- const struct ctf_metadata_decoder_config *decoder_config)
+static struct ctf_visitor_generate_ir *
+ctx_create(const struct ctf_metadata_decoder_config *decoder_config)
{
- struct ctf_visitor_generate_ir *ctx = NULL;
-
- BT_ASSERT(decoder_config);
-
- ctx = g_new0(struct ctf_visitor_generate_ir, 1);
- if (!ctx) {
- BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level,
- decoder_config->self_comp,
- "Failed to allocate one visitor context.");
- goto error;
- }
-
- ctx->log_cfg.log_level = decoder_config->log_level;
- ctx->log_cfg.self_comp = decoder_config->self_comp;
- ctx->log_cfg.self_comp_class = decoder_config->self_comp_class;
-
- if (decoder_config->self_comp) {
- ctx->trace_class = bt_trace_class_create(
- decoder_config->self_comp);
- if (!ctx->trace_class) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create empty trace class.");
- goto error;
- }
- }
-
- ctx->ctf_tc = ctf_trace_class_create();
- if (!ctx->ctf_tc) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create CTF trace class.");
- goto error;
- }
-
- /* Root declaration scope */
- ctx->current_scope = ctx_decl_scope_create(ctx, NULL);
- if (!ctx->current_scope) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope.");
- goto error;
- }
-
- ctx->decoder_config = *decoder_config;
- goto end;
+ struct ctf_visitor_generate_ir *ctx = NULL;
+
+ BT_ASSERT(decoder_config);
+
+ ctx = g_new0(struct ctf_visitor_generate_ir, 1);
+ if (!ctx) {
+ BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, decoder_config->self_comp,
+ "Failed to allocate one visitor context.");
+ goto error;
+ }
+
+ ctx->log_cfg.log_level = decoder_config->log_level;
+ ctx->log_cfg.self_comp = decoder_config->self_comp;
+ ctx->log_cfg.self_comp_class = decoder_config->self_comp_class;
+
+ if (decoder_config->self_comp) {
+ ctx->trace_class = bt_trace_class_create(decoder_config->self_comp);
+ if (!ctx->trace_class) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create empty trace class.");
+ goto error;
+ }
+ }
+
+ ctx->ctf_tc = ctf_trace_class_create();
+ if (!ctx->ctf_tc) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create CTF trace class.");
+ goto error;
+ }
+
+ /* Root declaration scope */
+ ctx->current_scope = ctx_decl_scope_create(ctx, NULL);
+ if (!ctx->current_scope) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope.");
+ goto error;
+ }
+
+ ctx->decoder_config = *decoder_config;
+ goto end;
error:
- ctx_destroy(ctx);
- ctx = NULL;
+ ctx_destroy(ctx);
+ ctx = NULL;
end:
- return ctx;
+ return ctx;
}
/**
* @param ctx Visitor context
* @returns 0 on success, or a negative value on error
*/
-static
-int ctx_push_scope(struct ctf_visitor_generate_ir *ctx)
+static int ctx_push_scope(struct ctf_visitor_generate_ir *ctx)
{
- int ret = 0;
- struct ctx_decl_scope *new_scope;
+ int ret = 0;
+ struct ctx_decl_scope *new_scope;
- BT_ASSERT(ctx);
- new_scope = ctx_decl_scope_create(ctx, ctx->current_scope);
- if (!new_scope) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope.");
- ret = -ENOMEM;
- goto end;
- }
+ BT_ASSERT(ctx);
+ new_scope = ctx_decl_scope_create(ctx, ctx->current_scope);
+ if (!new_scope) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope.");
+ ret = -ENOMEM;
+ goto end;
+ }
- ctx->current_scope = new_scope;
+ ctx->current_scope = new_scope;
end:
- return ret;
+ return ret;
}
-static
-void ctx_pop_scope(struct ctf_visitor_generate_ir *ctx)
+static void ctx_pop_scope(struct ctf_visitor_generate_ir *ctx)
{
- struct ctx_decl_scope *parent_scope = NULL;
+ struct ctx_decl_scope *parent_scope = NULL;
- BT_ASSERT(ctx);
+ BT_ASSERT(ctx);
- if (!ctx->current_scope) {
- goto end;
- }
+ if (!ctx->current_scope) {
+ goto end;
+ }
- parent_scope = ctx->current_scope->parent_scope;
- ctx_decl_scope_destroy(ctx->current_scope);
- ctx->current_scope = parent_scope;
+ parent_scope = ctx->current_scope->parent_scope;
+ ctx_decl_scope_destroy(ctx->current_scope);
+ ctx->current_scope = parent_scope;
end:
- return;
+ return;
}
-static
-int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *ts_list, struct ctf_field_class **decl);
+static int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *ts_list,
+ struct ctf_field_class **decl);
-static
-int is_unary_string(struct bt_list_head *head)
+static int is_unary_string(struct bt_list_head *head)
{
- int ret = TRUE;
- struct ctf_node *node;
+ int ret = TRUE;
+ struct ctf_node *node;
- bt_list_for_each_entry(node, head, siblings) {
- if (node->type != NODE_UNARY_EXPRESSION) {
- ret = FALSE;
- }
+ bt_list_for_each_entry (node, head, siblings) {
+ if (node->type != NODE_UNARY_EXPRESSION) {
+ ret = FALSE;
+ }
- if (node->u.unary_expression.type != UNARY_STRING) {
- ret = FALSE;
- }
- }
+ if (node->u.unary_expression.type != UNARY_STRING) {
+ ret = FALSE;
+ }
+ }
- return ret;
+ return ret;
}
-static
-const char *get_map_clock_name_value(struct bt_list_head *head)
+static const char *get_map_clock_name_value(struct bt_list_head *head)
{
- int i = 0;
- struct ctf_node *node;
- const char *name = NULL;
-
- bt_list_for_each_entry(node, head, siblings) {
- char *src_string;
- int uexpr_type = node->u.unary_expression.type;
- int uexpr_link = node->u.unary_expression.link;
- int cond = node->type != NODE_UNARY_EXPRESSION ||
- uexpr_type != UNARY_STRING ||
- !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0));
- if (cond) {
- goto error;
- }
-
- /* Needs to be chained with . */
- switch (node->u.unary_expression.link) {
- case UNARY_DOTLINK:
- break;
- case UNARY_ARROWLINK:
- case UNARY_DOTDOTDOT:
- goto error;
- default:
- break;
- }
-
- src_string = node->u.unary_expression.u.string;
-
- switch (i) {
- case 0:
- if (strcmp("clock", src_string)) {
- goto error;
- }
- break;
- case 1:
- name = src_string;
- break;
- case 2:
- if (strcmp("value", src_string)) {
- goto error;
- }
- break;
- default:
- /* Extra identifier, unknown */
- goto error;
- }
-
- i++;
- }
-
- return name;
+ int i = 0;
+ struct ctf_node *node;
+ const char *name = NULL;
+
+ bt_list_for_each_entry (node, head, siblings) {
+ char *src_string;
+ int uexpr_type = node->u.unary_expression.type;
+ int uexpr_link = node->u.unary_expression.link;
+ int cond = node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_STRING ||
+ !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0));
+ if (cond) {
+ goto error;
+ }
+
+ /* Needs to be chained with . */
+ switch (node->u.unary_expression.link) {
+ case UNARY_DOTLINK:
+ break;
+ case UNARY_ARROWLINK:
+ case UNARY_DOTDOTDOT:
+ goto error;
+ default:
+ break;
+ }
+
+ src_string = node->u.unary_expression.u.string;
+
+ switch (i) {
+ case 0:
+ if (strcmp("clock", src_string)) {
+ goto error;
+ }
+ break;
+ case 1:
+ name = src_string;
+ break;
+ case 2:
+ if (strcmp("value", src_string)) {
+ goto error;
+ }
+ break;
+ default:
+ /* Extra identifier, unknown */
+ goto error;
+ }
+
+ i++;
+ }
+
+ return name;
error:
- return NULL;
+ return NULL;
}
-static
-int is_unary_unsigned(struct bt_list_head *head)
+static int is_unary_unsigned(struct bt_list_head *head)
{
- int ret = TRUE;
- struct ctf_node *node;
+ int ret = TRUE;
+ struct ctf_node *node;
- bt_list_for_each_entry(node, head, siblings) {
- if (node->type != NODE_UNARY_EXPRESSION) {
- ret = FALSE;
- }
+ bt_list_for_each_entry (node, head, siblings) {
+ if (node->type != NODE_UNARY_EXPRESSION) {
+ ret = FALSE;
+ }
- if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
- ret = FALSE;
- }
- }
+ if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ ret = FALSE;
+ }
+ }
- return ret;
+ return ret;
}
-static
-int get_unary_unsigned(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head,
- uint64_t *value)
+static int get_unary_unsigned(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head,
+ uint64_t *value)
{
- int i = 0;
- int ret = 0;
- struct ctf_node *node;
-
- *value = 0;
-
- if (bt_list_empty(head)) {
- ret = -1;
- goto end;
- }
-
- bt_list_for_each_entry(node, head, siblings) {
- int uexpr_type = node->u.unary_expression.type;
- int uexpr_link = node->u.unary_expression.link;
- int cond = node->type != NODE_UNARY_EXPRESSION ||
- uexpr_type != UNARY_UNSIGNED_CONSTANT ||
- uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
- if (cond) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid constant unsigned integer.");
- ret = -EINVAL;
- goto end;
- }
-
- *value = node->u.unary_expression.u.unsigned_constant;
- i++;
- }
+ int i = 0;
+ int ret = 0;
+ struct ctf_node *node;
+
+ *value = 0;
+
+ if (bt_list_empty(head)) {
+ ret = -1;
+ goto end;
+ }
+
+ bt_list_for_each_entry (node, head, siblings) {
+ int uexpr_type = node->u.unary_expression.type;
+ int uexpr_link = node->u.unary_expression.link;
+ int cond = node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_UNSIGNED_CONSTANT ||
+ uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
+ if (cond) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid constant unsigned integer.");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ *value = node->u.unary_expression.u.unsigned_constant;
+ i++;
+ }
end:
- return ret;
+ return ret;
}
-static
-int is_unary_signed(struct bt_list_head *head)
+static int is_unary_signed(struct bt_list_head *head)
{
- int ret = TRUE;
- struct ctf_node *node;
+ int ret = TRUE;
+ struct ctf_node *node;
- bt_list_for_each_entry(node, head, siblings) {
- if (node->type != NODE_UNARY_EXPRESSION) {
- ret = FALSE;
- }
+ bt_list_for_each_entry (node, head, siblings) {
+ if (node->type != NODE_UNARY_EXPRESSION) {
+ ret = FALSE;
+ }
- if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
- ret = FALSE;
- }
- }
+ if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
+ ret = FALSE;
+ }
+ }
- return ret;
+ return ret;
}
-static
-int get_unary_signed(struct bt_list_head *head, int64_t *value)
+static int get_unary_signed(struct bt_list_head *head, int64_t *value)
{
- int i = 0;
- int ret = 0;
- struct ctf_node *node;
-
- bt_list_for_each_entry(node, head, siblings) {
- int uexpr_type = node->u.unary_expression.type;
- int uexpr_link = node->u.unary_expression.link;
- int cond = node->type != NODE_UNARY_EXPRESSION ||
- (uexpr_type != UNARY_UNSIGNED_CONSTANT &&
- uexpr_type != UNARY_SIGNED_CONSTANT) ||
- uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
- if (cond) {
- ret = -EINVAL;
- goto end;
- }
-
- switch (uexpr_type) {
- case UNARY_UNSIGNED_CONSTANT:
- *value = (int64_t)
- node->u.unary_expression.u.unsigned_constant;
- break;
- case UNARY_SIGNED_CONSTANT:
- *value = node->u.unary_expression.u.signed_constant;
- break;
- default:
- ret = -EINVAL;
- goto end;
- }
-
- i++;
- }
+ int i = 0;
+ int ret = 0;
+ struct ctf_node *node;
+
+ bt_list_for_each_entry (node, head, siblings) {
+ int uexpr_type = node->u.unary_expression.type;
+ int uexpr_link = node->u.unary_expression.link;
+ int cond = node->type != NODE_UNARY_EXPRESSION ||
+ (uexpr_type != UNARY_UNSIGNED_CONSTANT && uexpr_type != UNARY_SIGNED_CONSTANT) ||
+ uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
+ if (cond) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ switch (uexpr_type) {
+ case UNARY_UNSIGNED_CONSTANT:
+ *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
+ break;
+ case UNARY_SIGNED_CONSTANT:
+ *value = node->u.unary_expression.u.signed_constant;
+ break;
+ default:
+ ret = -EINVAL;
+ goto end;
+ }
+
+ i++;
+ }
end:
- return ret;
+ return ret;
}
-static
-int get_unary_uuid(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head,
- bt_uuid_t uuid)
+static int get_unary_uuid(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head,
+ bt_uuid_t uuid)
{
- return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level,
- ctx->log_cfg.self_comp);
+ return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level, ctx->log_cfg.self_comp);
}
-static
-int get_boolean(struct ctf_visitor_generate_ir *ctx, struct ctf_node *unary_expr)
+static int get_boolean(struct ctf_visitor_generate_ir *ctx, struct ctf_node *unary_expr)
{
- int ret = 0;
-
- if (unary_expr->type != NODE_UNARY_EXPRESSION) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
- "Expecting unary expression: node-type=%d",
- unary_expr->type);
- ret = -EINVAL;
- goto end;
- }
-
- switch (unary_expr->u.unary_expression.type) {
- case UNARY_UNSIGNED_CONSTANT:
- ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0);
- break;
- case UNARY_SIGNED_CONSTANT:
- ret = (unary_expr->u.unary_expression.u.signed_constant != 0);
- break;
- case UNARY_STRING:
- {
- const char *str = unary_expr->u.unary_expression.u.string;
-
- if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0) {
- ret = TRUE;
- } else if (strcmp(str, "false") == 0 || strcmp(str, "FALSE") == 0) {
- ret = FALSE;
- } else {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
- "Unexpected boolean value: value=\"%s\"", str);
- ret = -EINVAL;
- goto end;
- }
- break;
- }
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
- "Unexpected unary expression type: node-type=%d",
- unary_expr->u.unary_expression.type);
- ret = -EINVAL;
- goto end;
- }
+ int ret = 0;
+
+ if (unary_expr->type != NODE_UNARY_EXPRESSION) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, "Expecting unary expression: node-type=%d",
+ unary_expr->type);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ switch (unary_expr->u.unary_expression.type) {
+ case UNARY_UNSIGNED_CONSTANT:
+ ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0);
+ break;
+ case UNARY_SIGNED_CONSTANT:
+ ret = (unary_expr->u.unary_expression.u.signed_constant != 0);
+ break;
+ case UNARY_STRING:
+ {
+ const char *str = unary_expr->u.unary_expression.u.string;
+
+ if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0) {
+ ret = TRUE;
+ } else if (strcmp(str, "false") == 0 || strcmp(str, "FALSE") == 0) {
+ ret = FALSE;
+ } else {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, "Unexpected boolean value: value=\"%s\"",
+ str);
+ ret = -EINVAL;
+ goto end;
+ }
+ break;
+ }
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
+ "Unexpected unary expression type: node-type=%d",
+ unary_expr->u.unary_expression.type);
+ ret = -EINVAL;
+ goto end;
+ }
end:
- return ret;
+ return ret;
}
-static
-enum ctf_byte_order byte_order_from_unary_expr(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *unary_expr)
+static enum ctf_byte_order byte_order_from_unary_expr(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *unary_expr)
{
- const char *str;
- enum ctf_byte_order bo = CTF_BYTE_ORDER_UNKNOWN;
-
- if (unary_expr->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
- "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
- goto end;
- }
-
- str = unary_expr->u.unary_expression.u.string;
-
- if (strcmp(str, "be") == 0 || strcmp(str, "network") == 0) {
- bo = CTF_BYTE_ORDER_BIG;
- } else if (strcmp(str, "le") == 0) {
- bo = CTF_BYTE_ORDER_LITTLE;
- } else if (strcmp(str, "native") == 0) {
- bo = CTF_BYTE_ORDER_DEFAULT;
- } else {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr,
- "Unexpected \"byte_order\" attribute value: "
- "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
- str);
- goto end;
- }
+ const char *str;
+ enum ctf_byte_order bo = CTF_BYTE_ORDER_UNKNOWN;
+
+ if (unary_expr->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ unary_expr, "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
+ goto end;
+ }
+
+ str = unary_expr->u.unary_expression.u.string;
+
+ if (strcmp(str, "be") == 0 || strcmp(str, "network") == 0) {
+ bo = CTF_BYTE_ORDER_BIG;
+ } else if (strcmp(str, "le") == 0) {
+ bo = CTF_BYTE_ORDER_LITTLE;
+ } else if (strcmp(str, "native") == 0) {
+ bo = CTF_BYTE_ORDER_DEFAULT;
+ } else {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ unary_expr,
+ "Unexpected \"byte_order\" attribute value: "
+ "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
+ str);
+ goto end;
+ }
end:
- return bo;
+ return bo;
}
-static
-enum ctf_byte_order get_real_byte_order(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *uexpr)
+static enum ctf_byte_order get_real_byte_order(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *uexpr)
{
- enum ctf_byte_order bo = byte_order_from_unary_expr(ctx, uexpr);
+ enum ctf_byte_order bo = byte_order_from_unary_expr(ctx, uexpr);
- if (bo == CTF_BYTE_ORDER_DEFAULT) {
- bo = ctx->ctf_tc->default_byte_order;
- }
+ if (bo == CTF_BYTE_ORDER_DEFAULT) {
+ bo = ctx->ctf_tc->default_byte_order;
+ }
- return bo;
+ return bo;
}
-static
-int is_align_valid(uint64_t align)
+static int is_align_valid(uint64_t align)
{
- return (align != 0) && !(align & (align - UINT64_C(1)));
+ return (align != 0) && !(align & (align - UINT64_C(1)));
}
-static
-int get_class_specifier_name(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier, GString *str)
+static int get_class_specifier_name(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier, GString *str)
{
- int ret = 0;
-
- if (cls_specifier->type != NODE_TYPE_SPECIFIER) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier,
- "Unexpected node type: node-type=%d",
- cls_specifier->type);
- ret = -EINVAL;
- goto end;
- }
-
- switch (cls_specifier->u.field_class_specifier.type) {
- case TYPESPEC_VOID:
- g_string_append(str, "void");
- break;
- case TYPESPEC_CHAR:
- g_string_append(str, "char");
- break;
- case TYPESPEC_SHORT:
- g_string_append(str, "short");
- break;
- case TYPESPEC_INT:
- g_string_append(str, "int");
- break;
- case TYPESPEC_LONG:
- g_string_append(str, "long");
- break;
- case TYPESPEC_FLOAT:
- g_string_append(str, "float");
- break;
- case TYPESPEC_DOUBLE:
- g_string_append(str, "double");
- break;
- case TYPESPEC_SIGNED:
- g_string_append(str, "signed");
- break;
- case TYPESPEC_UNSIGNED:
- g_string_append(str, "unsigned");
- break;
- case TYPESPEC_BOOL:
- g_string_append(str, "bool");
- break;
- case TYPESPEC_COMPLEX:
- g_string_append(str, "_Complex");
- break;
- case TYPESPEC_IMAGINARY:
- g_string_append(str, "_Imaginary");
- break;
- case TYPESPEC_CONST:
- g_string_append(str, "const");
- break;
- case TYPESPEC_ID_TYPE:
- if (cls_specifier->u.field_class_specifier.id_type) {
- g_string_append(str,
- cls_specifier->u.field_class_specifier.id_type);
- }
- break;
- case TYPESPEC_STRUCT:
- {
- struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
-
- if (!node->u._struct.name) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty structure field class name.");
- ret = -EINVAL;
- goto end;
- }
-
- g_string_append(str, "struct ");
- g_string_append(str, node->u._struct.name);
- break;
- }
- case TYPESPEC_VARIANT:
- {
- struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
-
- if (!node->u.variant.name) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty variant field class name.");
- ret = -EINVAL;
- goto end;
- }
-
- g_string_append(str, "variant ");
- g_string_append(str, node->u.variant.name);
- break;
- }
- case TYPESPEC_ENUM:
- {
- struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
-
- if (!node->u._enum.enum_id) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected empty enumeration field class (`enum`) name.");
- ret = -EINVAL;
- goto end;
- }
-
- g_string_append(str, "enum ");
- g_string_append(str, node->u._enum.enum_id);
- break;
- }
- case TYPESPEC_FLOATING_POINT:
- case TYPESPEC_INTEGER:
- case TYPESPEC_STRING:
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier->u.field_class_specifier.node,
- "Unexpected field class specifier type: %d",
- cls_specifier->u.field_class_specifier.type);
- ret = -EINVAL;
- goto end;
- }
+ int ret = 0;
+
+ if (cls_specifier->type != NODE_TYPE_SPECIFIER) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier, "Unexpected node type: node-type=%d",
+ cls_specifier->type);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ switch (cls_specifier->u.field_class_specifier.type) {
+ case TYPESPEC_VOID:
+ g_string_append(str, "void");
+ break;
+ case TYPESPEC_CHAR:
+ g_string_append(str, "char");
+ break;
+ case TYPESPEC_SHORT:
+ g_string_append(str, "short");
+ break;
+ case TYPESPEC_INT:
+ g_string_append(str, "int");
+ break;
+ case TYPESPEC_LONG:
+ g_string_append(str, "long");
+ break;
+ case TYPESPEC_FLOAT:
+ g_string_append(str, "float");
+ break;
+ case TYPESPEC_DOUBLE:
+ g_string_append(str, "double");
+ break;
+ case TYPESPEC_SIGNED:
+ g_string_append(str, "signed");
+ break;
+ case TYPESPEC_UNSIGNED:
+ g_string_append(str, "unsigned");
+ break;
+ case TYPESPEC_BOOL:
+ g_string_append(str, "bool");
+ break;
+ case TYPESPEC_COMPLEX:
+ g_string_append(str, "_Complex");
+ break;
+ case TYPESPEC_IMAGINARY:
+ g_string_append(str, "_Imaginary");
+ break;
+ case TYPESPEC_CONST:
+ g_string_append(str, "const");
+ break;
+ case TYPESPEC_ID_TYPE:
+ if (cls_specifier->u.field_class_specifier.id_type) {
+ g_string_append(str, cls_specifier->u.field_class_specifier.id_type);
+ }
+ break;
+ case TYPESPEC_STRUCT:
+ {
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
+
+ if (!node->u._struct.name) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty structure field class name.");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ g_string_append(str, "struct ");
+ g_string_append(str, node->u._struct.name);
+ break;
+ }
+ case TYPESPEC_VARIANT:
+ {
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
+
+ if (!node->u.variant.name) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty variant field class name.");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ g_string_append(str, "variant ");
+ g_string_append(str, node->u.variant.name);
+ break;
+ }
+ case TYPESPEC_ENUM:
+ {
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
+
+ if (!node->u._enum.enum_id) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected empty enumeration field class (`enum`) name.");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ g_string_append(str, "enum ");
+ g_string_append(str, node->u._enum.enum_id);
+ break;
+ }
+ case TYPESPEC_FLOATING_POINT:
+ case TYPESPEC_INTEGER:
+ case TYPESPEC_STRING:
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier->u.field_class_specifier.node,
+ "Unexpected field class specifier type: %d",
+ cls_specifier->u.field_class_specifier.type);
+ ret = -EINVAL;
+ goto end;
+ }
end:
- return ret;
+ return ret;
}
-static
-int get_class_specifier_list_name(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier_list, GString *str)
+static int get_class_specifier_list_name(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier_list, GString *str)
{
- int ret = 0;
- struct ctf_node *iter;
- int alias_item_nr = 0;
- struct bt_list_head *head =
- &cls_specifier_list->u.field_class_specifier_list.head;
-
- bt_list_for_each_entry(iter, head, siblings) {
- if (alias_item_nr != 0) {
- g_string_append(str, " ");
- }
-
- alias_item_nr++;
- ret = get_class_specifier_name(ctx, iter, str);
- if (ret) {
- goto end;
- }
- }
+ int ret = 0;
+ struct ctf_node *iter;
+ int alias_item_nr = 0;
+ struct bt_list_head *head = &cls_specifier_list->u.field_class_specifier_list.head;
+
+ bt_list_for_each_entry (iter, head, siblings) {
+ if (alias_item_nr != 0) {
+ g_string_append(str, " ");
+ }
+
+ alias_item_nr++;
+ ret = get_class_specifier_name(ctx, iter, str);
+ if (ret) {
+ goto end;
+ }
+ }
end:
- return ret;
+ return ret;
}
-static
-GQuark create_class_alias_identifier(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier_list,
- struct ctf_node *node_field_class_declarator)
+static GQuark create_class_alias_identifier(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier_list,
+ struct ctf_node *node_field_class_declarator)
{
- int ret;
- char *str_c;
- GString *str;
- GQuark qalias = 0;
- struct ctf_node *iter;
- struct bt_list_head *pointers =
- &node_field_class_declarator->u.field_class_declarator.pointers;
-
- str = g_string_new("");
- ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
- if (ret) {
- g_string_free(str, TRUE);
- goto end;
- }
-
- bt_list_for_each_entry(iter, pointers, siblings) {
- g_string_append(str, " *");
-
- if (iter->u.pointer.const_qualifier) {
- g_string_append(str, " const");
- }
- }
-
- str_c = g_string_free(str, FALSE);
- qalias = g_quark_from_string(str_c);
- g_free(str_c);
+ int ret;
+ char *str_c;
+ GString *str;
+ GQuark qalias = 0;
+ struct ctf_node *iter;
+ struct bt_list_head *pointers = &node_field_class_declarator->u.field_class_declarator.pointers;
+
+ str = g_string_new("");
+ ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
+ if (ret) {
+ g_string_free(str, TRUE);
+ goto end;
+ }
+
+ bt_list_for_each_entry (iter, pointers, siblings) {
+ g_string_append(str, " *");
+
+ if (iter->u.pointer.const_qualifier) {
+ g_string_append(str, " const");
+ }
+ }
+
+ str_c = g_string_free(str, FALSE);
+ qalias = g_quark_from_string(str_c);
+ g_free(str_c);
end:
- return qalias;
+ return qalias;
}
-static
-int visit_field_class_declarator(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier_list,
- GQuark *field_name, struct ctf_node *node_field_class_declarator,
- struct ctf_field_class **field_decl,
- struct ctf_field_class *nested_decl)
+static int visit_field_class_declarator(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier_list, GQuark *field_name,
+ struct ctf_node *node_field_class_declarator,
+ struct ctf_field_class **field_decl,
+ struct ctf_field_class *nested_decl)
{
- /*
- * During this whole function, nested_decl is always OURS,
- * whereas field_decl is an output which we create, but
- * belongs to the caller (it is moved).
- */
- int ret = 0;
- *field_decl = NULL;
-
- /* Validate field class declarator node */
- if (node_field_class_declarator) {
- if (node_field_class_declarator->u.field_class_declarator.type ==
- TYPEDEC_UNKNOWN) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Unexpected field class declarator type: type=%d",
- node_field_class_declarator->u.field_class_declarator.type);
- ret = -EINVAL;
- goto error;
- }
-
- /* TODO: GCC bitfields not supported yet */
- if (node_field_class_declarator->u.field_class_declarator.bitfield_len !=
- NULL) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "GCC bitfields are not supported as of this version.");
- ret = -EPERM;
- goto error;
- }
- }
-
- /* Find the right nested declaration if not provided */
- if (!nested_decl) {
- struct bt_list_head *pointers =
- &node_field_class_declarator->u.field_class_declarator.pointers;
-
- if (node_field_class_declarator && !bt_list_empty(pointers)) {
- GQuark qalias;
-
- /*
- * If we have a pointer declarator, it HAS to
+ /*
+ * During this whole function, nested_decl is always OURS,
+ * whereas field_decl is an output which we create, but
+ * belongs to the caller (it is moved).
+ */
+ int ret = 0;
+ *field_decl = NULL;
+
+ /* Validate field class declarator node */
+ if (node_field_class_declarator) {
+ if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_UNKNOWN) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node_field_class_declarator, "Unexpected field class declarator type: type=%d",
+ node_field_class_declarator->u.field_class_declarator.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* TODO: GCC bitfields not supported yet */
+ if (node_field_class_declarator->u.field_class_declarator.bitfield_len != NULL) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "GCC bitfields are not supported as of this version.");
+ ret = -EPERM;
+ goto error;
+ }
+ }
+
+ /* Find the right nested declaration if not provided */
+ if (!nested_decl) {
+ struct bt_list_head *pointers =
+ &node_field_class_declarator->u.field_class_declarator.pointers;
+
+ if (node_field_class_declarator && !bt_list_empty(pointers)) {
+ GQuark qalias;
+
+ /*
+ * If we have a pointer declarator, it HAS to
* be present in the field class aliases (else
* fail).
- */
- qalias = create_class_alias_identifier(ctx,
- cls_specifier_list, node_field_class_declarator);
- nested_decl =
- ctx_decl_scope_lookup_alias(ctx,
- ctx->current_scope,
- g_quark_to_string(qalias), -1, true);
- if (!nested_decl) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Cannot find class alias: name=\"%s\"",
- g_quark_to_string(qalias));
- ret = -EINVAL;
- goto error;
- }
-
- if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) {
- /* Pointer: force integer's base to 16 */
- struct ctf_field_class_int *int_fc =
- ctf_field_class_as_int(nested_decl);
-
- int_fc->disp_base =
- BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
- }
- } else {
- ret = visit_field_class_specifier_list(ctx,
- cls_specifier_list, &nested_decl);
- if (ret) {
- BT_ASSERT(!nested_decl);
- goto error;
- }
- }
- }
-
- BT_ASSERT(nested_decl);
-
- if (!node_field_class_declarator) {
- *field_decl = nested_decl;
- nested_decl = NULL;
- goto end;
- }
-
- if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) {
- if (node_field_class_declarator->u.field_class_declarator.u.id) {
- const char *id =
- node_field_class_declarator->u.field_class_declarator.u.id;
-
- *field_name = g_quark_from_string(id);
- } else {
- *field_name = 0;
- }
-
- *field_decl = nested_decl;
- nested_decl = NULL;
- goto end;
- } else {
- struct ctf_node *first;
- struct ctf_field_class *decl = NULL;
- struct ctf_field_class *outer_field_decl = NULL;
- struct bt_list_head *length =
- &node_field_class_declarator->
- u.field_class_declarator.u.nested.length;
-
- /* Create array/sequence, pass nested_decl as child */
- if (bt_list_empty(length)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Expecting length field reference or value.");
- ret = -EINVAL;
- goto error;
- }
-
- first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings);
- if (first->type != NODE_UNARY_EXPRESSION) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(first,
- "Unexpected node type: node-type=%d",
- first->type);
- ret = -EINVAL;
- goto error;
- }
-
- switch (first->u.unary_expression.type) {
- case UNARY_UNSIGNED_CONSTANT:
- {
- struct ctf_field_class_array *array_decl = NULL;
-
- array_decl = ctf_field_class_array_create();
- BT_ASSERT(array_decl);
- array_decl->length =
- first->u.unary_expression.u.unsigned_constant;
- array_decl->base.elem_fc = nested_decl;
- nested_decl = NULL;
- decl = &array_decl->base.base;
- break;
- }
- case UNARY_STRING:
- {
- /* Lookup unsigned integer definition, create seq. */
- struct ctf_field_class_sequence *seq_decl = NULL;
- char *length_name = ctf_ast_concatenate_unary_strings(length);
-
- if (!length_name) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strncmp(length_name, "env.", 4) == 0) {
- /* This is, in fact, an array */
- const char *env_entry_name = &length_name[4];
- struct ctf_trace_class_env_entry *env_entry =
- ctf_trace_class_borrow_env_entry_by_name(
- ctx->ctf_tc, env_entry_name);
- struct ctf_field_class_array *array_decl;
-
- if (!env_entry) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Cannot find environment entry: "
- "name=\"%s\"", env_entry_name);
- ret = -EINVAL;
- goto error;
- }
-
- if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Wrong environment entry type "
- "(expecting integer): "
- "name=\"%s\"", env_entry_name);
- ret = -EINVAL;
- goto error;
- }
-
- if (env_entry->value.i < 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
- "Invalid, negative array length: "
- "env-entry-name=\"%s\", "
- "value=%" PRId64,
- env_entry_name,
- env_entry->value.i);
- ret = -EINVAL;
- goto error;
- }
-
- array_decl = ctf_field_class_array_create();
- BT_ASSERT(array_decl);
- array_decl->length =
- (uint64_t) env_entry->value.i;
- array_decl->base.elem_fc = nested_decl;
- nested_decl = NULL;
- decl = &array_decl->base.base;
- } else {
- seq_decl = ctf_field_class_sequence_create();
- BT_ASSERT(seq_decl);
- seq_decl->base.elem_fc = nested_decl;
- nested_decl = NULL;
- g_string_assign(seq_decl->length_ref,
- length_name);
- decl = &seq_decl->base.base;
- }
-
- g_free(length_name);
- break;
- }
- default:
- ret = -EINVAL;
- goto error;
- }
-
- BT_ASSERT(!nested_decl);
- BT_ASSERT(decl);
- BT_ASSERT(!*field_decl);
-
- /*
- * At this point, we found the next nested declaration.
- * We currently own this (and lost the ownership of
- * nested_decl in the meantime). Pass this next
- * nested declaration as the content of the outer
- * container, MOVING its ownership.
- */
- ret = visit_field_class_declarator(ctx, cls_specifier_list,
- field_name,
- node_field_class_declarator->
- u.field_class_declarator.u.nested.field_class_declarator,
- &outer_field_decl, decl);
- decl = NULL;
- if (ret) {
- BT_ASSERT(!outer_field_decl);
- ret = -EINVAL;
- goto error;
- }
-
- BT_ASSERT(outer_field_decl);
- *field_decl = outer_field_decl;
- outer_field_decl = NULL;
- }
-
- BT_ASSERT(*field_decl);
- goto end;
+ */
+ qalias =
+ create_class_alias_identifier(ctx, cls_specifier_list, node_field_class_declarator);
+ nested_decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope,
+ g_quark_to_string(qalias), -1, true);
+ if (!nested_decl) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Cannot find class alias: name=\"%s\"",
+ g_quark_to_string(qalias));
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) {
+ /* Pointer: force integer's base to 16 */
+ struct ctf_field_class_int *int_fc = ctf_field_class_as_int(nested_decl);
+
+ int_fc->disp_base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
+ }
+ } else {
+ ret = visit_field_class_specifier_list(ctx, cls_specifier_list, &nested_decl);
+ if (ret) {
+ BT_ASSERT(!nested_decl);
+ goto error;
+ }
+ }
+ }
+
+ BT_ASSERT(nested_decl);
+
+ if (!node_field_class_declarator) {
+ *field_decl = nested_decl;
+ nested_decl = NULL;
+ goto end;
+ }
+
+ if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) {
+ if (node_field_class_declarator->u.field_class_declarator.u.id) {
+ const char *id = node_field_class_declarator->u.field_class_declarator.u.id;
+
+ *field_name = g_quark_from_string(id);
+ } else {
+ *field_name = 0;
+ }
+
+ *field_decl = nested_decl;
+ nested_decl = NULL;
+ goto end;
+ } else {
+ struct ctf_node *first;
+ struct ctf_field_class *decl = NULL;
+ struct ctf_field_class *outer_field_decl = NULL;
+ struct bt_list_head *length =
+ &node_field_class_declarator->u.field_class_declarator.u.nested.length;
+
+ /* Create array/sequence, pass nested_decl as child */
+ if (bt_list_empty(length)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Expecting length field reference or value.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings);
+ if (first->type != NODE_UNARY_EXPRESSION) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Unexpected node type: node-type=%d",
+ first->type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ switch (first->u.unary_expression.type) {
+ case UNARY_UNSIGNED_CONSTANT:
+ {
+ struct ctf_field_class_array *array_decl = NULL;
+
+ array_decl = ctf_field_class_array_create();
+ BT_ASSERT(array_decl);
+ array_decl->length = first->u.unary_expression.u.unsigned_constant;
+ array_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ decl = &array_decl->base.base;
+ break;
+ }
+ case UNARY_STRING:
+ {
+ /* Lookup unsigned integer definition, create seq. */
+ struct ctf_field_class_sequence *seq_decl = NULL;
+ char *length_name = ctf_ast_concatenate_unary_strings(length);
+
+ if (!length_name) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strncmp(length_name, "env.", 4) == 0) {
+ /* This is, in fact, an array */
+ const char *env_entry_name = &length_name[4];
+ struct ctf_trace_class_env_entry *env_entry =
+ ctf_trace_class_borrow_env_entry_by_name(ctx->ctf_tc, env_entry_name);
+ struct ctf_field_class_array *array_decl;
+
+ if (!env_entry) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Cannot find environment entry: "
+ "name=\"%s\"",
+ env_entry_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Wrong environment entry type "
+ "(expecting integer): "
+ "name=\"%s\"",
+ env_entry_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (env_entry->value.i < 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator,
+ "Invalid, negative array length: "
+ "env-entry-name=\"%s\", "
+ "value=%" PRId64,
+ env_entry_name, env_entry->value.i);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ array_decl = ctf_field_class_array_create();
+ BT_ASSERT(array_decl);
+ array_decl->length = (uint64_t) env_entry->value.i;
+ array_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ decl = &array_decl->base.base;
+ } else {
+ seq_decl = ctf_field_class_sequence_create();
+ BT_ASSERT(seq_decl);
+ seq_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ g_string_assign(seq_decl->length_ref, length_name);
+ decl = &seq_decl->base.base;
+ }
+
+ g_free(length_name);
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ goto error;
+ }
+
+ BT_ASSERT(!nested_decl);
+ BT_ASSERT(decl);
+ BT_ASSERT(!*field_decl);
+
+ /*
+ * At this point, we found the next nested declaration.
+ * We currently own this (and lost the ownership of
+ * nested_decl in the meantime). Pass this next
+ * nested declaration as the content of the outer
+ * container, MOVING its ownership.
+ */
+ ret = visit_field_class_declarator(
+ ctx, cls_specifier_list, field_name,
+ node_field_class_declarator->u.field_class_declarator.u.nested.field_class_declarator,
+ &outer_field_decl, decl);
+ decl = NULL;
+ if (ret) {
+ BT_ASSERT(!outer_field_decl);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ BT_ASSERT(outer_field_decl);
+ *field_decl = outer_field_decl;
+ outer_field_decl = NULL;
+ }
+
+ BT_ASSERT(*field_decl);
+ goto end;
error:
- ctf_field_class_destroy(*field_decl);
- *field_decl = NULL;
+ ctf_field_class_destroy(*field_decl);
+ *field_decl = NULL;
- if (ret >= 0) {
- ret = -1;
- }
+ if (ret >= 0) {
+ ret = -1;
+ }
end:
- ctf_field_class_destroy(nested_decl);
- nested_decl = NULL;
- return ret;
+ ctf_field_class_destroy(nested_decl);
+ nested_decl = NULL;
+ return ret;
}
-static
-int visit_struct_decl_field(struct ctf_visitor_generate_ir *ctx,
- struct ctf_field_class_struct *struct_decl,
- struct ctf_node *cls_specifier_list,
- struct bt_list_head *field_class_declarators)
+static int visit_struct_decl_field(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_field_class_struct *struct_decl,
+ struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
- int ret = 0;
- struct ctf_node *iter;
- struct ctf_field_class *field_decl = NULL;
-
- bt_list_for_each_entry(iter, field_class_declarators, siblings) {
- field_decl = NULL;
- GQuark qfield_name;
- const char *field_name;
-
- ret = visit_field_class_declarator(ctx, cls_specifier_list,
- &qfield_name, iter, &field_decl, NULL);
- if (ret) {
- BT_ASSERT(!field_decl);
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Cannot visit field class declarator: ret=%d", ret);
- goto error;
- }
-
- BT_ASSERT(field_decl);
- field_name = g_quark_to_string(qfield_name);
-
- /* Check if field with same name already exists */
- if (ctf_field_class_struct_borrow_member_by_name(
- struct_decl, field_name)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Duplicate field in structure field class: "
- "field-name=\"%s\"", field_name);
- ret = -EINVAL;
- goto error;
- }
-
- /* Add field to structure */
- ctf_field_class_struct_append_member(struct_decl,
- field_name, field_decl);
- field_decl = NULL;
- }
-
- return 0;
+ int ret = 0;
+ struct ctf_node *iter;
+ struct ctf_field_class *field_decl = NULL;
+
+ bt_list_for_each_entry (iter, field_class_declarators, siblings) {
+ field_decl = NULL;
+ GQuark qfield_name;
+ const char *field_name;
+
+ ret = visit_field_class_declarator(ctx, cls_specifier_list, &qfield_name, iter, &field_decl,
+ NULL);
+ if (ret) {
+ BT_ASSERT(!field_decl);
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
+ "Cannot visit field class declarator: ret=%d", ret);
+ goto error;
+ }
+
+ BT_ASSERT(field_decl);
+ field_name = g_quark_to_string(qfield_name);
+
+ /* Check if field with same name already exists */
+ if (ctf_field_class_struct_borrow_member_by_name(struct_decl, field_name)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
+ "Duplicate field in structure field class: "
+ "field-name=\"%s\"",
+ field_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* Add field to structure */
+ ctf_field_class_struct_append_member(struct_decl, field_name, field_decl);
+ field_decl = NULL;
+ }
+
+ return 0;
error:
- ctf_field_class_destroy(field_decl);
- field_decl = NULL;
- return ret;
+ ctf_field_class_destroy(field_decl);
+ field_decl = NULL;
+ return ret;
}
-static
-int visit_variant_decl_field(struct ctf_visitor_generate_ir *ctx,
- struct ctf_field_class_variant *variant_decl,
- struct ctf_node *cls_specifier_list,
- struct bt_list_head *field_class_declarators)
+static int visit_variant_decl_field(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_field_class_variant *variant_decl,
+ struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
- int ret = 0;
- struct ctf_node *iter;
- struct ctf_field_class *field_decl = NULL;
-
- bt_list_for_each_entry(iter, field_class_declarators, siblings) {
- field_decl = NULL;
- GQuark qfield_name;
- const char *field_name;
-
- ret = visit_field_class_declarator(ctx, cls_specifier_list,
- &qfield_name, iter, &field_decl, NULL);
- if (ret) {
- BT_ASSERT(!field_decl);
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Cannot visit field class declarator: ret=%d", ret);
- goto error;
- }
-
- BT_ASSERT(field_decl);
- field_name = g_quark_to_string(qfield_name);
-
- /* Check if field with same name already exists */
- if (ctf_field_class_variant_borrow_option_by_name(
- variant_decl, field_name)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Duplicate field in variant field class: "
- "field-name=\"%s\"", field_name);
- ret = -EINVAL;
- goto error;
- }
-
- /* Add field to structure */
- ctf_field_class_variant_append_option(variant_decl,
- field_name, field_decl);
- field_decl = NULL;
- }
-
- return 0;
+ int ret = 0;
+ struct ctf_node *iter;
+ struct ctf_field_class *field_decl = NULL;
+
+ bt_list_for_each_entry (iter, field_class_declarators, siblings) {
+ field_decl = NULL;
+ GQuark qfield_name;
+ const char *field_name;
+
+ ret = visit_field_class_declarator(ctx, cls_specifier_list, &qfield_name, iter, &field_decl,
+ NULL);
+ if (ret) {
+ BT_ASSERT(!field_decl);
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
+ "Cannot visit field class declarator: ret=%d", ret);
+ goto error;
+ }
+
+ BT_ASSERT(field_decl);
+ field_name = g_quark_to_string(qfield_name);
+
+ /* Check if field with same name already exists */
+ if (ctf_field_class_variant_borrow_option_by_name(variant_decl, field_name)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
+ "Duplicate field in variant field class: "
+ "field-name=\"%s\"",
+ field_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* Add field to structure */
+ ctf_field_class_variant_append_option(variant_decl, field_name, field_decl);
+ field_decl = NULL;
+ }
+
+ return 0;
error:
- ctf_field_class_destroy(field_decl);
- field_decl = NULL;
- return ret;
+ ctf_field_class_destroy(field_decl);
+ field_decl = NULL;
+ return ret;
}
-static
-int visit_field_class_def(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier_list,
- struct bt_list_head *field_class_declarators)
+static int visit_field_class_def(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
- int ret = 0;
- GQuark qidentifier;
- struct ctf_node *iter;
- struct ctf_field_class *class_decl = NULL;
-
- bt_list_for_each_entry(iter, field_class_declarators, siblings) {
- ret = visit_field_class_declarator(ctx, cls_specifier_list,
- &qidentifier, iter, &class_decl, NULL);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit field class declarator: ret=%d", ret);
- ret = -EINVAL;
- goto end;
- }
-
- /* Do not allow field class def and alias of untagged variants */
- if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
- struct ctf_field_class_variant *var_fc =
- ctf_field_class_as_variant(class_decl);
-
- if (var_fc->tag_path.path->len == 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Type definition of untagged variant field class is not allowed.");
- ret = -EPERM;
- goto end;
- }
- }
-
- ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope,
- g_quark_to_string(qidentifier), class_decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot register field class alias: name=\"%s\"",
- g_quark_to_string(qidentifier));
- goto end;
- }
- }
+ int ret = 0;
+ GQuark qidentifier;
+ struct ctf_node *iter;
+ struct ctf_field_class *class_decl = NULL;
+
+ bt_list_for_each_entry (iter, field_class_declarators, siblings) {
+ ret = visit_field_class_declarator(ctx, cls_specifier_list, &qidentifier, iter, &class_decl,
+ NULL);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit field class declarator: ret=%d",
+ ret);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Do not allow field class def and alias of untagged variants */
+ if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(class_decl);
+
+ if (var_fc->tag_path.path->len == 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ iter, "Type definition of untagged variant field class is not allowed.");
+ ret = -EPERM;
+ goto end;
+ }
+ }
+
+ ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, g_quark_to_string(qidentifier),
+ class_decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot register field class alias: name=\"%s\"",
+ g_quark_to_string(qidentifier));
+ goto end;
+ }
+ }
end:
- ctf_field_class_destroy(class_decl);
- class_decl = NULL;
- return ret;
+ ctf_field_class_destroy(class_decl);
+ class_decl = NULL;
+ return ret;
}
-static
-int visit_field_class_alias(struct ctf_visitor_generate_ir *ctx, struct ctf_node *target,
- struct ctf_node *alias)
+static int visit_field_class_alias(struct ctf_visitor_generate_ir *ctx, struct ctf_node *target,
+ struct ctf_node *alias)
{
- int ret = 0;
- GQuark qalias;
- struct ctf_node *node;
- GQuark qdummy_field_name;
- struct ctf_field_class *class_decl = NULL;
-
- /* Create target field class */
- if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) {
- node = NULL;
- } else {
- node = _BT_LIST_FIRST_ENTRY(
- &target->u.field_class_alias_target.field_class_declarators,
- struct ctf_node, siblings);
- }
-
- ret = visit_field_class_declarator(ctx,
- target->u.field_class_alias_target.field_class_specifier_list,
- &qdummy_field_name, node, &class_decl, NULL);
- if (ret) {
- BT_ASSERT(!class_decl);
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot visit field class declarator: ret=%d", ret);
- goto end;
- }
-
- /* Do not allow field class def and alias of untagged variants */
- if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
- struct ctf_field_class_variant *var_fc =
- ctf_field_class_as_variant(class_decl);
-
- if (var_fc->tag_path.path->len == 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(target,
- "Type definition of untagged variant field class is not allowed.");
- ret = -EPERM;
- goto end;
- }
- }
-
- /*
- * The semantic validator does not check whether the target is
- * abstract or not (if it has an identifier). Check it here.
- */
- if (qdummy_field_name != 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(target,
- "Expecting empty identifier: id=\"%s\"",
- g_quark_to_string(qdummy_field_name));
- ret = -EINVAL;
- goto end;
- }
-
- /* Create alias identifier */
- node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators,
- struct ctf_node, siblings);
- qalias = create_class_alias_identifier(ctx,
- alias->u.field_class_alias_name.field_class_specifier_list, node);
- ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope,
- g_quark_to_string(qalias), class_decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot register class alias: name=\"%s\"",
- g_quark_to_string(qalias));
- goto end;
- }
+ int ret = 0;
+ GQuark qalias;
+ struct ctf_node *node;
+ GQuark qdummy_field_name;
+ struct ctf_field_class *class_decl = NULL;
+
+ /* Create target field class */
+ if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) {
+ node = NULL;
+ } else {
+ node = _BT_LIST_FIRST_ENTRY(&target->u.field_class_alias_target.field_class_declarators,
+ struct ctf_node, siblings);
+ }
+
+ ret = visit_field_class_declarator(
+ ctx, target->u.field_class_alias_target.field_class_specifier_list, &qdummy_field_name,
+ node, &class_decl, NULL);
+ if (ret) {
+ BT_ASSERT(!class_decl);
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot visit field class declarator: ret=%d", ret);
+ goto end;
+ }
+
+ /* Do not allow field class def and alias of untagged variants */
+ if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(class_decl);
+
+ if (var_fc->tag_path.path->len == 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ target, "Type definition of untagged variant field class is not allowed.");
+ ret = -EPERM;
+ goto end;
+ }
+ }
+
+ /*
+ * The semantic validator does not check whether the target is
+ * abstract or not (if it has an identifier). Check it here.
+ */
+ if (qdummy_field_name != 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(target, "Expecting empty identifier: id=\"%s\"",
+ g_quark_to_string(qdummy_field_name));
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Create alias identifier */
+ node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators,
+ struct ctf_node, siblings);
+ qalias = create_class_alias_identifier(
+ ctx, alias->u.field_class_alias_name.field_class_specifier_list, node);
+ ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, g_quark_to_string(qalias),
+ class_decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot register class alias: name=\"%s\"",
+ g_quark_to_string(qalias));
+ goto end;
+ }
end:
- ctf_field_class_destroy(class_decl);
- class_decl = NULL;
- return ret;
+ ctf_field_class_destroy(class_decl);
+ class_decl = NULL;
+ return ret;
}
-static
-int visit_struct_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node,
- struct ctf_field_class_struct *struct_decl)
+static int visit_struct_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node,
+ struct ctf_field_class_struct *struct_decl)
{
- int ret = 0;
-
- switch (entry_node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx,
- entry_node->u.field_class_def.field_class_specifier_list,
- &entry_node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot add field class found in structure field class: ret=%d",
- ret);
- goto end;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
- entry_node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot add field class alias found in structure field class: ret=%d",
- ret);
- goto end;
- }
- break;
- case NODE_STRUCT_OR_VARIANT_DECLARATION:
- /* Field */
- ret = visit_struct_decl_field(ctx, struct_decl,
- entry_node->u.struct_or_variant_declaration.
- field_class_specifier_list,
- &entry_node->u.struct_or_variant_declaration.
- field_class_declarators);
- if (ret) {
- goto end;
- }
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected node type: node-type=%d", entry_node->type);
- ret = -EINVAL;
- goto end;
- }
+ int ret = 0;
+
+ switch (entry_node->type) {
+ case NODE_TYPEDEF:
+ ret = visit_field_class_def(ctx, entry_node->u.field_class_def.field_class_specifier_list,
+ &entry_node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Cannot add field class found in structure field class: ret=%d", ret);
+ goto end;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
+ entry_node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Cannot add field class alias found in structure field class: ret=%d",
+ ret);
+ goto end;
+ }
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ /* Field */
+ ret = visit_struct_decl_field(
+ ctx, struct_decl,
+ entry_node->u.struct_or_variant_declaration.field_class_specifier_list,
+ &entry_node->u.struct_or_variant_declaration.field_class_declarators);
+ if (ret) {
+ goto end;
+ }
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d",
+ entry_node->type);
+ ret = -EINVAL;
+ goto end;
+ }
end:
- return ret;
+ return ret;
}
-static
-int visit_variant_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node,
- struct ctf_field_class_variant *variant_decl)
+static int visit_variant_decl_entry(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *entry_node,
+ struct ctf_field_class_variant *variant_decl)
{
- int ret = 0;
-
- switch (entry_node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx,
- entry_node->u.field_class_def.field_class_specifier_list,
- &entry_node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot add field class found in variant field class: ret=%d",
- ret);
- goto end;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
- entry_node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot add field class alias found in variant field class: ret=%d",
- ret);
- goto end;
- }
- break;
- case NODE_STRUCT_OR_VARIANT_DECLARATION:
- /* Field */
- ret = visit_variant_decl_field(ctx, variant_decl,
- entry_node->u.struct_or_variant_declaration.
- field_class_specifier_list,
- &entry_node->u.struct_or_variant_declaration.
- field_class_declarators);
- if (ret) {
- goto end;
- }
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected node type: node-type=%d",
- entry_node->type);
- ret = -EINVAL;
- goto end;
- }
+ int ret = 0;
+
+ switch (entry_node->type) {
+ case NODE_TYPEDEF:
+ ret = visit_field_class_def(ctx, entry_node->u.field_class_def.field_class_specifier_list,
+ &entry_node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Cannot add field class found in variant field class: ret=%d", ret);
+ goto end;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
+ entry_node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Cannot add field class alias found in variant field class: ret=%d",
+ ret);
+ goto end;
+ }
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ /* Field */
+ ret = visit_variant_decl_field(
+ ctx, variant_decl,
+ entry_node->u.struct_or_variant_declaration.field_class_specifier_list,
+ &entry_node->u.struct_or_variant_declaration.field_class_declarators);
+ if (ret) {
+ goto end;
+ }
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d",
+ entry_node->type);
+ ret = -EINVAL;
+ goto end;
+ }
end:
- return ret;
+ return ret;
}
-static
-int visit_struct_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
- struct bt_list_head *decl_list, int has_body,
- struct bt_list_head *min_align,
- struct ctf_field_class_struct **struct_decl)
+static int visit_struct_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
+ struct bt_list_head *decl_list, int has_body,
+ struct bt_list_head *min_align,
+ struct ctf_field_class_struct **struct_decl)
{
- int ret = 0;
-
- BT_ASSERT(struct_decl);
- *struct_decl = NULL;
-
- /* For named struct (without body), lookup in declaration scope */
- if (!has_body) {
- if (!name) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless structure field class: missing name.");
- ret = -EPERM;
- goto error;
- }
-
- *struct_decl = ctx_decl_scope_lookup_struct(ctx, ctx->current_scope,
- name, -1, true);
- if (!*struct_decl) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find structure field class: name=\"struct %s\"",
- name);
- ret = -EINVAL;
- goto error;
- }
- } else {
- struct ctf_node *entry_node;
- uint64_t min_align_value = 0;
-
- if (name) {
- if (ctx_decl_scope_lookup_struct(ctx,
- ctx->current_scope, name, 1, false)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Structure field class already declared in local scope: "
- "name=\"struct %s\"", name);
- ret = -EINVAL;
- goto error;
- }
- }
-
- if (!bt_list_empty(min_align)) {
- ret = get_unary_unsigned(ctx, min_align,
- &min_align_value);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Unexpected unary expression for structure field class's `align` attribute: "
- "ret=%d", ret);
- goto error;
- }
- }
-
- *struct_decl = ctf_field_class_struct_create();
- BT_ASSERT(*struct_decl);
-
- if (min_align_value != 0) {
- (*struct_decl)->base.alignment = min_align_value;
- }
-
- _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
-
- bt_list_for_each_entry(entry_node, decl_list, siblings) {
- ret = visit_struct_decl_entry(ctx, entry_node,
- *struct_decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot visit structure field class entry: "
- "ret=%d", ret);
- ctx_pop_scope(ctx);
- goto error;
- }
- }
-
- ctx_pop_scope(ctx);
-
- if (name) {
- ret = ctx_decl_scope_register_struct(ctx,
- ctx->current_scope, name, *struct_decl);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register structure field class in declaration scope: "
- "name=\"struct %s\", ret=%d", name, ret);
- goto error;
- }
- }
- }
-
- return 0;
+ int ret = 0;
+
+ BT_ASSERT(struct_decl);
+ *struct_decl = NULL;
+
+ /* For named struct (without body), lookup in declaration scope */
+ if (!has_body) {
+ if (!name) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Bodyless structure field class: missing name.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ *struct_decl = ctx_decl_scope_lookup_struct(ctx, ctx->current_scope, name, -1, true);
+ if (!*struct_decl) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot find structure field class: name=\"struct %s\"", name);
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ struct ctf_node *entry_node;
+ uint64_t min_align_value = 0;
+
+ if (name) {
+ if (ctx_decl_scope_lookup_struct(ctx, ctx->current_scope, name, 1, false)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Structure field class already declared in local scope: "
+ "name=\"struct %s\"",
+ name);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+
+ if (!bt_list_empty(min_align)) {
+ ret = get_unary_unsigned(ctx, min_align, &min_align_value);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Unexpected unary expression for structure field class's `align` attribute: "
+ "ret=%d",
+ ret);
+ goto error;
+ }
+ }
+
+ *struct_decl = ctf_field_class_struct_create();
+ BT_ASSERT(*struct_decl);
+
+ if (min_align_value != 0) {
+ (*struct_decl)->base.alignment = min_align_value;
+ }
+
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
+
+ bt_list_for_each_entry (entry_node, decl_list, siblings) {
+ ret = visit_struct_decl_entry(ctx, entry_node, *struct_decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
+ "Cannot visit structure field class entry: "
+ "ret=%d",
+ ret);
+ ctx_pop_scope(ctx);
+ goto error;
+ }
+ }
+
+ ctx_pop_scope(ctx);
+
+ if (name) {
+ ret = ctx_decl_scope_register_struct(ctx, ctx->current_scope, name, *struct_decl);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot register structure field class in declaration scope: "
+ "name=\"struct %s\", ret=%d",
+ name, ret);
+ goto error;
+ }
+ }
+ }
+
+ return 0;
error:
- ctf_field_class_destroy(&(*struct_decl)->base);
- *struct_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&(*struct_decl)->base);
+ *struct_decl = NULL;
+ return ret;
}
-static
-int visit_variant_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
- const char *tag, struct bt_list_head *decl_list,
- int has_body, struct ctf_field_class_variant **variant_decl)
+static int visit_variant_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
+ const char *tag, struct bt_list_head *decl_list, int has_body,
+ struct ctf_field_class_variant **variant_decl)
{
- int ret = 0;
- struct ctf_field_class_variant *untagged_variant_decl = NULL;
-
- BT_ASSERT(variant_decl);
- *variant_decl = NULL;
-
- /* For named variant (without body), lookup in declaration scope */
- if (!has_body) {
- if (!name) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless variant field class: missing name.");
- ret = -EPERM;
- goto error;
- }
-
- untagged_variant_decl =
- ctx_decl_scope_lookup_variant(ctx, ctx->current_scope,
- name, -1, true);
- if (!untagged_variant_decl) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find variant field class: name=\"variant %s\"",
- name);
- ret = -EINVAL;
- goto error;
- }
- } else {
- struct ctf_node *entry_node;
-
- if (name) {
- if (ctx_decl_scope_lookup_variant(ctx,
- ctx->current_scope, name, 1, false)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Variant field class already declared in local scope: "
- "name=\"variant %s\"", name);
- ret = -EINVAL;
- goto error;
- }
- }
-
- untagged_variant_decl = ctf_field_class_variant_create();
- BT_ASSERT(untagged_variant_decl);
- _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
-
- bt_list_for_each_entry(entry_node, decl_list, siblings) {
- ret = visit_variant_decl_entry(ctx, entry_node,
- untagged_variant_decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot visit variant field class entry: "
- "ret=%d", ret);
- ctx_pop_scope(ctx);
- goto error;
- }
- }
-
- ctx_pop_scope(ctx);
-
- if (name) {
- ret = ctx_decl_scope_register_variant(ctx,
- ctx->current_scope, name,
- untagged_variant_decl);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register variant field class in declaration scope: "
- "name=\"variant %s\", ret=%d", name, ret);
- goto error;
- }
- }
- }
-
- /*
- * If tagged, create tagged variant and return; otherwise
- * return untagged variant.
- */
- if (!tag) {
- *variant_decl = untagged_variant_decl;
- untagged_variant_decl = NULL;
- } else {
- /*
- * At this point, we have a fresh untagged variant; nobody
- * else owns it. Set its tag now.
- */
- g_string_assign(untagged_variant_decl->tag_ref, tag);
- *variant_decl = untagged_variant_decl;
- untagged_variant_decl = NULL;
- }
-
- BT_ASSERT(!untagged_variant_decl);
- BT_ASSERT(*variant_decl);
- return 0;
+ int ret = 0;
+ struct ctf_field_class_variant *untagged_variant_decl = NULL;
+
+ BT_ASSERT(variant_decl);
+ *variant_decl = NULL;
+
+ /* For named variant (without body), lookup in declaration scope */
+ if (!has_body) {
+ if (!name) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless variant field class: missing name.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ untagged_variant_decl =
+ ctx_decl_scope_lookup_variant(ctx, ctx->current_scope, name, -1, true);
+ if (!untagged_variant_decl) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot find variant field class: name=\"variant %s\"", name);
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ struct ctf_node *entry_node;
+
+ if (name) {
+ if (ctx_decl_scope_lookup_variant(ctx, ctx->current_scope, name, 1, false)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Variant field class already declared in local scope: "
+ "name=\"variant %s\"",
+ name);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+
+ untagged_variant_decl = ctf_field_class_variant_create();
+ BT_ASSERT(untagged_variant_decl);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
+
+ bt_list_for_each_entry (entry_node, decl_list, siblings) {
+ ret = visit_variant_decl_entry(ctx, entry_node, untagged_variant_decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
+ "Cannot visit variant field class entry: "
+ "ret=%d",
+ ret);
+ ctx_pop_scope(ctx);
+ goto error;
+ }
+ }
+
+ ctx_pop_scope(ctx);
+
+ if (name) {
+ ret = ctx_decl_scope_register_variant(ctx, ctx->current_scope, name,
+ untagged_variant_decl);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot register variant field class in declaration scope: "
+ "name=\"variant %s\", ret=%d",
+ name, ret);
+ goto error;
+ }
+ }
+ }
+
+ /*
+ * If tagged, create tagged variant and return; otherwise
+ * return untagged variant.
+ */
+ if (!tag) {
+ *variant_decl = untagged_variant_decl;
+ untagged_variant_decl = NULL;
+ } else {
+ /*
+ * At this point, we have a fresh untagged variant; nobody
+ * else owns it. Set its tag now.
+ */
+ g_string_assign(untagged_variant_decl->tag_ref, tag);
+ *variant_decl = untagged_variant_decl;
+ untagged_variant_decl = NULL;
+ }
+
+ BT_ASSERT(!untagged_variant_decl);
+ BT_ASSERT(*variant_decl);
+ return 0;
error:
- ctf_field_class_destroy(&untagged_variant_decl->base);
- untagged_variant_decl = NULL;
- ctf_field_class_destroy(&(*variant_decl)->base);
- *variant_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&untagged_variant_decl->base);
+ untagged_variant_decl = NULL;
+ ctf_field_class_destroy(&(*variant_decl)->base);
+ *variant_decl = NULL;
+ return ret;
}
-struct uori {
- bool is_signed;
- union {
- uint64_t u;
- uint64_t i;
- } value;
+struct uori
+{
+ bool is_signed;
+ union
+ {
+ uint64_t u;
+ uint64_t i;
+ } value;
};
-static
-int visit_enum_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *enumerator,
- struct ctf_field_class_enum *enum_decl, struct uori *last)
+static int visit_enum_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *enumerator,
+ struct ctf_field_class_enum *enum_decl, struct uori *last)
{
- int ret = 0;
- int nr_vals = 0;
- struct ctf_node *iter;
- struct uori start = {
- .is_signed = false,
- .value = {
- .u = 0,
- },
- };
- struct uori end = {
- .is_signed = false,
- .value = {
- .u = 0,
- },
- };
- const char *label = enumerator->u.enumerator.id;
- struct bt_list_head *values = &enumerator->u.enumerator.values;
-
- bt_list_for_each_entry(iter, values, siblings) {
- struct uori *target;
-
- if (iter->type != NODE_UNARY_EXPRESSION) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Wrong expression for enumeration field class label: "
- "node-type=%d, label=\"%s\"", iter->type,
- label);
- ret = -EINVAL;
- goto error;
- }
-
- if (nr_vals == 0) {
- target = &start;
- } else {
- target = &end;
- }
-
- switch (iter->u.unary_expression.type) {
- case UNARY_SIGNED_CONSTANT:
- target->is_signed = true;
- target->value.i =
- iter->u.unary_expression.u.signed_constant;
- break;
- case UNARY_UNSIGNED_CONSTANT:
- target->is_signed = false;
- target->value.u =
- iter->u.unary_expression.u.unsigned_constant;
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Invalid enumeration field class entry: "
- "expecting constant signed or unsigned integer: "
- "node-type=%d, label=\"%s\"",
- iter->u.unary_expression.type, label);
- ret = -EINVAL;
- goto error;
- }
-
- if (nr_vals > 1) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Invalid enumeration field class entry: label=\"%s\"",
- label);
- ret = -EINVAL;
- goto error;
- }
-
- nr_vals++;
- }
-
- if (nr_vals == 0) {
- start = *last;
- }
-
- if (nr_vals <= 1) {
- end = start;
- }
-
- if (end.is_signed) {
- last->value.i = end.value.i + 1;
- } else {
- last->value.u = end.value.u + 1;
- }
-
- ctf_field_class_enum_map_range(enum_decl, label,
- start.value.u, end.value.u);
- return 0;
+ int ret = 0;
+ int nr_vals = 0;
+ struct ctf_node *iter;
+ struct uori start = {
+ .is_signed = false,
+ .value =
+ {
+ .u = 0,
+ },
+ };
+ struct uori end = {
+ .is_signed = false,
+ .value =
+ {
+ .u = 0,
+ },
+ };
+ const char *label = enumerator->u.enumerator.id;
+ struct bt_list_head *values = &enumerator->u.enumerator.values;
+
+ bt_list_for_each_entry (iter, values, siblings) {
+ struct uori *target;
+
+ if (iter->type != NODE_UNARY_EXPRESSION) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Wrong expression for enumeration field class label: "
+ "node-type=%d, label=\"%s\"",
+ iter->type, label);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (nr_vals == 0) {
+ target = &start;
+ } else {
+ target = &end;
+ }
+
+ switch (iter->u.unary_expression.type) {
+ case UNARY_SIGNED_CONSTANT:
+ target->is_signed = true;
+ target->value.i = iter->u.unary_expression.u.signed_constant;
+ break;
+ case UNARY_UNSIGNED_CONSTANT:
+ target->is_signed = false;
+ target->value.u = iter->u.unary_expression.u.unsigned_constant;
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Invalid enumeration field class entry: "
+ "expecting constant signed or unsigned integer: "
+ "node-type=%d, label=\"%s\"",
+ iter->u.unary_expression.type, label);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (nr_vals > 1) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ iter, "Invalid enumeration field class entry: label=\"%s\"", label);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ nr_vals++;
+ }
+
+ if (nr_vals == 0) {
+ start = *last;
+ }
+
+ if (nr_vals <= 1) {
+ end = start;
+ }
+
+ if (end.is_signed) {
+ last->value.i = end.value.i + 1;
+ } else {
+ last->value.u = end.value.u + 1;
+ }
+
+ ctf_field_class_enum_map_range(enum_decl, label, start.value.u, end.value.u);
+ return 0;
error:
- return ret;
+ return ret;
}
-static
-int visit_enum_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
- struct ctf_node *container_cls,
- struct bt_list_head *enumerator_list,
- int has_body, struct ctf_field_class_enum **enum_decl)
+static int visit_enum_decl(struct ctf_visitor_generate_ir *ctx, const char *name,
+ struct ctf_node *container_cls, struct bt_list_head *enumerator_list,
+ int has_body, struct ctf_field_class_enum **enum_decl)
{
- int ret = 0;
- GQuark qdummy_id;
- struct ctf_field_class_int *integer_decl = NULL;
-
- BT_ASSERT(enum_decl);
- *enum_decl = NULL;
-
- /* For named enum (without body), lookup in declaration scope */
- if (!has_body) {
- if (!name) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless enumeration field class: missing name.");
- ret = -EPERM;
- goto error;
- }
-
- *enum_decl = ctx_decl_scope_lookup_enum(ctx, ctx->current_scope,
- name, -1, true);
- if (!*enum_decl) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find enumeration field class: "
- "name=\"enum %s\"", name);
- ret = -EINVAL;
- goto error;
- }
- } else {
- struct ctf_node *iter;
- struct uori last_value = {
- .is_signed = false,
- .value = {
- .u = 0,
- },
- };
-
- if (name) {
- if (ctx_decl_scope_lookup_enum(ctx, ctx->current_scope,
- name, 1, false)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Enumeration field class already declared in local scope: "
- "name=\"enum %s\"", name);
- ret = -EINVAL;
- goto error;
- }
- }
-
- if (!container_cls) {
- integer_decl = ctf_field_class_as_int(ctx_decl_scope_lookup_alias(ctx,
- ctx->current_scope, "int", -1, true));
- if (!integer_decl) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find implicit `int` field class alias for enumeration field class.");
- ret = -EINVAL;
- goto error;
- }
- } else {
- ctf_field_class *decl;
-
- ret = visit_field_class_declarator(ctx, container_cls,
- &qdummy_id, NULL, &decl, NULL);
- if (ret) {
- BT_ASSERT(!decl);
- ret = -EINVAL;
- goto error;
- }
-
- integer_decl = ctf_field_class_as_int(decl);
- }
-
- BT_ASSERT(integer_decl);
-
- if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Container field class for enumeration field class is not an integer field class: "
- "fc-type=%d", integer_decl->base.base.type);
- ret = -EINVAL;
- goto error;
- }
-
- *enum_decl = ctf_field_class_enum_create();
- BT_ASSERT(*enum_decl);
- (*enum_decl)->base.base.base.alignment =
- integer_decl->base.base.alignment;
- ctf_field_class_int_copy_content(
- &(*enum_decl)->base, integer_decl);
- last_value.is_signed = (*enum_decl)->base.is_signed;
-
- bt_list_for_each_entry(iter, enumerator_list, siblings) {
- ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
- &last_value);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit enumeration field class entry: "
- "ret=%d", ret);
- goto error;
- }
- }
-
- if (name) {
- ret = ctx_decl_scope_register_enum(ctx,
- ctx->current_scope, name, *enum_decl);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register enumeration field class in declaration scope: "
- "ret=%d", ret);
- goto error;
- }
- }
- }
-
- goto end;
+ int ret = 0;
+ GQuark qdummy_id;
+ struct ctf_field_class_int *integer_decl = NULL;
+
+ BT_ASSERT(enum_decl);
+ *enum_decl = NULL;
+
+ /* For named enum (without body), lookup in declaration scope */
+ if (!has_body) {
+ if (!name) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Bodyless enumeration field class: missing name.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ *enum_decl = ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, name, -1, true);
+ if (!*enum_decl) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find enumeration field class: "
+ "name=\"enum %s\"",
+ name);
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ struct ctf_node *iter;
+ struct uori last_value = {
+ .is_signed = false,
+ .value =
+ {
+ .u = 0,
+ },
+ };
+
+ if (name) {
+ if (ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, name, 1, false)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Enumeration field class already declared in local scope: "
+ "name=\"enum %s\"",
+ name);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+
+ if (!container_cls) {
+ integer_decl = ctf_field_class_as_int(
+ ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, "int", -1, true));
+ if (!integer_decl) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot find implicit `int` field class alias for enumeration field class.");
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ ctf_field_class *decl;
+
+ ret = visit_field_class_declarator(ctx, container_cls, &qdummy_id, NULL, &decl, NULL);
+ if (ret) {
+ BT_ASSERT(!decl);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ integer_decl = ctf_field_class_as_int(decl);
+ }
+
+ BT_ASSERT(integer_decl);
+
+ if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Container field class for enumeration field class is not an integer field class: "
+ "fc-type=%d",
+ integer_decl->base.base.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ *enum_decl = ctf_field_class_enum_create();
+ BT_ASSERT(*enum_decl);
+ (*enum_decl)->base.base.base.alignment = integer_decl->base.base.alignment;
+ ctf_field_class_int_copy_content(&(*enum_decl)->base, integer_decl);
+ last_value.is_signed = (*enum_decl)->base.is_signed;
+
+ bt_list_for_each_entry (iter, enumerator_list, siblings) {
+ ret = visit_enum_decl_entry(ctx, iter, *enum_decl, &last_value);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Cannot visit enumeration field class entry: "
+ "ret=%d",
+ ret);
+ goto error;
+ }
+ }
+
+ if (name) {
+ ret = ctx_decl_scope_register_enum(ctx, ctx->current_scope, name, *enum_decl);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot register enumeration field class in declaration scope: "
+ "ret=%d",
+ ret);
+ goto error;
+ }
+ }
+ }
+
+ goto end;
error:
- ctf_field_class_destroy(&(*enum_decl)->base.base.base);
- *enum_decl = NULL;
+ ctf_field_class_destroy(&(*enum_decl)->base.base.base);
+ *enum_decl = NULL;
end:
- ctf_field_class_destroy(&integer_decl->base.base);
- integer_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&integer_decl->base.base);
+ integer_decl = NULL;
+ return ret;
}
-static
-int visit_field_class_specifier(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *cls_specifier_list,
- struct ctf_field_class **decl)
+static int visit_field_class_specifier(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *cls_specifier_list,
+ struct ctf_field_class **decl)
{
- int ret = 0;
- GString *str = NULL;
-
- *decl = NULL;
- str = g_string_new("");
- ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Cannot get field class specifier list's name: ret=%d", ret);
- goto error;
- }
-
- *decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, str->str,
- -1, true);
- if (!*decl) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
- "Cannot find field class alias: name=\"%s\"", str->str);
- ret = -EINVAL;
- goto error;
- }
-
- goto end;
+ int ret = 0;
+ GString *str = NULL;
+
+ *decl = NULL;
+ str = g_string_new("");
+ ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ cls_specifier_list, "Cannot get field class specifier list's name: ret=%d", ret);
+ goto error;
+ }
+
+ *decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, str->str, -1, true);
+ if (!*decl) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list,
+ "Cannot find field class alias: name=\"%s\"", str->str);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ goto end;
error:
- ctf_field_class_destroy(*decl);
- *decl = NULL;
+ ctf_field_class_destroy(*decl);
+ *decl = NULL;
end:
- if (str) {
- g_string_free(str, TRUE);
- }
+ if (str) {
+ g_string_free(str, TRUE);
+ }
- return ret;
+ return ret;
}
-static
-int visit_integer_decl(struct ctf_visitor_generate_ir *ctx,
- struct bt_list_head *expressions,
- struct ctf_field_class_int **integer_decl)
+static int visit_integer_decl(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *expressions,
+ struct ctf_field_class_int **integer_decl)
{
- int set = 0;
- int ret = 0;
- int signedness = 0;
- struct ctf_node *expression;
- uint64_t alignment = 0, size = 0;
- struct ctf_clock_class *mapped_clock_class = NULL;
- enum ctf_encoding encoding = CTF_ENCODING_NONE;
- bt_field_class_integer_preferred_display_base base =
- BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
- enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
-
- *integer_decl = NULL;
-
- bt_list_for_each_entry(expression, expressions, siblings) {
- struct ctf_node *left, *right;
-
- left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
- struct ctf_node, siblings);
- right = _BT_LIST_FIRST_ENTRY(
- &expression->u.ctf_expression.right, struct ctf_node,
- siblings);
-
- if (left->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(left,
- "Unexpected unary expression type: type=%d",
- left->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left->u.unary_expression.u.string, "signed") == 0) {
- if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "signed",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- signedness = get_boolean(ctx, right);
- if (signedness < 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid boolean value for integer field class's `signed` attribute: "
- "ret=%d", ret);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_SIGNED_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) {
- if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- byte_order = get_real_byte_order(ctx, right);
- if (byte_order == CTF_BYTE_ORDER_UNKNOWN) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `byte_order` attribute in integer field class: "
- "ret=%d", ret);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_BYTE_ORDER_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "size") == 0) {
- if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "size",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type !=
- UNARY_UNSIGNED_CONSTANT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `size` attribute in integer field class: "
- "expecting unsigned constant integer: "
- "node-type=%d",
- right->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- size = right->u.unary_expression.u.unsigned_constant;
- if (size == 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `size` attribute in integer field class: "
- "expecting positive constant integer: "
- "size=%" PRIu64, size);
- ret = -EINVAL;
- goto error;
- } else if (size > 64) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `size` attribute in integer field class: "
- "integer fields over 64 bits are not supported as of this version: "
- "size=%" PRIu64, size);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_SIZE_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) {
- if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type !=
- UNARY_UNSIGNED_CONSTANT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `align` attribute in integer field class: "
- "expecting unsigned constant integer: "
- "node-type=%d",
- right->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- alignment =
- right->u.unary_expression.u.unsigned_constant;
- if (!is_align_valid(alignment)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `align` attribute in integer field class: "
- "expecting power of two: "
- "align=%" PRIu64, alignment);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_ALIGN_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "base") == 0) {
- if (_IS_SET(&set, _INTEGER_BASE_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "base",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- switch (right->u.unary_expression.type) {
- case UNARY_UNSIGNED_CONSTANT:
- {
- uint64_t constant = right->u.unary_expression.
- u.unsigned_constant;
-
- switch (constant) {
- case 2:
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
- break;
- case 8:
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
- break;
- case 10:
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
- break;
- case 16:
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `base` attribute in integer field class: "
- "base=%" PRIu64,
- right->u.unary_expression.u.unsigned_constant);
- ret = -EINVAL;
- goto error;
- }
- break;
- }
- case UNARY_STRING:
- {
- char *s_right = ctf_ast_concatenate_unary_strings(
- &expression->u.ctf_expression.right);
- if (!s_right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Unexpected unary expression for integer field class's `base` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(s_right, "decimal") == 0 ||
- strcmp(s_right, "dec") == 0 ||
- strcmp(s_right, "d") == 0 ||
- strcmp(s_right, "i") == 0 ||
- strcmp(s_right, "u") == 0) {
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
- } else if (strcmp(s_right, "hexadecimal") == 0 ||
- strcmp(s_right, "hex") == 0 ||
- strcmp(s_right, "x") == 0 ||
- strcmp(s_right, "X") == 0 ||
- strcmp(s_right, "p") == 0) {
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
- } else if (strcmp(s_right, "octal") == 0 ||
- strcmp(s_right, "oct") == 0 ||
- strcmp(s_right, "o") == 0) {
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
- } else if (strcmp(s_right, "binary") == 0 ||
- strcmp(s_right, "b") == 0) {
- base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
- } else {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Unexpected unary expression for integer field class's `base` attribute: "
- "base=\"%s\"", s_right);
- g_free(s_right);
- ret = -EINVAL;
- goto error;
- }
-
- g_free(s_right);
- break;
- }
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `base` attribute in integer field class: "
- "expecting unsigned constant integer or unary string.");
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_BASE_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) {
- char *s_right;
-
- if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `encoding` attribute in integer field class: "
- "expecting unary string.");
- ret = -EINVAL;
- goto error;
- }
-
- s_right = ctf_ast_concatenate_unary_strings(
- &expression->u.ctf_expression.right);
- if (!s_right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Unexpected unary expression for integer field class's `encoding` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(s_right, "UTF8") == 0 ||
- strcmp(s_right, "utf8") == 0 ||
- strcmp(s_right, "utf-8") == 0 ||
- strcmp(s_right, "UTF-8") == 0 ||
- strcmp(s_right, "ASCII") == 0 ||
- strcmp(s_right, "ascii") == 0) {
- encoding = CTF_ENCODING_UTF8;
- } else if (strcmp(s_right, "none") == 0) {
- encoding = CTF_ENCODING_NONE;
- } else {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `encoding` attribute in integer field class: "
- "unknown encoding: encoding=\"%s\"",
- s_right);
- g_free(s_right);
- ret = -EINVAL;
- goto error;
- }
-
- g_free(s_right);
- _SET(&set, _INTEGER_ENCODING_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "map") == 0) {
- const char *clock_name;
-
- if (_IS_SET(&set, _INTEGER_MAP_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "map",
- "integer field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `map` attribute in integer field class: "
- "expecting unary string.");
- ret = -EINVAL;
- goto error;
- }
-
- clock_name =
- get_map_clock_name_value(
- &expression->u.ctf_expression.right);
- if (!clock_name) {
- char *s_right = ctf_ast_concatenate_unary_strings(
- &expression->u.ctf_expression.right);
-
- if (!s_right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Unexpected unary expression for integer field class's `map` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- _BT_COMP_LOGE_NODE(right,
- "Invalid `map` attribute in integer field class: "
- "cannot find clock class at this point: name=\"%s\"",
- s_right);
- _SET(&set, _INTEGER_MAP_SET);
- g_free(s_right);
- continue;
- }
-
- mapped_clock_class =
- ctf_trace_class_borrow_clock_class_by_name(
- ctx->ctf_tc, clock_name);
- if (!mapped_clock_class) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `map` attribute in integer field class: "
- "cannot find clock class at this point: name=\"%s\"",
- clock_name);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _INTEGER_MAP_SET);
- } else {
- _BT_COMP_LOGW_NODE(left,
- "Unknown attribute in integer field class: "
- "attr-name=\"%s\"",
- left->u.unary_expression.u.string);
- }
- }
-
- if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `size` attribute in integer field class.");
- ret = -EPERM;
- goto error;
- }
-
- if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
- if (size % CHAR_BIT) {
- /* Bit-packed alignment */
- alignment = 1;
- } else {
- /* Byte-packed alignment */
- alignment = CHAR_BIT;
- }
- }
-
- *integer_decl = ctf_field_class_int_create();
- BT_ASSERT(*integer_decl);
- (*integer_decl)->base.base.alignment = alignment;
- (*integer_decl)->base.byte_order = byte_order;
- (*integer_decl)->base.size = size;
- (*integer_decl)->is_signed = (signedness > 0);
- (*integer_decl)->disp_base = base;
- (*integer_decl)->encoding = encoding;
- (*integer_decl)->mapped_clock_class = mapped_clock_class;
- return 0;
+ int set = 0;
+ int ret = 0;
+ int signedness = 0;
+ struct ctf_node *expression;
+ uint64_t alignment = 0, size = 0;
+ struct ctf_clock_class *mapped_clock_class = NULL;
+ enum ctf_encoding encoding = CTF_ENCODING_NONE;
+ bt_field_class_integer_preferred_display_base base =
+ BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+ enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
+
+ *integer_decl = NULL;
+
+ bt_list_for_each_entry (expression, expressions, siblings) {
+ struct ctf_node *left, *right;
+
+ left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings);
+ right =
+ _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings);
+
+ if (left->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d",
+ left->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left->u.unary_expression.u.string, "signed") == 0) {
+ if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "signed", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ signedness = get_boolean(ctx, right);
+ if (signedness < 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid boolean value for integer field class's `signed` attribute: "
+ "ret=%d",
+ ret);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_SIGNED_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) {
+ if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ byte_order = get_real_byte_order(ctx, right);
+ if (byte_order == CTF_BYTE_ORDER_UNKNOWN) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `byte_order` attribute in integer field class: "
+ "ret=%d",
+ ret);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_BYTE_ORDER_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "size") == 0) {
+ if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "size", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
+ "Invalid `size` attribute in integer field class: "
+ "expecting unsigned constant integer: "
+ "node-type=%d",
+ right->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ size = right->u.unary_expression.u.unsigned_constant;
+ if (size == 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
+ "Invalid `size` attribute in integer field class: "
+ "expecting positive constant integer: "
+ "size=%" PRIu64,
+ size);
+ ret = -EINVAL;
+ goto error;
+ } else if (size > 64) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `size` attribute in integer field class: "
+ "integer fields over 64 bits are not supported as of this version: "
+ "size=%" PRIu64,
+ size);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_SIZE_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) {
+ if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
+ "Invalid `align` attribute in integer field class: "
+ "expecting unsigned constant integer: "
+ "node-type=%d",
+ right->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ alignment = right->u.unary_expression.u.unsigned_constant;
+ if (!is_align_valid(alignment)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
+ "Invalid `align` attribute in integer field class: "
+ "expecting power of two: "
+ "align=%" PRIu64,
+ alignment);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_ALIGN_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "base") == 0) {
+ if (_IS_SET(&set, _INTEGER_BASE_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "base", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ switch (right->u.unary_expression.type) {
+ case UNARY_UNSIGNED_CONSTANT:
+ {
+ uint64_t constant = right->u.unary_expression.u.unsigned_constant;
+
+ switch (constant) {
+ case 2:
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
+ break;
+ case 8:
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
+ break;
+ case 10:
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+ break;
+ case 16:
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `base` attribute in integer field class: "
+ "base=%" PRIu64,
+ right->u.unary_expression.u.unsigned_constant);
+ ret = -EINVAL;
+ goto error;
+ }
+ break;
+ }
+ case UNARY_STRING:
+ {
+ char *s_right =
+ ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right);
+ if (!s_right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Unexpected unary expression for integer field class's `base` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(s_right, "decimal") == 0 || strcmp(s_right, "dec") == 0 ||
+ strcmp(s_right, "d") == 0 || strcmp(s_right, "i") == 0 ||
+ strcmp(s_right, "u") == 0) {
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+ } else if (strcmp(s_right, "hexadecimal") == 0 || strcmp(s_right, "hex") == 0 ||
+ strcmp(s_right, "x") == 0 || strcmp(s_right, "X") == 0 ||
+ strcmp(s_right, "p") == 0) {
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
+ } else if (strcmp(s_right, "octal") == 0 || strcmp(s_right, "oct") == 0 ||
+ strcmp(s_right, "o") == 0) {
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
+ } else if (strcmp(s_right, "binary") == 0 || strcmp(s_right, "b") == 0) {
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
+ } else {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Unexpected unary expression for integer field class's `base` attribute: "
+ "base=\"%s\"",
+ s_right);
+ g_free(s_right);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_free(s_right);
+ break;
+ }
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right, "Invalid `base` attribute in integer field class: "
+ "expecting unsigned constant integer or unary string.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_BASE_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) {
+ char *s_right;
+
+ if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right, "Invalid `encoding` attribute in integer field class: "
+ "expecting unary string.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ s_right = ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right);
+ if (!s_right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Unexpected unary expression for integer field class's `encoding` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(s_right, "UTF8") == 0 || strcmp(s_right, "utf8") == 0 ||
+ strcmp(s_right, "utf-8") == 0 || strcmp(s_right, "UTF-8") == 0 ||
+ strcmp(s_right, "ASCII") == 0 || strcmp(s_right, "ascii") == 0) {
+ encoding = CTF_ENCODING_UTF8;
+ } else if (strcmp(s_right, "none") == 0) {
+ encoding = CTF_ENCODING_NONE;
+ } else {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `encoding` attribute in integer field class: "
+ "unknown encoding: encoding=\"%s\"",
+ s_right);
+ g_free(s_right);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_free(s_right);
+ _SET(&set, _INTEGER_ENCODING_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "map") == 0) {
+ const char *clock_name;
+
+ if (_IS_SET(&set, _INTEGER_MAP_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "map", "integer field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
+ "Invalid `map` attribute in integer field class: "
+ "expecting unary string.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
+ if (!clock_name) {
+ char *s_right =
+ ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right);
+
+ if (!s_right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Unexpected unary expression for integer field class's `map` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _BT_COMP_LOGE_NODE(right,
+ "Invalid `map` attribute in integer field class: "
+ "cannot find clock class at this point: name=\"%s\"",
+ s_right);
+ _SET(&set, _INTEGER_MAP_SET);
+ g_free(s_right);
+ continue;
+ }
+
+ mapped_clock_class =
+ ctf_trace_class_borrow_clock_class_by_name(ctx->ctf_tc, clock_name);
+ if (!mapped_clock_class) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `map` attribute in integer field class: "
+ "cannot find clock class at this point: name=\"%s\"",
+ clock_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _INTEGER_MAP_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(left,
+ "Unknown attribute in integer field class: "
+ "attr-name=\"%s\"",
+ left->u.unary_expression.u.string);
+ }
+ }
+
+ if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Missing `size` attribute in integer field class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
+ if (size % CHAR_BIT) {
+ /* Bit-packed alignment */
+ alignment = 1;
+ } else {
+ /* Byte-packed alignment */
+ alignment = CHAR_BIT;
+ }
+ }
+
+ *integer_decl = ctf_field_class_int_create();
+ BT_ASSERT(*integer_decl);
+ (*integer_decl)->base.base.alignment = alignment;
+ (*integer_decl)->base.byte_order = byte_order;
+ (*integer_decl)->base.size = size;
+ (*integer_decl)->is_signed = (signedness > 0);
+ (*integer_decl)->disp_base = base;
+ (*integer_decl)->encoding = encoding;
+ (*integer_decl)->mapped_clock_class = mapped_clock_class;
+ return 0;
error:
- ctf_field_class_destroy(&(*integer_decl)->base.base);
- *integer_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&(*integer_decl)->base.base);
+ *integer_decl = NULL;
+ return ret;
}
-static
-int visit_floating_point_number_decl(struct ctf_visitor_generate_ir *ctx,
- struct bt_list_head *expressions,
- struct ctf_field_class_float **float_decl)
+static int visit_floating_point_number_decl(struct ctf_visitor_generate_ir *ctx,
+ struct bt_list_head *expressions,
+ struct ctf_field_class_float **float_decl)
{
- int set = 0;
- int ret = 0;
- struct ctf_node *expression;
- uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
- enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
-
- *float_decl = NULL;
-
- bt_list_for_each_entry(expression, expressions, siblings) {
- struct ctf_node *left, *right;
-
- left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
- struct ctf_node, siblings);
- right = _BT_LIST_FIRST_ENTRY(
- &expression->u.ctf_expression.right, struct ctf_node,
- siblings);
-
- if (left->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(left,
- "Unexpected unary expression type: type=%d",
- left->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) {
- if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order",
- "floating point number field class");
- ret = -EPERM;
- goto error;
- }
-
- byte_order = get_real_byte_order(ctx, right);
- if (byte_order == CTF_BYTE_ORDER_UNKNOWN) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `byte_order` attribute in floating point number field class: "
- "ret=%d", ret);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _FLOAT_BYTE_ORDER_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "exp_dig") == 0) {
- if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "exp_dig",
- "floating point number field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type !=
- UNARY_UNSIGNED_CONSTANT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `exp_dig` attribute in floating point number field class: "
- "expecting unsigned constant integer: "
- "node-type=%d",
- right->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- exp_dig = right->u.unary_expression.u.unsigned_constant;
- _SET(&set, _FLOAT_EXP_DIG_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "mant_dig") == 0) {
- if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "mant_dig",
- "floating point number field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type !=
- UNARY_UNSIGNED_CONSTANT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `mant_dig` attribute in floating point number field class: "
- "expecting unsigned constant integer: "
- "node-type=%d",
- right->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- mant_dig = right->u.unary_expression.u.
- unsigned_constant;
- _SET(&set, _FLOAT_MANT_DIG_SET);
- } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) {
- if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align",
- "floating point number field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type !=
- UNARY_UNSIGNED_CONSTANT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `align` attribute in floating point number field class: "
- "expecting unsigned constant integer: "
- "node-type=%d",
- right->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- alignment = right->u.unary_expression.u.
- unsigned_constant;
-
- if (!is_align_valid(alignment)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `align` attribute in floating point number field class: "
- "expecting power of two: "
- "align=%" PRIu64, alignment);
- ret = -EINVAL;
- goto error;
- }
-
- _SET(&set, _FLOAT_ALIGN_SET);
- } else {
- _BT_COMP_LOGW_NODE(left,
- "Unknown attribute in floating point number field class: "
- "attr-name=\"%s\"",
- left->u.unary_expression.u.string);
- }
- }
-
- if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `mant_dig` attribute in floating point number field class.");
- ret = -EPERM;
- goto error;
- }
-
- if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `exp_dig` attribute in floating point number field class.");
- ret = -EPERM;
- goto error;
- }
-
- if (mant_dig != 24 && mant_dig != 53) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`mant_dig` attribute: expecting 24 or 53.");
- ret = -EPERM;
- goto error;
- }
-
- if (mant_dig == 24 && exp_dig != 8) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
- ret = -EPERM;
- goto error;
- }
-
- if (mant_dig == 53 && exp_dig != 11) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
- ret = -EPERM;
- goto error;
- }
-
- if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
- if ((mant_dig + exp_dig) % CHAR_BIT) {
- /* Bit-packed alignment */
- alignment = 1;
- } else {
- /* Byte-packed alignment */
- alignment = CHAR_BIT;
- }
- }
-
- *float_decl = ctf_field_class_float_create();
- BT_ASSERT(*float_decl);
- (*float_decl)->base.base.alignment = alignment;
- (*float_decl)->base.byte_order = byte_order;
- (*float_decl)->base.size = mant_dig + exp_dig;
- return 0;
+ int set = 0;
+ int ret = 0;
+ struct ctf_node *expression;
+ uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
+ enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
+
+ *float_decl = NULL;
+
+ bt_list_for_each_entry (expression, expressions, siblings) {
+ struct ctf_node *left, *right;
+
+ left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings);
+ right =
+ _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings);
+
+ if (left->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d",
+ left->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) {
+ if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order",
+ "floating point number field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ byte_order = get_real_byte_order(ctx, right);
+ if (byte_order == CTF_BYTE_ORDER_UNKNOWN) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `byte_order` attribute in floating point number field class: "
+ "ret=%d",
+ ret);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _FLOAT_BYTE_ORDER_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "exp_dig") == 0) {
+ if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "exp_dig",
+ "floating point number field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `exp_dig` attribute in floating point number field class: "
+ "expecting unsigned constant integer: "
+ "node-type=%d",
+ right->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ exp_dig = right->u.unary_expression.u.unsigned_constant;
+ _SET(&set, _FLOAT_EXP_DIG_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "mant_dig") == 0) {
+ if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "mant_dig",
+ "floating point number field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `mant_dig` attribute in floating point number field class: "
+ "expecting unsigned constant integer: "
+ "node-type=%d",
+ right->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ mant_dig = right->u.unary_expression.u.unsigned_constant;
+ _SET(&set, _FLOAT_MANT_DIG_SET);
+ } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) {
+ if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align",
+ "floating point number field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `align` attribute in floating point number field class: "
+ "expecting unsigned constant integer: "
+ "node-type=%d",
+ right->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ alignment = right->u.unary_expression.u.unsigned_constant;
+
+ if (!is_align_valid(alignment)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `align` attribute in floating point number field class: "
+ "expecting power of two: "
+ "align=%" PRIu64,
+ alignment);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(&set, _FLOAT_ALIGN_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(left,
+ "Unknown attribute in floating point number field class: "
+ "attr-name=\"%s\"",
+ left->u.unary_expression.u.string);
+ }
+ }
+
+ if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Missing `mant_dig` attribute in floating point number field class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Missing `exp_dig` attribute in floating point number field class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig != 24 && mant_dig != 53) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`mant_dig` attribute: expecting 24 or 53.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig == 24 && exp_dig != 8) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig == 53 && exp_dig != 11) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
+ if ((mant_dig + exp_dig) % CHAR_BIT) {
+ /* Bit-packed alignment */
+ alignment = 1;
+ } else {
+ /* Byte-packed alignment */
+ alignment = CHAR_BIT;
+ }
+ }
+
+ *float_decl = ctf_field_class_float_create();
+ BT_ASSERT(*float_decl);
+ (*float_decl)->base.base.alignment = alignment;
+ (*float_decl)->base.byte_order = byte_order;
+ (*float_decl)->base.size = mant_dig + exp_dig;
+ return 0;
error:
- ctf_field_class_destroy(&(*float_decl)->base.base);
- *float_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&(*float_decl)->base.base);
+ *float_decl = NULL;
+ return ret;
}
-static
-int visit_string_decl(struct ctf_visitor_generate_ir *ctx,
- struct bt_list_head *expressions,
- struct ctf_field_class_string **string_decl)
+static int visit_string_decl(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *expressions,
+ struct ctf_field_class_string **string_decl)
{
- int set = 0;
- int ret = 0;
- struct ctf_node *expression;
- enum ctf_encoding encoding = CTF_ENCODING_UTF8;
-
- *string_decl = NULL;
-
- bt_list_for_each_entry(expression, expressions, siblings) {
- struct ctf_node *left, *right;
-
- left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
- struct ctf_node, siblings);
- right = _BT_LIST_FIRST_ENTRY(
- &expression->u.ctf_expression.right, struct ctf_node,
- siblings);
-
- if (left->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(left,
- "Unexpected unary expression type: type=%d",
- left->u.unary_expression.type);
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) {
- char *s_right;
-
- if (_IS_SET(&set, _STRING_ENCODING_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding",
- "string field class");
- ret = -EPERM;
- goto error;
- }
-
- if (right->u.unary_expression.type != UNARY_STRING) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `encoding` attribute in string field class: "
- "expecting unary string.");
- ret = -EINVAL;
- goto error;
- }
-
- s_right = ctf_ast_concatenate_unary_strings(
- &expression->u.ctf_expression.right);
- if (!s_right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Unexpected unary expression for string field class's `encoding` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(s_right, "UTF8") == 0 ||
- strcmp(s_right, "utf8") == 0 ||
- strcmp(s_right, "utf-8") == 0 ||
- strcmp(s_right, "UTF-8") == 0 ||
- strcmp(s_right, "ASCII") == 0 ||
- strcmp(s_right, "ascii") == 0) {
- encoding = CTF_ENCODING_UTF8;
- } else if (strcmp(s_right, "none") == 0) {
- encoding = CTF_ENCODING_NONE;
- } else {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(right,
- "Invalid `encoding` attribute in string field class: "
- "unknown encoding: encoding=\"%s\"",
- s_right);
- g_free(s_right);
- ret = -EINVAL;
- goto error;
- }
-
- g_free(s_right);
- _SET(&set, _STRING_ENCODING_SET);
- } else {
- _BT_COMP_LOGW_NODE(left,
- "Unknown attribute in string field class: "
- "attr-name=\"%s\"",
- left->u.unary_expression.u.string);
- }
- }
-
- *string_decl = ctf_field_class_string_create();
- BT_ASSERT(*string_decl);
- (*string_decl)->encoding = encoding;
- return 0;
+ int set = 0;
+ int ret = 0;
+ struct ctf_node *expression;
+ enum ctf_encoding encoding = CTF_ENCODING_UTF8;
+
+ *string_decl = NULL;
+
+ bt_list_for_each_entry (expression, expressions, siblings) {
+ struct ctf_node *left, *right;
+
+ left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings);
+ right =
+ _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings);
+
+ if (left->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d",
+ left->u.unary_expression.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) {
+ char *s_right;
+
+ if (_IS_SET(&set, _STRING_ENCODING_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", "string field class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (right->u.unary_expression.type != UNARY_STRING) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right, "Invalid `encoding` attribute in string field class: "
+ "expecting unary string.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ s_right = ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right);
+ if (!s_right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Unexpected unary expression for string field class's `encoding` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(s_right, "UTF8") == 0 || strcmp(s_right, "utf8") == 0 ||
+ strcmp(s_right, "utf-8") == 0 || strcmp(s_right, "UTF-8") == 0 ||
+ strcmp(s_right, "ASCII") == 0 || strcmp(s_right, "ascii") == 0) {
+ encoding = CTF_ENCODING_UTF8;
+ } else if (strcmp(s_right, "none") == 0) {
+ encoding = CTF_ENCODING_NONE;
+ } else {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ right,
+ "Invalid `encoding` attribute in string field class: "
+ "unknown encoding: encoding=\"%s\"",
+ s_right);
+ g_free(s_right);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_free(s_right);
+ _SET(&set, _STRING_ENCODING_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(left,
+ "Unknown attribute in string field class: "
+ "attr-name=\"%s\"",
+ left->u.unary_expression.u.string);
+ }
+ }
+
+ *string_decl = ctf_field_class_string_create();
+ BT_ASSERT(*string_decl);
+ (*string_decl)->encoding = encoding;
+ return 0;
error:
- ctf_field_class_destroy(&(*string_decl)->base);
- *string_decl = NULL;
- return ret;
+ ctf_field_class_destroy(&(*string_decl)->base);
+ *string_decl = NULL;
+ return ret;
}
-static
-int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *ts_list, struct ctf_field_class **decl)
+static int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_node *ts_list, struct ctf_field_class **decl)
{
- int ret = 0;
- struct ctf_node *first, *node;
-
- *decl = NULL;
-
- if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(ts_list,
- "Unexpected node type: node-type=%d", ts_list->type);
- ret = -EINVAL;
- goto error;
- }
-
- first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head,
- struct ctf_node, siblings);
- if (first->type != NODE_TYPE_SPECIFIER) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(first,
- "Unexpected node type: node-type=%d", first->type);
- ret = -EINVAL;
- goto error;
- }
-
- node = first->u.field_class_specifier.node;
-
- switch (first->u.field_class_specifier.type) {
- case TYPESPEC_INTEGER: {
- ctf_field_class_int *int_decl;
-
- ret = visit_integer_decl(ctx, &node->u.integer.expressions,
- &int_decl);
- if (ret) {
- BT_ASSERT(!int_decl);
- goto error;
- }
-
- *decl = &int_decl->base.base;
- break;
- }
- case TYPESPEC_FLOATING_POINT: {
- ctf_field_class_float *float_decl;
-
- ret = visit_floating_point_number_decl(ctx,
- &node->u.floating_point.expressions, &float_decl);
- if (ret) {
- BT_ASSERT(!float_decl);
- goto error;
- }
-
- *decl = &float_decl->base.base;
- break;
- }
- case TYPESPEC_STRING: {
- ctf_field_class_string *string_decl;
-
- ret = visit_string_decl(ctx,
- &node->u.string.expressions, &string_decl);
- if (ret) {
- BT_ASSERT(!string_decl);
- goto error;
- }
-
- *decl = &string_decl->base;
- break;
- }
- case TYPESPEC_STRUCT: {
- ctf_field_class_struct *struct_decl;
-
- ret = visit_struct_decl(ctx, node->u._struct.name,
- &node->u._struct.declaration_list,
- node->u._struct.has_body,
- &node->u._struct.min_align, &struct_decl);
- if (ret) {
- BT_ASSERT(!struct_decl);
- goto error;
- }
-
- *decl = &struct_decl->base;
- break;
- }
- case TYPESPEC_VARIANT: {
- ctf_field_class_variant *variant_decl;
-
- ret = visit_variant_decl(ctx, node->u.variant.name,
- node->u.variant.choice,
- &node->u.variant.declaration_list,
- node->u.variant.has_body, &variant_decl);
- if (ret) {
- BT_ASSERT(!variant_decl);
- goto error;
- }
-
- *decl = &variant_decl->base;
- break;
- }
- case TYPESPEC_ENUM: {
- ctf_field_class_enum *enum_decl;
-
- ret = visit_enum_decl(ctx, node->u._enum.enum_id,
- node->u._enum.container_field_class,
- &node->u._enum.enumerator_list,
- node->u._enum.has_body, &enum_decl);
- if (ret) {
- BT_ASSERT(!enum_decl);
- goto error;
- }
-
- *decl = &enum_decl->base.base.base;
- break;
- }
- case TYPESPEC_VOID:
- case TYPESPEC_CHAR:
- case TYPESPEC_SHORT:
- case TYPESPEC_INT:
- case TYPESPEC_LONG:
- case TYPESPEC_FLOAT:
- case TYPESPEC_DOUBLE:
- case TYPESPEC_SIGNED:
- case TYPESPEC_UNSIGNED:
- case TYPESPEC_BOOL:
- case TYPESPEC_COMPLEX:
- case TYPESPEC_IMAGINARY:
- case TYPESPEC_CONST:
- case TYPESPEC_ID_TYPE:
- ret = visit_field_class_specifier(ctx, ts_list, decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(first,
- "Cannot visit field class specifier: ret=%d",
- ret);
- BT_ASSERT(!*decl);
- goto error;
- }
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(first,
- "Unexpected field class specifier type: node-type=%d",
- first->u.field_class_specifier.type);
- ret = -EINVAL;
- goto error;
- }
-
- BT_ASSERT(*decl);
- return 0;
+ int ret = 0;
+ struct ctf_node *first, *node;
+
+ *decl = NULL;
+
+ if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(ts_list, "Unexpected node type: node-type=%d",
+ ts_list->type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head, struct ctf_node,
+ siblings);
+ if (first->type != NODE_TYPE_SPECIFIER) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Unexpected node type: node-type=%d", first->type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ node = first->u.field_class_specifier.node;
+
+ switch (first->u.field_class_specifier.type) {
+ case TYPESPEC_INTEGER:
+ {
+ ctf_field_class_int *int_decl;
+
+ ret = visit_integer_decl(ctx, &node->u.integer.expressions, &int_decl);
+ if (ret) {
+ BT_ASSERT(!int_decl);
+ goto error;
+ }
+
+ *decl = &int_decl->base.base;
+ break;
+ }
+ case TYPESPEC_FLOATING_POINT:
+ {
+ ctf_field_class_float *float_decl;
+
+ ret =
+ visit_floating_point_number_decl(ctx, &node->u.floating_point.expressions, &float_decl);
+ if (ret) {
+ BT_ASSERT(!float_decl);
+ goto error;
+ }
+
+ *decl = &float_decl->base.base;
+ break;
+ }
+ case TYPESPEC_STRING:
+ {
+ ctf_field_class_string *string_decl;
+
+ ret = visit_string_decl(ctx, &node->u.string.expressions, &string_decl);
+ if (ret) {
+ BT_ASSERT(!string_decl);
+ goto error;
+ }
+
+ *decl = &string_decl->base;
+ break;
+ }
+ case TYPESPEC_STRUCT:
+ {
+ ctf_field_class_struct *struct_decl;
+
+ ret = visit_struct_decl(ctx, node->u._struct.name, &node->u._struct.declaration_list,
+ node->u._struct.has_body, &node->u._struct.min_align, &struct_decl);
+ if (ret) {
+ BT_ASSERT(!struct_decl);
+ goto error;
+ }
+
+ *decl = &struct_decl->base;
+ break;
+ }
+ case TYPESPEC_VARIANT:
+ {
+ ctf_field_class_variant *variant_decl;
+
+ ret = visit_variant_decl(ctx, node->u.variant.name, node->u.variant.choice,
+ &node->u.variant.declaration_list, node->u.variant.has_body,
+ &variant_decl);
+ if (ret) {
+ BT_ASSERT(!variant_decl);
+ goto error;
+ }
+
+ *decl = &variant_decl->base;
+ break;
+ }
+ case TYPESPEC_ENUM:
+ {
+ ctf_field_class_enum *enum_decl;
+
+ ret = visit_enum_decl(ctx, node->u._enum.enum_id, node->u._enum.container_field_class,
+ &node->u._enum.enumerator_list, node->u._enum.has_body, &enum_decl);
+ if (ret) {
+ BT_ASSERT(!enum_decl);
+ goto error;
+ }
+
+ *decl = &enum_decl->base.base.base;
+ break;
+ }
+ case TYPESPEC_VOID:
+ case TYPESPEC_CHAR:
+ case TYPESPEC_SHORT:
+ case TYPESPEC_INT:
+ case TYPESPEC_LONG:
+ case TYPESPEC_FLOAT:
+ case TYPESPEC_DOUBLE:
+ case TYPESPEC_SIGNED:
+ case TYPESPEC_UNSIGNED:
+ case TYPESPEC_BOOL:
+ case TYPESPEC_COMPLEX:
+ case TYPESPEC_IMAGINARY:
+ case TYPESPEC_CONST:
+ case TYPESPEC_ID_TYPE:
+ ret = visit_field_class_specifier(ctx, ts_list, decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Cannot visit field class specifier: ret=%d",
+ ret);
+ BT_ASSERT(!*decl);
+ goto error;
+ }
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(first,
+ "Unexpected field class specifier type: node-type=%d",
+ first->u.field_class_specifier.type);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ BT_ASSERT(*decl);
+ return 0;
error:
- ctf_field_class_destroy(*decl);
- *decl = NULL;
- return ret;
+ ctf_field_class_destroy(*decl);
+ *decl = NULL;
+ return ret;
}
-static
-int visit_event_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
- struct ctf_event_class *event_class, uint64_t *stream_id,
- int *set)
+static int visit_event_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
+ struct ctf_event_class *event_class, uint64_t *stream_id,
+ int *set)
{
- int ret = 0;
- char *left = NULL;
-
- switch (node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
- &node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class found in event class.");
- goto error;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
- node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class alias found in event class.");
- goto error;
- }
- break;
- case NODE_CTF_EXPRESSION:
- {
- left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "name") == 0) {
- /* This is already known at this stage */
- if (_IS_SET(set, _EVENT_NAME_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "name", "event class");
- ret = -EPERM;
- goto error;
- }
-
- _SET(set, _EVENT_NAME_SET);
- } else if (strcmp(left, "id") == 0) {
- int64_t id = -1;
-
- if (_IS_SET(set, _EVENT_ID_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "event class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right,
- (uint64_t *) &id);
- /* Only read "id" if get_unary_unsigned() succeeded. */
- if (ret || (!ret && id < 0)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for event class's `id` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- event_class->id = id;
- _SET(set, _EVENT_ID_SET);
- } else if (strcmp(left, "stream_id") == 0) {
- if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "stream_id",
- "event class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right, stream_id);
-
- /*
- * Only read "stream_id" if get_unary_unsigned()
- * succeeded.
- */
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for event class's `stream_id` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- _SET(set, _EVENT_STREAM_ID_SET);
- } else if (strcmp(left, "context") == 0) {
- if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `context` entry in event class.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &event_class->spec_context_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create event class's context field class.");
- goto error;
- }
-
- BT_ASSERT(event_class->spec_context_fc);
- _SET(set, _EVENT_CONTEXT_SET);
- } else if (strcmp(left, "fields") == 0) {
- if (_IS_SET(set, _EVENT_FIELDS_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `fields` entry in event class.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &event_class->payload_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create event class's payload field class.");
- goto error;
- }
-
- BT_ASSERT(event_class->payload_fc);
- _SET(set, _EVENT_FIELDS_SET);
- } else if (strcmp(left, "loglevel") == 0) {
- uint64_t loglevel_value;
- bool is_log_level_known = true;
- bt_event_class_log_level log_level;
-
- if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "loglevel",
- "event class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right, &loglevel_value);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for event class's `loglevel` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- switch (loglevel_value) {
- case 0:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
- break;
- case 1:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT;
- break;
- case 2:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL;
- break;
- case 3:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR;
- break;
- case 4:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING;
- break;
- case 5:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE;
- break;
- case 6:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO;
- break;
- case 7:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
- break;
- case 8:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
- break;
- case 9:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
- break;
- case 10:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
- break;
- case 11:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
- break;
- case 12:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
- break;
- case 13:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
- break;
- case 14:
- log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG;
- break;
- default:
- is_log_level_known = false;
- _BT_COMP_LOGW_NODE(node, "Not setting event class's log level because its value is unknown: "
- "log-level=%" PRIu64, loglevel_value);
- }
-
- if (is_log_level_known) {
- ctf_event_class_set_log_level(event_class, log_level);
- }
-
- _SET(set, _EVENT_LOG_LEVEL_SET);
- } else if (strcmp(left, "model.emf.uri") == 0) {
- char *right;
-
- if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "model.emf.uri",
- "event class");
- ret = -EPERM;
- goto error;
- }
-
- right = ctf_ast_concatenate_unary_strings(
- &node->u.ctf_expression.right);
- if (!right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for event class's `model.emf.uri` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strlen(right) == 0) {
- _BT_COMP_LOGW_NODE(node,
- "Not setting event class's EMF URI because it's empty.");
- } else {
- g_string_assign(event_class->emf_uri,
- right);
- }
-
- g_free(right);
- _SET(set, _EVENT_MODEL_EMF_URI_SET);
- } else {
- _BT_COMP_LOGW_NODE(node,
- "Unknown attribute in event class: "
- "attr-name=\"%s\"", left);
- }
-
- g_free(left);
- left = NULL;
- break;
- }
- default:
- ret = -EPERM;
- goto error;
- }
-
- goto end;
+ int ret = 0;
+ char *left = NULL;
+
+ switch (node->type) {
+ case NODE_TYPEDEF:
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot add field class found in event class.");
+ goto error;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot add field class alias found in event class.");
+ goto error;
+ }
+ break;
+ case NODE_CTF_EXPRESSION:
+ {
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "name") == 0) {
+ /* This is already known at this stage */
+ if (_IS_SET(set, _EVENT_NAME_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "name", "event class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ _SET(set, _EVENT_NAME_SET);
+ } else if (strcmp(left, "id") == 0) {
+ int64_t id = -1;
+
+ if (_IS_SET(set, _EVENT_ID_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "event class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, (uint64_t *) &id);
+ /* Only read "id" if get_unary_unsigned() succeeded. */
+ if (ret || (!ret && id < 0)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for event class's `id` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ event_class->id = id;
+ _SET(set, _EVENT_ID_SET);
+ } else if (strcmp(left, "stream_id") == 0) {
+ if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "stream_id", "event class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, stream_id);
+
+ /*
+ * Only read "stream_id" if get_unary_unsigned()
+ * succeeded.
+ */
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for event class's `stream_id` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(set, _EVENT_STREAM_ID_SET);
+ } else if (strcmp(left, "context") == 0) {
+ if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `context` entry in event class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &event_class->spec_context_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot create event class's context field class.");
+ goto error;
+ }
+
+ BT_ASSERT(event_class->spec_context_fc);
+ _SET(set, _EVENT_CONTEXT_SET);
+ } else if (strcmp(left, "fields") == 0) {
+ if (_IS_SET(set, _EVENT_FIELDS_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `fields` entry in event class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &event_class->payload_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot create event class's payload field class.");
+ goto error;
+ }
+
+ BT_ASSERT(event_class->payload_fc);
+ _SET(set, _EVENT_FIELDS_SET);
+ } else if (strcmp(left, "loglevel") == 0) {
+ uint64_t loglevel_value;
+ bool is_log_level_known = true;
+ bt_event_class_log_level log_level;
+
+ if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "loglevel", "event class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &loglevel_value);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for event class's `loglevel` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ switch (loglevel_value) {
+ case 0:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
+ break;
+ case 1:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT;
+ break;
+ case 2:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL;
+ break;
+ case 3:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR;
+ break;
+ case 4:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING;
+ break;
+ case 5:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE;
+ break;
+ case 6:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO;
+ break;
+ case 7:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
+ break;
+ case 8:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
+ break;
+ case 9:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
+ break;
+ case 10:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
+ break;
+ case 11:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
+ break;
+ case 12:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
+ break;
+ case 13:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
+ break;
+ case 14:
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG;
+ break;
+ default:
+ is_log_level_known = false;
+ _BT_COMP_LOGW_NODE(
+ node,
+ "Not setting event class's log level because its value is unknown: "
+ "log-level=%" PRIu64,
+ loglevel_value);
+ }
+
+ if (is_log_level_known) {
+ ctf_event_class_set_log_level(event_class, log_level);
+ }
+
+ _SET(set, _EVENT_LOG_LEVEL_SET);
+ } else if (strcmp(left, "model.emf.uri") == 0) {
+ char *right;
+
+ if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "model.emf.uri", "event class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ right = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.right);
+ if (!right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Unexpected unary expression for event class's `model.emf.uri` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strlen(right) == 0) {
+ _BT_COMP_LOGW_NODE(node, "Not setting event class's EMF URI because it's empty.");
+ } else {
+ g_string_assign(event_class->emf_uri, right);
+ }
+
+ g_free(right);
+ _SET(set, _EVENT_MODEL_EMF_URI_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(node,
+ "Unknown attribute in event class: "
+ "attr-name=\"%s\"",
+ left);
+ }
+
+ g_free(left);
+ left = NULL;
+ break;
+ }
+ default:
+ ret = -EPERM;
+ goto error;
+ }
+
+ goto end;
error:
- g_free(left);
+ g_free(left);
end:
- return ret;
+ return ret;
}
-static
-char *get_event_decl_name(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
+static char *get_event_decl_name(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- char *left = NULL;
- char *name = NULL;
- struct ctf_node *iter;
- struct bt_list_head *decl_list = &node->u.event.declaration_list;
-
- bt_list_for_each_entry(iter, decl_list, siblings) {
- if (iter->type != NODE_CTF_EXPRESSION) {
- continue;
- }
-
- left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot concatenate unary strings.");
- goto error;
- }
-
- if (strcmp(left, "name") == 0) {
- name = ctf_ast_concatenate_unary_strings(
- &iter->u.ctf_expression.right);
- if (!name) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Unexpected unary expression for event class's `name` attribute.");
- goto error;
- }
- }
-
- g_free(left);
- left = NULL;
-
- if (name) {
- break;
- }
- }
-
- return name;
+ char *left = NULL;
+ char *name = NULL;
+ struct ctf_node *iter;
+ struct bt_list_head *decl_list = &node->u.event.declaration_list;
+
+ bt_list_for_each_entry (iter, decl_list, siblings) {
+ if (iter->type != NODE_CTF_EXPRESSION) {
+ continue;
+ }
+
+ left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot concatenate unary strings.");
+ goto error;
+ }
+
+ if (strcmp(left, "name") == 0) {
+ name = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.right);
+ if (!name) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ iter, "Unexpected unary expression for event class's `name` attribute.");
+ goto error;
+ }
+ }
+
+ g_free(left);
+ left = NULL;
+
+ if (name) {
+ break;
+ }
+ }
+
+ return name;
error:
- g_free(left);
- return NULL;
+ g_free(left);
+ return NULL;
}
-static
-int visit_event_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
+static int visit_event_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- int ret = 0;
- int set = 0;
- struct ctf_node *iter;
- uint64_t stream_id = 0;
- char *event_name = NULL;
- struct ctf_event_class *event_class = NULL;
- struct ctf_stream_class *stream_class = NULL;
- struct bt_list_head *decl_list = &node->u.event.declaration_list;
- bool pop_scope = false;
-
- if (node->visited) {
- goto end;
- }
-
- node->visited = TRUE;
- event_name = get_event_decl_name(ctx, node);
- if (!event_name) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `name` attribute in event class.");
- ret = -EPERM;
- goto error;
- }
-
- event_class = ctf_event_class_create();
- BT_ASSERT(event_class);
- g_string_assign(event_class->name, event_name);
- _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
- pop_scope = true;
-
- bt_list_for_each_entry(iter, decl_list, siblings) {
- ret = visit_event_decl_entry(ctx, iter, event_class,
- &stream_id, &set);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit event class's entry: "
- "ret=%d", ret);
- goto error;
- }
- }
-
- if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
- /*
- * Allow missing stream_id if there is only a single
- * stream class.
- */
- switch (ctx->ctf_tc->stream_classes->len) {
- case 0:
- /* Create implicit stream class if there's none */
- stream_id = 0;
- stream_class = ctf_stream_class_create();
- BT_ASSERT(stream_class);
- stream_class->id = stream_id;
- g_ptr_array_add(ctx->ctf_tc->stream_classes,
- stream_class);
- break;
- case 1:
- /* Single stream class: get its ID */
- stream_class = (ctf_stream_class *) ctx->ctf_tc->stream_classes->pdata[0];
- stream_id = stream_class->id;
- break;
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `stream_id` attribute in event class.");
- ret = -EPERM;
- goto error;
- }
- }
-
- /* We have the stream ID now; get the stream class if found */
- if (!stream_class) {
- stream_class = ctf_trace_class_borrow_stream_class_by_id(
- ctx->ctf_tc, stream_id);
- if (!stream_class) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot find stream class at this point: "
- "id=%" PRId64, stream_id);
- ret = -EINVAL;
- goto error;
- }
- }
-
- BT_ASSERT(stream_class);
-
- if (!_IS_SET(&set, _EVENT_ID_SET)) {
- /* Allow only one event without ID per stream */
- if (stream_class->event_classes->len != 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `id` attribute in event class.");
- ret = -EPERM;
- goto error;
- }
-
- /* Automatic ID */
- event_class->id = 0;
- }
-
- if (ctf_stream_class_borrow_event_class_by_id(stream_class,
- event_class->id)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate event class (same ID) in the same stream class: "
- "id=%" PRId64, event_class->id);
- ret = -EEXIST;
- goto error;
- }
-
- ctf_stream_class_append_event_class(stream_class, event_class);
- event_class = NULL;
- goto end;
+ int ret = 0;
+ int set = 0;
+ struct ctf_node *iter;
+ uint64_t stream_id = 0;
+ char *event_name = NULL;
+ struct ctf_event_class *event_class = NULL;
+ struct ctf_stream_class *stream_class = NULL;
+ struct bt_list_head *decl_list = &node->u.event.declaration_list;
+ bool pop_scope = false;
+
+ if (node->visited) {
+ goto end;
+ }
+
+ node->visited = TRUE;
+ event_name = get_event_decl_name(ctx, node);
+ if (!event_name) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `name` attribute in event class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ event_class = ctf_event_class_create();
+ BT_ASSERT(event_class);
+ g_string_assign(event_class->name, event_name);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
+ pop_scope = true;
+
+ bt_list_for_each_entry (iter, decl_list, siblings) {
+ ret = visit_event_decl_entry(ctx, iter, event_class, &stream_id, &set);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Cannot visit event class's entry: "
+ "ret=%d",
+ ret);
+ goto error;
+ }
+ }
+
+ if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
+ /*
+ * Allow missing stream_id if there is only a single
+ * stream class.
+ */
+ switch (ctx->ctf_tc->stream_classes->len) {
+ case 0:
+ /* Create implicit stream class if there's none */
+ stream_id = 0;
+ stream_class = ctf_stream_class_create();
+ BT_ASSERT(stream_class);
+ stream_class->id = stream_id;
+ g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
+ break;
+ case 1:
+ /* Single stream class: get its ID */
+ stream_class = (ctf_stream_class *) ctx->ctf_tc->stream_classes->pdata[0];
+ stream_id = stream_class->id;
+ break;
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `stream_id` attribute in event class.");
+ ret = -EPERM;
+ goto error;
+ }
+ }
+
+ /* We have the stream ID now; get the stream class if found */
+ if (!stream_class) {
+ stream_class = ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, stream_id);
+ if (!stream_class) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot find stream class at this point: "
+ "id=%" PRId64,
+ stream_id);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+
+ BT_ASSERT(stream_class);
+
+ if (!_IS_SET(&set, _EVENT_ID_SET)) {
+ /* Allow only one event without ID per stream */
+ if (stream_class->event_classes->len != 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `id` attribute in event class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ /* Automatic ID */
+ event_class->id = 0;
+ }
+
+ if (ctf_stream_class_borrow_event_class_by_id(stream_class, event_class->id)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Duplicate event class (same ID) in the same stream class: "
+ "id=%" PRId64,
+ event_class->id);
+ ret = -EEXIST;
+ goto error;
+ }
+
+ ctf_stream_class_append_event_class(stream_class, event_class);
+ event_class = NULL;
+ goto end;
error:
- ctf_event_class_destroy(event_class);
- event_class = NULL;
+ ctf_event_class_destroy(event_class);
+ event_class = NULL;
- if (ret >= 0) {
- ret = -1;
- }
+ if (ret >= 0) {
+ ret = -1;
+ }
end:
- if (pop_scope) {
- ctx_pop_scope(ctx);
- }
+ if (pop_scope) {
+ ctx_pop_scope(ctx);
+ }
- g_free(event_name);
+ g_free(event_name);
- return ret;
+ return ret;
}
-static
-int auto_map_field_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx,
- struct ctf_field_class *fc)
+static int auto_map_field_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_field_class *fc)
{
- struct ctf_clock_class *clock_class_to_map_to = NULL;
- struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc);
- int ret = 0;
- uint64_t clock_class_count;
-
- if (!fc) {
- goto end;
- }
-
- if (fc->type != CTF_FIELD_CLASS_TYPE_INT &&
- fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
- goto end;
- }
-
- if (int_fc->mapped_clock_class) {
- /* Already mapped */
- goto end;
- }
-
- clock_class_count = ctx->ctf_tc->clock_classes->len;
-
- switch (clock_class_count) {
- case 0:
- /*
- * No clock class exists in the trace at this point. Create an
- * implicit one at 1 GHz, named `default`, and use this clock
- * class.
- */
- clock_class_to_map_to = ctf_clock_class_create();
- BT_ASSERT(clock_class_to_map_to);
- clock_class_to_map_to->frequency = UINT64_C(1000000000);
- g_string_assign(clock_class_to_map_to->name, "default");
- BT_ASSERT(ret == 0);
- g_ptr_array_add(ctx->ctf_tc->clock_classes,
- clock_class_to_map_to);
- break;
- case 1:
- /*
- * Only one clock class exists in the trace at this point: use
- * this one.
- */
- clock_class_to_map_to = (ctf_clock_class *) ctx->ctf_tc->clock_classes->pdata[0];
- break;
- default:
- /*
- * Timestamp field not mapped to a clock class and there's more
- * than one clock class in the trace: this is an error.
- */
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Timestamp field found with no mapped clock class, "
- "but there's more than one clock class in the trace at this point.");
- ret = -1;
- goto end;
- }
-
- BT_ASSERT(clock_class_to_map_to);
- int_fc->mapped_clock_class = clock_class_to_map_to;
+ struct ctf_clock_class *clock_class_to_map_to = NULL;
+ struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc);
+ int ret = 0;
+ uint64_t clock_class_count;
+
+ if (!fc) {
+ goto end;
+ }
+
+ if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
+ goto end;
+ }
+
+ if (int_fc->mapped_clock_class) {
+ /* Already mapped */
+ goto end;
+ }
+
+ clock_class_count = ctx->ctf_tc->clock_classes->len;
+
+ switch (clock_class_count) {
+ case 0:
+ /*
+ * No clock class exists in the trace at this point. Create an
+ * implicit one at 1 GHz, named `default`, and use this clock
+ * class.
+ */
+ clock_class_to_map_to = ctf_clock_class_create();
+ BT_ASSERT(clock_class_to_map_to);
+ clock_class_to_map_to->frequency = UINT64_C(1000000000);
+ g_string_assign(clock_class_to_map_to->name, "default");
+ BT_ASSERT(ret == 0);
+ g_ptr_array_add(ctx->ctf_tc->clock_classes, clock_class_to_map_to);
+ break;
+ case 1:
+ /*
+ * Only one clock class exists in the trace at this point: use
+ * this one.
+ */
+ clock_class_to_map_to = (ctf_clock_class *) ctx->ctf_tc->clock_classes->pdata[0];
+ break;
+ default:
+ /*
+ * Timestamp field not mapped to a clock class and there's more
+ * than one clock class in the trace: this is an error.
+ */
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Timestamp field found with no mapped clock class, "
+ "but there's more than one clock class in the trace at this point.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(clock_class_to_map_to);
+ int_fc->mapped_clock_class = clock_class_to_map_to;
end:
- return ret;
+ return ret;
}
-static
-int auto_map_fields_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx,
- struct ctf_field_class *root_fc, const char *field_name)
+static int auto_map_fields_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_field_class *root_fc,
+ const char *field_name)
{
- int ret = 0;
- uint64_t i, count;
- struct ctf_field_class_struct *struct_fc = (ctf_field_class_struct *) root_fc;
- struct ctf_field_class_variant *var_fc = (ctf_field_class_variant *) root_fc;
-
- if (!root_fc) {
- goto end;
- }
-
- if (root_fc->type != CTF_FIELD_CLASS_TYPE_STRUCT &&
- root_fc->type != CTF_FIELD_CLASS_TYPE_VARIANT) {
- goto end;
- }
-
- if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
- count = struct_fc->members->len;
- } else {
- count = var_fc->options->len;
- }
-
- for (i = 0; i < count; i++) {
- struct ctf_named_field_class *named_fc = NULL;
-
- if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
- named_fc = ctf_field_class_struct_borrow_member_by_index(
- struct_fc, i);
- } else if (root_fc->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
- named_fc = ctf_field_class_variant_borrow_option_by_index(
- var_fc, i);
- } else {
- bt_common_abort();
- }
-
- if (strcmp(named_fc->name->str, field_name) == 0) {
- ret = auto_map_field_to_trace_clock_class(ctx,
- named_fc->fc);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot automatically map field to trace's clock class: "
- "field-name=\"%s\"", field_name);
- goto end;
- }
- }
-
- ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc,
- field_name);
- if (ret) {
- _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
- "field-name=\"%s\", root-field-name=\"%s\"",
- field_name, named_fc->name->str);
- goto end;
- }
- }
+ int ret = 0;
+ uint64_t i, count;
+ struct ctf_field_class_struct *struct_fc = (ctf_field_class_struct *) root_fc;
+ struct ctf_field_class_variant *var_fc = (ctf_field_class_variant *) root_fc;
+
+ if (!root_fc) {
+ goto end;
+ }
+
+ if (root_fc->type != CTF_FIELD_CLASS_TYPE_STRUCT &&
+ root_fc->type != CTF_FIELD_CLASS_TYPE_VARIANT) {
+ goto end;
+ }
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ count = struct_fc->members->len;
+ } else {
+ count = var_fc->options->len;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct ctf_named_field_class *named_fc = NULL;
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ named_fc = ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
+ } else if (root_fc->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ named_fc = ctf_field_class_variant_borrow_option_by_index(var_fc, i);
+ } else {
+ bt_common_abort();
+ }
+
+ if (strcmp(named_fc->name->str, field_name) == 0) {
+ ret = auto_map_field_to_trace_clock_class(ctx, named_fc->fc);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot automatically map field to trace's clock class: "
+ "field-name=\"%s\"",
+ field_name);
+ goto end;
+ }
+ }
+
+ ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc, field_name);
+ if (ret) {
+ _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
+ "Cannot automatically map structure or variant field class's fields to trace's clock class: "
+ "field-name=\"%s\", root-field-name=\"%s\"",
+ field_name, named_fc->name->str);
+ goto end;
+ }
+ }
end:
- return ret;
+ return ret;
}
-static
-int visit_stream_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
- struct ctf_stream_class *stream_class, int *set)
+static int visit_stream_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
+ struct ctf_stream_class *stream_class, int *set)
{
- int ret = 0;
- char *left = NULL;
-
- switch (node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
- &node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class found in stream class.");
- goto error;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
- node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class alias found in stream class.");
- goto error;
- }
- break;
- case NODE_CTF_EXPRESSION:
- {
- left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "id") == 0) {
- int64_t id;
-
- if (_IS_SET(set, _STREAM_ID_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id",
- "stream declaration");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right,
- (uint64_t *) &id);
-
- /* Only read "id" if get_unary_unsigned() succeeded. */
- if (ret || (!ret && id < 0)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for stream class's `id` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (ctf_trace_class_borrow_stream_class_by_id(
- ctx->ctf_tc, id)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate stream class (same ID): id=%" PRId64,
- id);
- ret = -EEXIST;
- goto error;
- }
-
- stream_class->id = id;
- _SET(set, _STREAM_ID_SET);
- } else if (strcmp(left, "event.header") == 0) {
- if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `event.header` entry in stream class.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &stream_class->event_header_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create stream class's event header field class.");
- goto error;
- }
-
- BT_ASSERT(stream_class->event_header_fc);
- ret = auto_map_fields_to_trace_clock_class(ctx,
- stream_class->event_header_fc, "timestamp");
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
- goto error;
- }
-
- _SET(set, _STREAM_EVENT_HEADER_SET);
- } else if (strcmp(left, "event.context") == 0) {
- if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `event.context` entry in stream class.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &stream_class->event_common_context_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create stream class's event context field class.");
- goto error;
- }
-
- BT_ASSERT(stream_class->event_common_context_fc);
- _SET(set, _STREAM_EVENT_CONTEXT_SET);
- } else if (strcmp(left, "packet.context") == 0) {
- if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `packet.context` entry in stream class.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &stream_class->packet_context_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create stream class's packet context field class.");
- goto error;
- }
-
- BT_ASSERT(stream_class->packet_context_fc);
- ret = auto_map_fields_to_trace_clock_class(ctx,
- stream_class->packet_context_fc,
- "timestamp_begin");
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
- goto error;
- }
-
- ret = auto_map_fields_to_trace_clock_class(ctx,
- stream_class->packet_context_fc,
- "timestamp_end");
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
- goto error;
- }
-
- _SET(set, _STREAM_PACKET_CONTEXT_SET);
- } else {
- _BT_COMP_LOGW_NODE(node,
- "Unknown attribute in stream class: "
- "attr-name=\"%s\"", left);
- }
-
- g_free(left);
- left = NULL;
- break;
- }
-
- default:
- ret = -EPERM;
- goto error;
- }
-
- return 0;
+ int ret = 0;
+ char *left = NULL;
+
+ switch (node->type) {
+ case NODE_TYPEDEF:
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot add field class found in stream class.");
+ goto error;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot add field class alias found in stream class.");
+ goto error;
+ }
+ break;
+ case NODE_CTF_EXPRESSION:
+ {
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "id") == 0) {
+ int64_t id;
+
+ if (_IS_SET(set, _STREAM_ID_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "stream declaration");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, (uint64_t *) &id);
+
+ /* Only read "id" if get_unary_unsigned() succeeded. */
+ if (ret || (!ret && id < 0)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for stream class's `id` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, id)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Duplicate stream class (same ID): id=%" PRId64, id);
+ ret = -EEXIST;
+ goto error;
+ }
+
+ stream_class->id = id;
+ _SET(set, _STREAM_ID_SET);
+ } else if (strcmp(left, "event.header") == 0) {
+ if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Duplicate `event.header` entry in stream class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &stream_class->event_header_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Cannot create stream class's event header field class.");
+ goto error;
+ }
+
+ BT_ASSERT(stream_class->event_header_fc);
+ ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->event_header_fc,
+ "timestamp");
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
+ goto error;
+ }
+
+ _SET(set, _STREAM_EVENT_HEADER_SET);
+ } else if (strcmp(left, "event.context") == 0) {
+ if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Duplicate `event.context` entry in stream class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &stream_class->event_common_context_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Cannot create stream class's event context field class.");
+ goto error;
+ }
+
+ BT_ASSERT(stream_class->event_common_context_fc);
+ _SET(set, _STREAM_EVENT_CONTEXT_SET);
+ } else if (strcmp(left, "packet.context") == 0) {
+ if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Duplicate `packet.context` entry in stream class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &stream_class->packet_context_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Cannot create stream class's packet context field class.");
+ goto error;
+ }
+
+ BT_ASSERT(stream_class->packet_context_fc);
+ ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->packet_context_fc,
+ "timestamp_begin");
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
+ goto error;
+ }
+
+ ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->packet_context_fc,
+ "timestamp_end");
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
+ goto error;
+ }
+
+ _SET(set, _STREAM_PACKET_CONTEXT_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(node,
+ "Unknown attribute in stream class: "
+ "attr-name=\"%s\"",
+ left);
+ }
+
+ g_free(left);
+ left = NULL;
+ break;
+ }
+
+ default:
+ ret = -EPERM;
+ goto error;
+ }
+
+ return 0;
error:
- g_free(left);
- return ret;
+ g_free(left);
+ return ret;
}
-static
-int visit_stream_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
+static int visit_stream_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- int set = 0;
- int ret = 0;
- struct ctf_node *iter;
- struct ctf_stream_class *stream_class = NULL;
- struct bt_list_head *decl_list = &node->u.stream.declaration_list;
-
- if (node->visited) {
- goto end;
- }
-
- node->visited = TRUE;
- stream_class = ctf_stream_class_create();
- BT_ASSERT(stream_class);
- _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
-
- bt_list_for_each_entry(iter, decl_list, siblings) {
- ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit stream class's entry: "
- "ret=%d", ret);
- ctx_pop_scope(ctx);
- goto error;
- }
- }
-
- ctx_pop_scope(ctx);
-
- if (_IS_SET(&set, _STREAM_ID_SET)) {
- /* Check that packet header has `stream_id` field */
- struct ctf_named_field_class *named_fc = NULL;
-
- if (!ctx->ctf_tc->packet_header_fc) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Stream class has a `id` attribute, "
- "but trace has no packet header field class.");
- ret = -EINVAL;
- goto error;
- }
-
- named_fc = ctf_field_class_struct_borrow_member_by_name(
- ctf_field_class_as_struct(ctx->ctf_tc->packet_header_fc), "stream_id");
- if (!named_fc) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Stream class has a `id` attribute, "
- "but trace's packet header field class has no `stream_id` field.");
- ret = -EINVAL;
- goto error;
- }
-
- if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
- named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Stream class has a `id` attribute, "
- "but trace's packet header field class's `stream_id` field is not an integer field class.");
- ret = -EINVAL;
- goto error;
- }
- } else {
- /* Allow only _one_ ID-less stream */
- if (ctx->ctf_tc->stream_classes->len != 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
- ret = -EPERM;
- goto error;
- }
-
- /* Automatic ID: 0 */
- stream_class->id = 0;
- }
-
- /*
- * Make sure that this stream class's ID is currently unique in
- * the trace.
- */
- if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc,
- stream_class->id)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate stream class (same ID): id=%" PRId64,
- stream_class->id);
- ret = -EINVAL;
- goto error;
- }
-
- g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
- stream_class = NULL;
- goto end;
+ int set = 0;
+ int ret = 0;
+ struct ctf_node *iter;
+ struct ctf_stream_class *stream_class = NULL;
+ struct bt_list_head *decl_list = &node->u.stream.declaration_list;
+
+ if (node->visited) {
+ goto end;
+ }
+
+ node->visited = TRUE;
+ stream_class = ctf_stream_class_create();
+ BT_ASSERT(stream_class);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
+
+ bt_list_for_each_entry (iter, decl_list, siblings) {
+ ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Cannot visit stream class's entry: "
+ "ret=%d",
+ ret);
+ ctx_pop_scope(ctx);
+ goto error;
+ }
+ }
+
+ ctx_pop_scope(ctx);
+
+ if (_IS_SET(&set, _STREAM_ID_SET)) {
+ /* Check that packet header has `stream_id` field */
+ struct ctf_named_field_class *named_fc = NULL;
+
+ if (!ctx->ctf_tc->packet_header_fc) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Stream class has a `id` attribute, "
+ "but trace has no packet header field class.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ named_fc = ctf_field_class_struct_borrow_member_by_name(
+ ctf_field_class_as_struct(ctx->ctf_tc->packet_header_fc), "stream_id");
+ if (!named_fc) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Stream class has a `id` attribute, "
+ "but trace's packet header field class has no `stream_id` field.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
+ named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Stream class has a `id` attribute, "
+ "but trace's packet header field class's `stream_id` field is not an integer field class.");
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ /* Allow only _one_ ID-less stream */
+ if (ctx->ctf_tc->stream_classes->len != 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node,
+ "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ /* Automatic ID: 0 */
+ stream_class->id = 0;
+ }
+
+ /*
+ * Make sure that this stream class's ID is currently unique in
+ * the trace.
+ */
+ if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, stream_class->id)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate stream class (same ID): id=%" PRId64,
+ stream_class->id);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
+ stream_class = NULL;
+ goto end;
error:
- ctf_stream_class_destroy(stream_class);
- stream_class = NULL;
+ ctf_stream_class_destroy(stream_class);
+ stream_class = NULL;
end:
- return ret;
+ return ret;
}
-static
-int visit_trace_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
- int *set)
+static int visit_trace_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node,
+ int *set)
{
- int ret = 0;
- char *left = NULL;
- uint64_t val;
-
- switch (node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
- &node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class found in trace (`trace` block).");
- goto error;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
- node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot add field class alias found in trace (`trace` block).");
- goto error;
- }
- break;
- case NODE_CTF_EXPRESSION:
- {
- left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "major") == 0) {
- if (_IS_SET(set, _TRACE_MAJOR_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "major", "trace");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right, &val);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for trace's `major` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (val != 1) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Invalid trace's `minor` attribute: expecting 1.");
- ret = -EINVAL;
- goto error;
- }
-
- ctx->ctf_tc->major = val;
- _SET(set, _TRACE_MAJOR_SET);
- } else if (strcmp(left, "minor") == 0) {
- if (_IS_SET(set, _TRACE_MINOR_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "minor", "trace");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &node->u.ctf_expression.right, &val);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected unary expression for trace's `minor` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (val != 8) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Invalid trace's `minor` attribute: expecting 8.");
- ret = -EINVAL;
- goto error;
- }
-
- ctx->ctf_tc->minor = val;
- _SET(set, _TRACE_MINOR_SET);
- } else if (strcmp(left, "uuid") == 0) {
- if (_IS_SET(set, _TRACE_UUID_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "uuid", "trace");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_uuid(ctx,
- &node->u.ctf_expression.right,
- ctx->ctf_tc->uuid);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Invalid trace's `uuid` attribute.");
- goto error;
- }
-
- ctx->ctf_tc->is_uuid_set = true;
- _SET(set, _TRACE_UUID_SET);
- } else if (strcmp(left, "byte_order") == 0) {
- /* Default byte order is already known at this stage */
- if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order",
- "trace");
- ret = -EPERM;
- goto error;
- }
-
- BT_ASSERT(ctx->ctf_tc->default_byte_order != CTF_BYTE_ORDER_UNKNOWN);
- _SET(set, _TRACE_BYTE_ORDER_SET);
- } else if (strcmp(left, "packet.header") == 0) {
- if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate `packet.header` entry in trace.");
- ret = -EPERM;
- goto error;
- }
-
- ret = visit_field_class_specifier_list(ctx,
- _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings),
- &ctx->ctf_tc->packet_header_fc);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot create trace's packet header field class.");
- goto error;
- }
-
- BT_ASSERT(ctx->ctf_tc->packet_header_fc);
- _SET(set, _TRACE_PACKET_HEADER_SET);
- } else {
- _BT_COMP_LOGW_NODE(node,
- "Unknown attribute in stream class: "
- "attr-name=\"%s\"", left);
- }
-
- g_free(left);
- left = NULL;
- break;
- }
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unknown expression in trace.");
- ret = -EINVAL;
- goto error;
- }
-
- return 0;
+ int ret = 0;
+ char *left = NULL;
+ uint64_t val;
+
+ switch (node->type) {
+ case NODE_TYPEDEF:
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Cannot add field class found in trace (`trace` block).");
+ goto error;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Cannot add field class alias found in trace (`trace` block).");
+ goto error;
+ }
+ break;
+ case NODE_CTF_EXPRESSION:
+ {
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "major") == 0) {
+ if (_IS_SET(set, _TRACE_MAJOR_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "major", "trace");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &val);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for trace's `major` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (val != 1) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Invalid trace's `minor` attribute: expecting 1.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ctx->ctf_tc->major = val;
+ _SET(set, _TRACE_MAJOR_SET);
+ } else if (strcmp(left, "minor") == 0) {
+ if (_IS_SET(set, _TRACE_MINOR_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "minor", "trace");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &val);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Unexpected unary expression for trace's `minor` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (val != 8) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Invalid trace's `minor` attribute: expecting 8.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ctx->ctf_tc->minor = val;
+ _SET(set, _TRACE_MINOR_SET);
+ } else if (strcmp(left, "uuid") == 0) {
+ if (_IS_SET(set, _TRACE_UUID_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "uuid", "trace");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_uuid(ctx, &node->u.ctf_expression.right, ctx->ctf_tc->uuid);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid trace's `uuid` attribute.");
+ goto error;
+ }
+
+ ctx->ctf_tc->is_uuid_set = true;
+ _SET(set, _TRACE_UUID_SET);
+ } else if (strcmp(left, "byte_order") == 0) {
+ /* Default byte order is already known at this stage */
+ if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", "trace");
+ ret = -EPERM;
+ goto error;
+ }
+
+ BT_ASSERT(ctx->ctf_tc->default_byte_order != CTF_BYTE_ORDER_UNKNOWN);
+ _SET(set, _TRACE_BYTE_ORDER_SET);
+ } else if (strcmp(left, "packet.header") == 0) {
+ if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `packet.header` entry in trace.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = visit_field_class_specifier_list(
+ ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings),
+ &ctx->ctf_tc->packet_header_fc);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot create trace's packet header field class.");
+ goto error;
+ }
+
+ BT_ASSERT(ctx->ctf_tc->packet_header_fc);
+ _SET(set, _TRACE_PACKET_HEADER_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(node,
+ "Unknown attribute in stream class: "
+ "attr-name=\"%s\"",
+ left);
+ }
+
+ g_free(left);
+ left = NULL;
+ break;
+ }
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unknown expression in trace.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ return 0;
error:
- g_free(left);
- return ret;
+ g_free(left);
+ return ret;
}
-static
-int visit_trace_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
+static int visit_trace_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- int ret = 0;
- int set = 0;
- struct ctf_node *iter;
- struct bt_list_head *decl_list = &node->u.trace.declaration_list;
-
- if (node->visited) {
- goto end;
- }
-
- node->visited = TRUE;
-
- if (ctx->is_trace_visited) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block).");
- ret = -EEXIST;
- goto error;
- }
-
- _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
-
- bt_list_for_each_entry(iter, decl_list, siblings) {
- ret = visit_trace_decl_entry(ctx, iter, &set);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
- "ret=%d", ret);
- ctx_pop_scope(ctx);
- goto error;
- }
- }
-
- ctx_pop_scope(ctx);
-
- if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `major` attribute in trace (`trace` block).");
- ret = -EPERM;
- goto error;
- }
-
- if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `minor` attribute in trace (`trace` block).");
- ret = -EPERM;
- goto error;
- }
-
- if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Missing `byte_order` attribute in trace (`trace` block).");
- ret = -EPERM;
- goto error;
- }
-
- ctx->is_trace_visited = true;
+ int ret = 0;
+ int set = 0;
+ struct ctf_node *iter;
+ struct bt_list_head *decl_list = &node->u.trace.declaration_list;
+
+ if (node->visited) {
+ goto end;
+ }
+
+ node->visited = TRUE;
+
+ if (ctx->is_trace_visited) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block).");
+ ret = -EEXIST;
+ goto error;
+ }
+
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
+
+ bt_list_for_each_entry (iter, decl_list, siblings) {
+ ret = visit_trace_decl_entry(ctx, iter, &set);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Cannot visit trace's entry (`trace` block): "
+ "ret=%d",
+ ret);
+ ctx_pop_scope(ctx);
+ goto error;
+ }
+ }
+
+ ctx_pop_scope(ctx);
+
+ if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Missing `major` attribute in trace (`trace` block).");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Missing `minor` attribute in trace (`trace` block).");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Missing `byte_order` attribute in trace (`trace` block).");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ctx->is_trace_visited = true;
end:
- return 0;
+ return 0;
error:
- return ret;
+ return ret;
}
-static
-int visit_env(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
+static int visit_env(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- int ret = 0;
- char *left = NULL;
- struct ctf_node *entry_node;
- struct bt_list_head *decl_list = &node->u.env.declaration_list;
-
- if (node->visited) {
- goto end;
- }
-
- node->visited = TRUE;
-
- bt_list_for_each_entry(entry_node, decl_list, siblings) {
- struct bt_list_head *right_head =
- &entry_node->u.ctf_expression.right;
-
- if (entry_node->type != NODE_CTF_EXPRESSION) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Wrong expression in environment entry: "
- "node-type=%d", entry_node->type);
- ret = -EPERM;
- goto error;
- }
-
- left = ctf_ast_concatenate_unary_strings(
- &entry_node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot get environment entry's name.");
- ret = -EINVAL;
- goto error;
- }
-
- if (is_unary_string(right_head)) {
- char *right = ctf_ast_concatenate_unary_strings(right_head);
-
- if (!right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for environment entry's value: "
- "name=\"%s\"", left);
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "tracer_name") == 0) {
- if (strncmp(right, "lttng", 5) == 0) {
- BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
- "tracer-name=\"%s\"",
- left, right);
- ctx->is_lttng = true;
- }
- }
-
- ctf_trace_class_append_env_entry(ctx->ctf_tc,
- left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
- right, 0);
- g_free(right);
- } else if (is_unary_unsigned(right_head) ||
- is_unary_signed(right_head)) {
- int64_t v;
-
- if (is_unary_unsigned(right_head)) {
- ret = get_unary_unsigned(ctx, right_head,
- (uint64_t *) &v);
- } else {
- ret = get_unary_signed(right_head, &v);
- }
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for environment entry's value: "
- "name=\"%s\"", left);
- ret = -EINVAL;
- goto error;
- }
-
- ctf_trace_class_append_env_entry(ctx->ctf_tc,
- left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
- NULL, v);
- } else {
- _BT_COMP_LOGW_NODE(entry_node,
- "Environment entry has unknown type: "
- "name=\"%s\"", left);
- }
-
- g_free(left);
- left = NULL;
- }
+ int ret = 0;
+ char *left = NULL;
+ struct ctf_node *entry_node;
+ struct bt_list_head *decl_list = &node->u.env.declaration_list;
+
+ if (node->visited) {
+ goto end;
+ }
+
+ node->visited = TRUE;
+
+ bt_list_for_each_entry (entry_node, decl_list, siblings) {
+ struct bt_list_head *right_head = &entry_node->u.ctf_expression.right;
+
+ if (entry_node->type != NODE_CTF_EXPRESSION) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
+ "Wrong expression in environment entry: "
+ "node-type=%d",
+ entry_node->type);
+ ret = -EPERM;
+ goto error;
+ }
+
+ left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot get environment entry's name.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (is_unary_string(right_head)) {
+ char *right = ctf_ast_concatenate_unary_strings(right_head);
+
+ if (!right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node,
+ "Unexpected unary expression for environment entry's value: "
+ "name=\"%s\"",
+ left);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "tracer_name") == 0) {
+ if (strncmp(right, "lttng", 5) == 0) {
+ BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
+ "tracer-name=\"%s\"",
+ left, right);
+ ctx->is_lttng = true;
+ }
+ }
+
+ ctf_trace_class_append_env_entry(ctx->ctf_tc, left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
+ right, 0);
+ g_free(right);
+ } else if (is_unary_unsigned(right_head) || is_unary_signed(right_head)) {
+ int64_t v;
+
+ if (is_unary_unsigned(right_head)) {
+ ret = get_unary_unsigned(ctx, right_head, (uint64_t *) &v);
+ } else {
+ ret = get_unary_signed(right_head, &v);
+ }
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node,
+ "Unexpected unary expression for environment entry's value: "
+ "name=\"%s\"",
+ left);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ctf_trace_class_append_env_entry(ctx->ctf_tc, left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
+ NULL, v);
+ } else {
+ _BT_COMP_LOGW_NODE(entry_node,
+ "Environment entry has unknown type: "
+ "name=\"%s\"",
+ left);
+ }
+
+ g_free(left);
+ left = NULL;
+ }
end:
- return 0;
+ return 0;
error:
- g_free(left);
- return ret;
+ g_free(left);
+ return ret;
}
-static
-int set_trace_byte_order(struct ctf_visitor_generate_ir *ctx, struct ctf_node *trace_node)
+static int set_trace_byte_order(struct ctf_visitor_generate_ir *ctx, struct ctf_node *trace_node)
{
- int ret = 0;
- int set = 0;
- char *left = NULL;
- struct ctf_node *node;
- struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
-
- bt_list_for_each_entry(node, decl_list, siblings) {
- if (node->type == NODE_CTF_EXPRESSION) {
- struct ctf_node *right_node;
-
- left = ctf_ast_concatenate_unary_strings(
- &node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "byte_order") == 0) {
- enum ctf_byte_order bo;
-
- if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order",
- "trace");
- ret = -EPERM;
- goto error;
- }
-
- _SET(&set, _TRACE_BYTE_ORDER_SET);
- right_node = _BT_LIST_FIRST_ENTRY(
- &node->u.ctf_expression.right,
- struct ctf_node, siblings);
- bo = byte_order_from_unary_expr(ctx,
- right_node);
- if (bo == CTF_BYTE_ORDER_UNKNOWN) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Invalid `byte_order` attribute in trace (`trace` block): "
- "expecting `le`, `be`, or `network`.");
- ret = -EINVAL;
- goto error;
- } else if (bo == CTF_BYTE_ORDER_DEFAULT) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Invalid `byte_order` attribute in trace (`trace` block): "
- "cannot be set to `native` here.");
- ret = -EPERM;
- goto error;
- }
-
- ctx->ctf_tc->default_byte_order = bo;
- }
-
- g_free(left);
- left = NULL;
- }
- }
-
- if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(trace_node,
- "Missing `byte_order` attribute in trace (`trace` block).");
- ret = -EINVAL;
- goto error;
- }
-
- return 0;
+ int ret = 0;
+ int set = 0;
+ char *left = NULL;
+ struct ctf_node *node;
+ struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
+
+ bt_list_for_each_entry (node, decl_list, siblings) {
+ if (node->type == NODE_CTF_EXPRESSION) {
+ struct ctf_node *right_node;
+
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "byte_order") == 0) {
+ enum ctf_byte_order bo;
+
+ if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", "trace");
+ ret = -EPERM;
+ goto error;
+ }
+
+ _SET(&set, _TRACE_BYTE_ORDER_SET);
+ right_node =
+ _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings);
+ bo = byte_order_from_unary_expr(ctx, right_node);
+ if (bo == CTF_BYTE_ORDER_UNKNOWN) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Invalid `byte_order` attribute in trace (`trace` block): "
+ "expecting `le`, `be`, or `network`.");
+ ret = -EINVAL;
+ goto error;
+ } else if (bo == CTF_BYTE_ORDER_DEFAULT) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ node, "Invalid `byte_order` attribute in trace (`trace` block): "
+ "cannot be set to `native` here.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ctx->ctf_tc->default_byte_order = bo;
+ }
+
+ g_free(left);
+ left = NULL;
+ }
+ }
+
+ if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(trace_node,
+ "Missing `byte_order` attribute in trace (`trace` block).");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ return 0;
error:
- g_free(left);
- return ret;
+ g_free(left);
+ return ret;
}
-static
-int visit_clock_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node,
- struct ctf_clock_class *clock, int *set, int64_t *offset_seconds,
- uint64_t *offset_cycles)
+static int visit_clock_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node,
+ struct ctf_clock_class *clock, int *set, int64_t *offset_seconds,
+ uint64_t *offset_cycles)
{
- int ret = 0;
- char *left = NULL;
-
- if (entry_node->type != NODE_CTF_EXPRESSION) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected node type: node-type=%d",
- entry_node->type);
- ret = -EPERM;
- goto error;
- }
-
- left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left);
- if (!left) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot concatenate unary strings.");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcmp(left, "name") == 0) {
- char *right;
-
- if (_IS_SET(set, _CLOCK_NAME_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "name", "clock class");
- ret = -EPERM;
- goto error;
- }
-
- right = ctf_ast_concatenate_unary_strings(
- &entry_node->u.ctf_expression.right);
- if (!right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `name` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- g_string_assign(clock->name, right);
- g_free(right);
- _SET(set, _CLOCK_NAME_SET);
- } else if (strcmp(left, "uuid") == 0) {
- bt_uuid_t uuid;
-
- if (_IS_SET(set, _CLOCK_UUID_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "uuid", "clock class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_uuid(ctx, &entry_node->u.ctf_expression.right,
- uuid);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Invalid clock class's `uuid` attribute.");
- goto error;
- }
-
- clock->has_uuid = true;
- bt_uuid_copy(clock->uuid, uuid);
- _SET(set, _CLOCK_UUID_SET);
- } else if (strcmp(left, "description") == 0) {
- char *right;
-
- if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "description",
- "clock class");
- ret = -EPERM;
- goto error;
- }
-
- right = ctf_ast_concatenate_unary_strings(
- &entry_node->u.ctf_expression.right);
- if (!right) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `description` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- g_string_assign(clock->description, right);
- g_free(right);
- _SET(set, _CLOCK_DESCRIPTION_SET);
- } else if (strcmp(left, "freq") == 0) {
- uint64_t freq = UINT64_C(-1);
-
- if (_IS_SET(set, _CLOCK_FREQ_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "freq", "clock class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &entry_node->u.ctf_expression.right, &freq);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `freq` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- if (freq == UINT64_C(-1) || freq == 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Invalid clock class frequency: freq=%" PRIu64,
- freq);
- ret = -EINVAL;
- goto error;
- }
-
- clock->frequency = freq;
- _SET(set, _CLOCK_FREQ_SET);
- } else if (strcmp(left, "precision") == 0) {
- uint64_t precision;
-
- if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "precision",
- "clock class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &entry_node->u.ctf_expression.right, &precision);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `precision` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- clock->precision = precision;
- _SET(set, _CLOCK_PRECISION_SET);
- } else if (strcmp(left, "offset_s") == 0) {
- if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset_s",
- "clock class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_signed(
- &entry_node->u.ctf_expression.right, offset_seconds);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `offset_s` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- _SET(set, _CLOCK_OFFSET_S_SET);
- } else if (strcmp(left, "offset") == 0) {
- if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset", "clock class");
- ret = -EPERM;
- goto error;
- }
-
- ret = get_unary_unsigned(ctx,
- &entry_node->u.ctf_expression.right, offset_cycles);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `offset` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- _SET(set, _CLOCK_OFFSET_SET);
- } else if (strcmp(left, "absolute") == 0) {
- struct ctf_node *right;
-
- if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "absolute",
- "clock class");
- ret = -EPERM;
- goto error;
- }
-
- right = _BT_LIST_FIRST_ENTRY(
- &entry_node->u.ctf_expression.right,
- struct ctf_node, siblings);
- ret = get_boolean(ctx, right);
- if (ret < 0) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Unexpected unary expression for clock class's `absolute` attribute.");
- ret = -EINVAL;
- goto error;
- }
-
- clock->is_absolute = ret;
- _SET(set, _CLOCK_ABSOLUTE_SET);
- } else {
- _BT_COMP_LOGW_NODE(entry_node,
- "Unknown attribute in clock class: attr-name=\"%s\"",
- left);
- }
-
- g_free(left);
- left = NULL;
- return 0;
+ int ret = 0;
+ char *left = NULL;
+
+ if (entry_node->type != NODE_CTF_EXPRESSION) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d",
+ entry_node->type);
+ ret = -EPERM;
+ goto error;
+ }
+
+ left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left);
+ if (!left) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot concatenate unary strings.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (strcmp(left, "name") == 0) {
+ char *right;
+
+ if (_IS_SET(set, _CLOCK_NAME_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "name", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ right = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.right);
+ if (!right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `name` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_string_assign(clock->name, right);
+ g_free(right);
+ _SET(set, _CLOCK_NAME_SET);
+ } else if (strcmp(left, "uuid") == 0) {
+ bt_uuid_t uuid;
+
+ if (_IS_SET(set, _CLOCK_UUID_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "uuid", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_uuid(ctx, &entry_node->u.ctf_expression.right, uuid);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Invalid clock class's `uuid` attribute.");
+ goto error;
+ }
+
+ clock->has_uuid = true;
+ bt_uuid_copy(clock->uuid, uuid);
+ _SET(set, _CLOCK_UUID_SET);
+ } else if (strcmp(left, "description") == 0) {
+ char *right;
+
+ if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "description", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ right = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.right);
+ if (!right) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node,
+ "Unexpected unary expression for clock class's `description` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ g_string_assign(clock->description, right);
+ g_free(right);
+ _SET(set, _CLOCK_DESCRIPTION_SET);
+ } else if (strcmp(left, "freq") == 0) {
+ uint64_t freq = UINT64_C(-1);
+
+ if (_IS_SET(set, _CLOCK_FREQ_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "freq", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, &freq);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `freq` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (freq == UINT64_C(-1) || freq == 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
+ "Invalid clock class frequency: freq=%" PRIu64, freq);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ clock->frequency = freq;
+ _SET(set, _CLOCK_FREQ_SET);
+ } else if (strcmp(left, "precision") == 0) {
+ uint64_t precision;
+
+ if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "precision", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, &precision);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `precision` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ clock->precision = precision;
+ _SET(set, _CLOCK_PRECISION_SET);
+ } else if (strcmp(left, "offset_s") == 0) {
+ if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset_s", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_signed(&entry_node->u.ctf_expression.right, offset_seconds);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `offset_s` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(set, _CLOCK_OFFSET_S_SET);
+ } else if (strcmp(left, "offset") == 0) {
+ if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, offset_cycles);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `offset` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ _SET(set, _CLOCK_OFFSET_SET);
+ } else if (strcmp(left, "absolute") == 0) {
+ struct ctf_node *right;
+
+ if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "absolute", "clock class");
+ ret = -EPERM;
+ goto error;
+ }
+
+ right =
+ _BT_LIST_FIRST_ENTRY(&entry_node->u.ctf_expression.right, struct ctf_node, siblings);
+ ret = get_boolean(ctx, right);
+ if (ret < 0) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ entry_node, "Unexpected unary expression for clock class's `absolute` attribute.");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ clock->is_absolute = ret;
+ _SET(set, _CLOCK_ABSOLUTE_SET);
+ } else {
+ _BT_COMP_LOGW_NODE(entry_node, "Unknown attribute in clock class: attr-name=\"%s\"", left);
+ }
+
+ g_free(left);
+ left = NULL;
+ return 0;
error:
- g_free(left);
- return ret;
+ g_free(left);
+ return ret;
}
-static inline
-uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns)
+static inline uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns)
{
- uint64_t cycles;
+ uint64_t cycles;
- /* 1GHz */
- if (frequency == UINT64_C(1000000000)) {
- cycles = ns;
- } else {
- cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
- }
+ /* 1GHz */
+ if (frequency == UINT64_C(1000000000)) {
+ cycles = ns;
+ } else {
+ cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
+ }
- return cycles;
+ return cycles;
}
-static
-void calibrate_clock_class_offsets(int64_t *offset_seconds,
- uint64_t *offset_cycles, uint64_t freq)
+static void calibrate_clock_class_offsets(int64_t *offset_seconds, uint64_t *offset_cycles,
+ uint64_t freq)
{
- if (*offset_cycles >= freq) {
- const uint64_t s_in_offset_cycles = *offset_cycles / freq;
+ if (*offset_cycles >= freq) {
+ const uint64_t s_in_offset_cycles = *offset_cycles / freq;
- *offset_seconds += (int64_t) s_in_offset_cycles;
- *offset_cycles -= (s_in_offset_cycles * freq);
- }
+ *offset_seconds += (int64_t) s_in_offset_cycles;
+ *offset_cycles -= (s_in_offset_cycles * freq);
+ }
}
-static
-void apply_clock_class_is_absolute(struct ctf_visitor_generate_ir *ctx,
- struct ctf_clock_class *clock)
+static void apply_clock_class_is_absolute(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_clock_class *clock)
{
- if (ctx->decoder_config.force_clock_class_origin_unix_epoch) {
- clock->is_absolute = true;
- }
+ if (ctx->decoder_config.force_clock_class_origin_unix_epoch) {
+ clock->is_absolute = true;
+ }
- return;
+ return;
}
-static
-void apply_clock_class_offset(struct ctf_visitor_generate_ir *ctx,
- struct ctf_clock_class *clock)
+static void apply_clock_class_offset(struct ctf_visitor_generate_ir *ctx,
+ struct ctf_clock_class *clock)
{
- uint64_t freq;
- int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s;
- uint64_t offset_ns_to_apply;
- int64_t cur_offset_s;
- uint64_t cur_offset_cycles;
-
- if (ctx->decoder_config.clock_class_offset_s == 0 &&
- ctx->decoder_config.clock_class_offset_ns == 0) {
- goto end;
- }
-
- /* Transfer nanoseconds to seconds as much as possible */
- if (ctx->decoder_config.clock_class_offset_ns < 0) {
- const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns;
- const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1;
- const int64_t extra_s = -abs_extra_s;
- const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
- (extra_s * INT64_C(1000000000));
-
- BT_ASSERT(offset_ns > 0);
- offset_ns_to_apply = (uint64_t) offset_ns;
- offset_s_to_apply += extra_s;
- } else {
- const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns /
- INT64_C(1000000000);
- const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
- (extra_s * INT64_C(1000000000));
-
- BT_ASSERT(offset_ns >= 0);
- offset_ns_to_apply = (uint64_t) offset_ns;
- offset_s_to_apply += extra_s;
- }
-
- freq = clock->frequency;
- cur_offset_s = clock->offset_seconds;
- cur_offset_cycles = clock->offset_cycles;
-
- /* Apply offsets */
- cur_offset_s += offset_s_to_apply;
- cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply);
-
- /*
- * Recalibrate offsets because the part in cycles can be greater
- * than the frequency at this point.
- */
- calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq);
-
- /* Set final offsets */
- clock->offset_seconds = cur_offset_s;
- clock->offset_cycles = cur_offset_cycles;
+ uint64_t freq;
+ int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s;
+ uint64_t offset_ns_to_apply;
+ int64_t cur_offset_s;
+ uint64_t cur_offset_cycles;
+
+ if (ctx->decoder_config.clock_class_offset_s == 0 &&
+ ctx->decoder_config.clock_class_offset_ns == 0) {
+ goto end;
+ }
+
+ /* Transfer nanoseconds to seconds as much as possible */
+ if (ctx->decoder_config.clock_class_offset_ns < 0) {
+ const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns;
+ const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1;
+ const int64_t extra_s = -abs_extra_s;
+ const int64_t offset_ns =
+ ctx->decoder_config.clock_class_offset_ns - (extra_s * INT64_C(1000000000));
+
+ BT_ASSERT(offset_ns > 0);
+ offset_ns_to_apply = (uint64_t) offset_ns;
+ offset_s_to_apply += extra_s;
+ } else {
+ const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns / INT64_C(1000000000);
+ const int64_t offset_ns =
+ ctx->decoder_config.clock_class_offset_ns - (extra_s * INT64_C(1000000000));
+
+ BT_ASSERT(offset_ns >= 0);
+ offset_ns_to_apply = (uint64_t) offset_ns;
+ offset_s_to_apply += extra_s;
+ }
+
+ freq = clock->frequency;
+ cur_offset_s = clock->offset_seconds;
+ cur_offset_cycles = clock->offset_cycles;
+
+ /* Apply offsets */
+ cur_offset_s += offset_s_to_apply;
+ cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply);
+
+ /*
+ * Recalibrate offsets because the part in cycles can be greater
+ * than the frequency at this point.
+ */
+ calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq);
+
+ /* Set final offsets */
+ clock->offset_seconds = cur_offset_s;
+ clock->offset_cycles = cur_offset_cycles;
end:
- return;
+ return;
}
-static
-int visit_clock_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *clock_node)
+static int visit_clock_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *clock_node)
{
- int ret = 0;
- int set = 0;
- struct ctf_clock_class *clock;
- struct ctf_node *entry_node;
- struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
- const char *clock_class_name;
- int64_t offset_seconds = 0;
- uint64_t offset_cycles = 0;
- uint64_t freq;
-
- if (clock_node->visited) {
- return 0;
- }
-
- clock_node->visited = TRUE;
-
- /* CTF 1.8's default frequency for a clock class is 1 GHz */
- clock = ctf_clock_class_create();
- if (!clock) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node,
- "Cannot create default clock class.");
- ret = -ENOMEM;
- goto end;
- }
-
- bt_list_for_each_entry(entry_node, decl_list, siblings) {
- ret = visit_clock_decl_entry(ctx, entry_node, clock, &set,
- &offset_seconds, &offset_cycles);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node,
- "Cannot visit clock class's entry: ret=%d",
- ret);
- goto end;
- }
- }
-
- if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node,
- "Missing `name` attribute in clock class.");
- ret = -EPERM;
- goto end;
- }
-
- clock_class_name = clock->name->str;
- BT_ASSERT(clock_class_name);
- if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
- /*
- * Old versions of LTTng forgot to set its clock class
- * as absolute, even if it is. This is important because
- * it's a condition to be able to sort messages
- * from different sources.
- */
- clock->is_absolute = true;
- }
-
- /*
- * Adjust offsets so that the part in cycles is less than the
- * frequency (move to the part in seconds).
- */
- freq = clock->frequency;
- calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq);
- BT_ASSERT(offset_cycles < clock->frequency);
- clock->offset_seconds = offset_seconds;
- clock->offset_cycles = offset_cycles;
- apply_clock_class_offset(ctx, clock);
- apply_clock_class_is_absolute(ctx, clock);
- g_ptr_array_add(ctx->ctf_tc->clock_classes, clock);
- clock = NULL;
+ int ret = 0;
+ int set = 0;
+ struct ctf_clock_class *clock;
+ struct ctf_node *entry_node;
+ struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
+ const char *clock_class_name;
+ int64_t offset_seconds = 0;
+ uint64_t offset_cycles = 0;
+ uint64_t freq;
+
+ if (clock_node->visited) {
+ return 0;
+ }
+
+ clock_node->visited = TRUE;
+
+ /* CTF 1.8's default frequency for a clock class is 1 GHz */
+ clock = ctf_clock_class_create();
+ if (!clock) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, "Cannot create default clock class.");
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ bt_list_for_each_entry (entry_node, decl_list, siblings) {
+ ret = visit_clock_decl_entry(ctx, entry_node, clock, &set, &offset_seconds, &offset_cycles);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot visit clock class's entry: ret=%d",
+ ret);
+ goto end;
+ }
+ }
+
+ if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, "Missing `name` attribute in clock class.");
+ ret = -EPERM;
+ goto end;
+ }
+
+ clock_class_name = clock->name->str;
+ BT_ASSERT(clock_class_name);
+ if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
+ /*
+ * Old versions of LTTng forgot to set its clock class
+ * as absolute, even if it is. This is important because
+ * it's a condition to be able to sort messages
+ * from different sources.
+ */
+ clock->is_absolute = true;
+ }
+
+ /*
+ * Adjust offsets so that the part in cycles is less than the
+ * frequency (move to the part in seconds).
+ */
+ freq = clock->frequency;
+ calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq);
+ BT_ASSERT(offset_cycles < clock->frequency);
+ clock->offset_seconds = offset_seconds;
+ clock->offset_cycles = offset_cycles;
+ apply_clock_class_offset(ctx, clock);
+ apply_clock_class_is_absolute(ctx, clock);
+ g_ptr_array_add(ctx->ctf_tc->clock_classes, clock);
+ clock = NULL;
end:
- if (clock) {
- ctf_clock_class_destroy(clock);
- }
+ if (clock) {
+ ctf_clock_class_destroy(clock);
+ }
- return ret;
+ return ret;
}
-static
-int visit_root_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *root_decl_node)
+static int visit_root_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *root_decl_node)
{
- int ret = 0;
-
- if (root_decl_node->visited) {
- goto end;
- }
-
- root_decl_node->visited = TRUE;
-
- switch (root_decl_node->type) {
- case NODE_TYPEDEF:
- ret = visit_field_class_def(ctx,
- root_decl_node->u.field_class_def.field_class_specifier_list,
- &root_decl_node->u.field_class_def.field_class_declarators);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
- "Cannot add field class found in root scope.");
- goto end;
- }
- break;
- case NODE_TYPEALIAS:
- ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target,
- root_decl_node->u.field_class_alias.alias);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
- "Cannot add field class alias found in root scope.");
- goto end;
- }
- break;
- case NODE_TYPE_SPECIFIER_LIST:
- {
- struct ctf_field_class *decl = NULL;
-
- /*
- * Just add the field class specifier to the root
- * declaration scope. Put local reference.
- */
- ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
- "Cannot visit root scope's field class: "
- "ret=%d", ret);
- BT_ASSERT(!decl);
- goto end;
- }
-
- ctf_field_class_destroy(decl);
- decl = NULL;
- break;
- }
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
- "Unexpected node type: node-type=%d",
- root_decl_node->type);
- ret = -EPERM;
- goto end;
- }
+ int ret = 0;
+
+ if (root_decl_node->visited) {
+ goto end;
+ }
+
+ root_decl_node->visited = TRUE;
+
+ switch (root_decl_node->type) {
+ case NODE_TYPEDEF:
+ ret =
+ visit_field_class_def(ctx, root_decl_node->u.field_class_def.field_class_specifier_list,
+ &root_decl_node->u.field_class_def.field_class_declarators);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
+ "Cannot add field class found in root scope.");
+ goto end;
+ }
+ break;
+ case NODE_TYPEALIAS:
+ ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target,
+ root_decl_node->u.field_class_alias.alias);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
+ "Cannot add field class alias found in root scope.");
+ goto end;
+ }
+ break;
+ case NODE_TYPE_SPECIFIER_LIST:
+ {
+ struct ctf_field_class *decl = NULL;
+
+ /*
+ * Just add the field class specifier to the root
+ * declaration scope. Put local reference.
+ */
+ ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node,
+ "Cannot visit root scope's field class: "
+ "ret=%d",
+ ret);
+ BT_ASSERT(!decl);
+ goto end;
+ }
+
+ ctf_field_class_destroy(decl);
+ decl = NULL;
+ break;
+ }
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, "Unexpected node type: node-type=%d",
+ root_decl_node->type);
+ ret = -EPERM;
+ goto end;
+ }
end:
- return ret;
+ return ret;
}
BT_HIDDEN
-struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
- const struct ctf_metadata_decoder_config *decoder_config)
+struct ctf_visitor_generate_ir *
+ctf_visitor_generate_ir_create(const struct ctf_metadata_decoder_config *decoder_config)
{
- struct ctf_visitor_generate_ir *ctx = NULL;
+ struct ctf_visitor_generate_ir *ctx = NULL;
- /* Create visitor's context */
- ctx = ctx_create(decoder_config);
- if (!ctx) {
- BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level,
- decoder_config->self_comp,
- "Cannot create visitor's context.");
- goto error;
- }
+ /* Create visitor's context */
+ ctx = ctx_create(decoder_config);
+ if (!ctx) {
+ BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, decoder_config->self_comp,
+ "Cannot create visitor's context.");
+ goto error;
+ }
- goto end;
+ goto end;
error:
- ctx_destroy(ctx);
- ctx = NULL;
+ ctx_destroy(ctx);
+ ctx = NULL;
end:
- return ctx;
+ return ctx;
}
BT_HIDDEN
void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
{
- ctx_destroy(visitor);
+ ctx_destroy(visitor);
}
BT_HIDDEN
-bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(
- struct ctf_visitor_generate_ir *ctx)
+bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(struct ctf_visitor_generate_ir *ctx)
{
- BT_ASSERT_DBG(ctx);
+ BT_ASSERT_DBG(ctx);
- if (ctx->trace_class) {
- bt_trace_class_get_ref(ctx->trace_class);
- }
+ if (ctx->trace_class) {
+ bt_trace_class_get_ref(ctx->trace_class);
+ }
- return ctx->trace_class;
+ return ctx->trace_class;
}
BT_HIDDEN
-struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class(
- struct ctf_visitor_generate_ir *ctx)
+struct ctf_trace_class *
+ctf_visitor_generate_ir_borrow_ctf_trace_class(struct ctf_visitor_generate_ir *ctx)
{
- BT_ASSERT_DBG(ctx);
- BT_ASSERT_DBG(ctx->ctf_tc);
- return ctx->ctf_tc;
+ BT_ASSERT_DBG(ctx);
+ BT_ASSERT_DBG(ctx->ctf_tc);
+ return ctx->ctf_tc;
}
BT_HIDDEN
-int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *ctx,
- struct ctf_node *node)
+int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node)
{
- int ret = 0;
-
- BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
-
- switch (node->type) {
- case NODE_ROOT:
- {
- struct ctf_node *iter;
- bool got_trace_decl = false;
-
- /*
- * The first thing we need is the native byte order of
- * the trace block, because early class aliases can have
- * a `byte_order` attribute set to `native`. If we don't
- * have the native byte order yet, and we don't have any
- * trace block yet, then fail with EINCOMPLETE.
- */
- if (ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_UNKNOWN) {
- bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
- if (got_trace_decl) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Duplicate trace (`trace` block).");
- ret = -1;
- goto end;
- }
-
- ret = set_trace_byte_order(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Cannot set trace's native byte order: "
- "ret=%d", ret);
- goto end;
- }
-
- got_trace_decl = true;
- }
-
- if (!got_trace_decl) {
- BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
- ret = -EINCOMPLETE;
- goto end;
- }
- }
-
- BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE ||
- ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG);
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /* Environment */
- bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
- ret = visit_env(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit trace's environment (`env` block) entry: "
- "ret=%d", ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /*
- * Visit clock blocks.
- */
- bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
- ret = visit_clock_decl(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit clock class: ret=%d",
- ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /*
- * Visit root declarations next, as they can be used by any
- * following entity.
- */
- bt_list_for_each_entry(iter, &node->u.root.declaration_list,
- siblings) {
- ret = visit_root_decl(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit root entry: ret=%d",
- ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /* Callsite blocks are not supported */
- bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
- _BT_COMP_LOGW_NODE(iter,
- "\"callsite\" blocks are not supported as of this version.");
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /* Trace */
- bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
- ret = visit_trace_decl(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit trace (`trace` block): "
- "ret=%d", ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /* Streams */
- bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
- ret = visit_stream_decl(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit stream class: ret=%d",
- ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
-
- /* Events */
- bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
- ret = visit_event_decl(ctx, iter);
- if (ret) {
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
- "Cannot visit event class: ret=%d",
- ret);
- goto end;
- }
- }
-
- BT_ASSERT(ctx->current_scope &&
- !ctx->current_scope->parent_scope);
- break;
- }
- default:
- _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
- "Unexpected node type: node-type=%d",
- node->type);
- ret = -EINVAL;
- goto end;
- }
-
- /* Update default clock classes */
- ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc,
- &ctx->log_cfg);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Update trace class meanings */
- ret = ctf_trace_class_update_meanings(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Update stream class configuration */
- ret = ctf_trace_class_update_stream_class_config(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Update text arrays and sequences */
- ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Update structure/array/sequence alignments */
- ret = ctf_trace_class_update_alignments(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Resolve sequence lengths and variant tags */
- ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc, &ctx->log_cfg);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- if (ctx->trace_class) {
- /*
- * Update "in IR" for field classes.
- *
- * If we have no IR trace class, then we'll have no way
- * to create IR fields anyway, so we leave all the
- * `in_ir` members false.
- */
- ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
- }
-
- /* Update saved value indexes */
- ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /* Validate what we have so far */
- ret = ctf_trace_class_validate(ctx->ctf_tc, &ctx->log_cfg);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
-
- /*
- * If there are fields which are not related to the CTF format
- * itself in the packet header and in event header field
- * classes, warn about it because they are never translated.
- */
- ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc,
- &ctx->log_cfg);
-
- if (ctx->trace_class) {
- /* Copy new CTF metadata -> new IR metadata */
- ret = ctf_trace_class_translate(ctx->log_cfg.self_comp,
- ctx->trace_class, ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
- }
- }
+ int ret = 0;
+
+ BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
+
+ switch (node->type) {
+ case NODE_ROOT:
+ {
+ struct ctf_node *iter;
+ bool got_trace_decl = false;
+
+ /*
+ * The first thing we need is the native byte order of
+ * the trace block, because early class aliases can have
+ * a `byte_order` attribute set to `native`. If we don't
+ * have the native byte order yet, and we don't have any
+ * trace block yet, then fail with EINCOMPLETE.
+ */
+ if (ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_UNKNOWN) {
+ bt_list_for_each_entry (iter, &node->u.root.trace, siblings) {
+ if (got_trace_decl) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block).");
+ ret = -1;
+ goto end;
+ }
+
+ ret = set_trace_byte_order(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node,
+ "Cannot set trace's native byte order: "
+ "ret=%d",
+ ret);
+ goto end;
+ }
+
+ got_trace_decl = true;
+ }
+
+ if (!got_trace_decl) {
+ BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
+ ret = -EINCOMPLETE;
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE ||
+ ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG);
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /* Environment */
+ bt_list_for_each_entry (iter, &node->u.root.env, siblings) {
+ ret = visit_env(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(
+ iter,
+ "Cannot visit trace's environment (`env` block) entry: "
+ "ret=%d",
+ ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /*
+ * Visit clock blocks.
+ */
+ bt_list_for_each_entry (iter, &node->u.root.clock, siblings) {
+ ret = visit_clock_decl(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit clock class: ret=%d", ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /*
+ * Visit root declarations next, as they can be used by any
+ * following entity.
+ */
+ bt_list_for_each_entry (iter, &node->u.root.declaration_list, siblings) {
+ ret = visit_root_decl(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit root entry: ret=%d", ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /* Callsite blocks are not supported */
+ bt_list_for_each_entry (iter, &node->u.root.callsite, siblings) {
+ _BT_COMP_LOGW_NODE(iter, "\"callsite\" blocks are not supported as of this version.");
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /* Trace */
+ bt_list_for_each_entry (iter, &node->u.root.trace, siblings) {
+ ret = visit_trace_decl(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter,
+ "Cannot visit trace (`trace` block): "
+ "ret=%d",
+ ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /* Streams */
+ bt_list_for_each_entry (iter, &node->u.root.stream, siblings) {
+ ret = visit_stream_decl(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit stream class: ret=%d", ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+
+ /* Events */
+ bt_list_for_each_entry (iter, &node->u.root.event, siblings) {
+ ret = visit_event_decl(ctx, iter);
+ if (ret) {
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit event class: ret=%d", ret);
+ goto end;
+ }
+ }
+
+ BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope);
+ break;
+ }
+ default:
+ _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected node type: node-type=%d", node->type);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update default clock classes */
+ ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc, &ctx->log_cfg);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update trace class meanings */
+ ret = ctf_trace_class_update_meanings(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update stream class configuration */
+ ret = ctf_trace_class_update_stream_class_config(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update text arrays and sequences */
+ ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update structure/array/sequence alignments */
+ ret = ctf_trace_class_update_alignments(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Resolve sequence lengths and variant tags */
+ ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc, &ctx->log_cfg);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (ctx->trace_class) {
+ /*
+ * Update "in IR" for field classes.
+ *
+ * If we have no IR trace class, then we'll have no way
+ * to create IR fields anyway, so we leave all the
+ * `in_ir` members false.
+ */
+ ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+ }
+
+ /* Update saved value indexes */
+ ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Validate what we have so far */
+ ret = ctf_trace_class_validate(ctx->ctf_tc, &ctx->log_cfg);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /*
+ * If there are fields which are not related to the CTF format
+ * itself in the packet header and in event header field
+ * classes, warn about it because they are never translated.
+ */
+ ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc, &ctx->log_cfg);
+
+ if (ctx->trace_class) {
+ /* Copy new CTF metadata -> new IR metadata */
+ ret = ctf_trace_class_translate(ctx->log_cfg.self_comp, ctx->trace_class, ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+ }
end:
- return ret;
+ return ret;
}