X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Fctf%2Fmetadata%2Fctf-visitor-generate-io-struct.c;h=43763aab919131556d366c8bea8bcd3c78844093;hp=bd0a845f8fd1327ea2c00062e2259a109b5510fe;hb=e397791fdf2c953f923d910774d3a97d279074c2;hpb=ab4cf05887a402e53396db43b5958918d0d2d022 diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index bd0a845f..43763aab 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -258,7 +258,8 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth, GQuark *field_name, struct ctf_node *node_type_declarator, struct declaration_scope *declaration_scope, - struct declaration *nested_declaration) + struct declaration *nested_declaration, + struct ctf_trace *trace) { /* * Visit type declarator by first taking care of sequence/array @@ -266,16 +267,18 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth, * of pointers. */ - assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN); + if (node_type_declarator) { + assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN); - /* TODO: gcc bitfields not supported yet. */ - if (node_type_declarator->u.type_declarator.bitfield_len != NULL) { - fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__); - return NULL; + /* TODO: gcc bitfields not supported yet. */ + if (node_type_declarator->u.type_declarator.bitfield_len != NULL) { + fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__); + return NULL; + } } if (!nested_declaration) { - if (!cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) { + if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) { GQuark alias_q; /* @@ -290,10 +293,14 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth, return NULL; } } else { - nested_declaration = /* parse declaration_specifier */; + nested_declaration = ctf_declaration_specifier_visit(fd, depth, + declaration_specifier, declaration_scope, trace); } } + if (!node_type_declarator) + return nested_declaration; + if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) { if (node_type_declarator->u.type_declarator.u.id) *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id); @@ -311,15 +318,39 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth, if (length) { switch (length->type) { case NODE_UNARY_EXPRESSION: - /* Array */ - /* TODO */ - ............. - declaration = /* create array */; + { + struct declaration_array *array_declaration; + size_t len; + + if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + fprintf(stderr, "[error] %s: array: unexpected unary expression.\n", __func__); + return NULL; + } + len = length->u.unary_expression.u.unsigned_constant; + array_declaration = array_declaration_new(len, nested_declaration, + declaration_scope); + declaration = &array_declaration->p; break; + } + case NODE_INTEGER: case NODE_TYPE_SPECIFIER: - /* Sequence */ - declaration = /* create sequence */; + { + struct declaration_sequence *sequence_declaration; + struct declaration_integer *integer_declaration; + GQuark dummy_id; + + declaration = ctf_type_declarator_visit(fd, depth, + length, + &dummy_id, NULL, + declaration_scope, + NULL, trace); + assert(declaration->id == CTF_TYPE_INTEGER); + integer_declaration = container_of(declaration, struct declaration_integer, p); + declaration_sequence = sequence_declaration_new(integer_declaration, + nested_declaration, declaration_scope); + declaration = &declaration_sequence->p; break; + } default: assert(0); } @@ -329,7 +360,7 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth, declaration = ctf_type_declarator_visit(fd, depth, declaration_specifier, field_name, node_type_declarator->u.type_declarator.u.nested.type_declarator, - declaration_scope, declaration); + declaration_scope, declaration, trace); return declaration; } } @@ -339,7 +370,8 @@ int ctf_struct_type_declarators_visit(int fd, int depth, struct declaration_struct *struct_declaration, struct cds_list_head *declaration_specifier, struct cds_list_head *type_declarators, - struct declaration_scope *declaration_scope) + struct declaration_scope *declaration_scope, + struct ctf_trace *trace) { struct ctf_node *iter; GQuark field_name; @@ -351,7 +383,7 @@ int ctf_struct_type_declarators_visit(int fd, int depth, declaration_specifier, &field_name, iter, struct_declaration->scope, - NULL); + NULL, trace); struct_declaration_add_field(struct_declaration, g_quark_to_string(field_name), field_declaration); @@ -364,7 +396,8 @@ int ctf_variant_type_declarators_visit(int fd, int depth, struct declaration_variant *variant_declaration, struct cds_list_head *declaration_specifier, struct cds_list_head *type_declarators, - struct declaration_scope *declaration_scope) + struct declaration_scope *declaration_scope, + struct ctf_trace *trace) { struct ctf_node *iter; GQuark field_name; @@ -376,7 +409,7 @@ int ctf_variant_type_declarators_visit(int fd, int depth, declaration_specifier, &field_name, iter, variant_declaration->scope, - NULL); + NULL, trace); variant_declaration_add_field(variant_declaration, g_quark_to_string(field_name), field_declaration); @@ -387,7 +420,8 @@ int ctf_variant_type_declarators_visit(int fd, int depth, static int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope, struct cds_list_head *declaration_specifier, - struct cds_list_head *type_declarators) + struct cds_list_head *type_declarators, + struct ctf_trace *trace) { struct ctf_node *iter; GQuark identifier; @@ -399,7 +433,7 @@ int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope, type_declaration = ctf_type_declarator_visit(fd, depth, declaration_specifier, &identifier, iter, - scope, NULL); + scope, NULL, trace); ret = register_declaration(identifier, type_declaration, scope); if (ret) { type_declaration->declaration_free(type_declaration); @@ -411,7 +445,8 @@ int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope, static int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope, - struct ctf_node *target, struct ctf_node *alias) + struct ctf_node *target, struct ctf_node *alias, + struct ctf_trace *trace) { struct declaration *type_declaration; struct ctf_node *iter, *node; @@ -427,7 +462,7 @@ int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope, type_declaration = ctf_type_declarator_visit(fd, depth, &target->u.typealias_target.declaration_specifier, &dummy_id, &target->u.typealias_target.type_declarators, - scope, NULL); + scope, NULL, trace); if (!type_declaration) { fprintf(stderr, "[error] %s: problem creating type declaration\n", __func__); err = -EINVAL; @@ -462,7 +497,8 @@ error: static int ctf_struct_declaration_list_visit(int fd, int depth, - struct ctf_node *iter, struct declaration_struct *struct_declaration) + struct ctf_node *iter, struct declaration_struct *struct_declaration, + struct ctf_trace *trace) { struct declaration *declaration; int ret; @@ -473,7 +509,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth, ret = ctf_typedef_visit(fd, depth, struct_declaration->scope, &iter->u._typedef.declaration_specifier, - &iter->u._typedef.type_declarators); + &iter->u._typedef.type_declarators, trace); if (ret) return ret; break; @@ -482,7 +518,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth, ret = ctf_typealias_visit(fd, depth, struct_declaration->scope, iter->u.typealias.target, - iter->u.typealias.alias); + iter->u.typealias.alias, trace); if (ret) return ret; break; @@ -491,7 +527,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth, ret = ctf_struct_type_declarators_visit(fd, depth, struct_declaration, &iter->u.struct_or_variant_declaration.declaration_specifier, - &iter->u.struct_or_variant_declaration.type_declarators); + &iter->u.struct_or_variant_declaration.type_declarators, trace); if (ret) return ret; break; @@ -504,7 +540,8 @@ int ctf_struct_declaration_list_visit(int fd, int depth, static int ctf_variant_declaration_list_visit(int fd, int depth, - struct ctf_node *iter, struct declaration_variant *variant_declaration) + struct ctf_node *iter, struct declaration_variant *variant_declaration, + struct ctf_trace *trace) { struct declaration *declaration; int ret; @@ -515,7 +552,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth, ret = ctf_typedef_visit(fd, depth, variant_declaration->scope, &iter->u._typedef.declaration_specifier, - &iter->u._typedef.type_declarators); + &iter->u._typedef.type_declarators, trace); if (ret) return ret; break; @@ -524,7 +561,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth, ret = ctf_typealias_visit(fd, depth, variant_declaration->scope, iter->u.typealias.target, - iter->u.typealias.alias); + iter->u.typealias.alias, trace); if (ret) return ret; break; @@ -533,7 +570,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth, ret = ctf_variant_type_declarators_visit(fd, depth, variant_declaration, &iter->u.struct_or_variant_declaration.declaration_specifier, - &iter->u.struct_or_variant_declaration.type_declarators); + &iter->u.struct_or_variant_declaration.type_declarators, trace); if (ret) return ret; break; @@ -547,7 +584,8 @@ int ctf_variant_declaration_list_visit(int fd, int depth, static struct declaration_struct *ctf_declaration_struct_visit(FILE *fd, int depth, const char *name, struct cds_list_head *declaration_list, - int has_body, struct declaration_scope *declaration_scope) + int has_body, struct declaration_scope *declaration_scope, + struct ctf_trace *trace) { struct declaration *declaration; struct declaration_struct *struct_declaration; @@ -577,7 +615,8 @@ struct declaration_struct *ctf_declaration_struct_visit(FILE *fd, } struct_declaration = struct_declaration_new(name, declaration_scope); cds_list_for_each_entry(iter, declaration_list, siblings) { - ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, struct_declaration); + ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, + struct_declaration, trace); if (ret) goto error; } @@ -597,7 +636,8 @@ error: static struct declaration_variant *ctf_declaration_variant_visit(FILE *fd, int depth, const char *name, struct cds_list_head *declaration_list, - int has_body, struct declaration_scope *declaration_scope) + int has_body, struct declaration_scope *declaration_scope, + struct ctf_trace *trace) { struct declaration *declaration; struct declaration_variant *variant_declaration; @@ -627,7 +667,8 @@ struct declaration_variant *ctf_declaration_variant_visit(FILE *fd, } variant_declaration = variant_declaration_new(name, declaration_scope); cds_list_for_each_entry(iter, declaration_list, siblings) { - ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter, variant_declaration); + ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter, + variant_declaration, trace); if (ret) goto error; } @@ -649,22 +690,98 @@ int ctf_enumerator_list_visit(int fd, int depth, struct ctf_node *enumerator, struct declaration_enum *enum_declaration) { - /* TODO */ -........ + GQuark q; + struct ctf_node *iter; + + q = g_quark_from_string(enumerator->u.enumerator.id); + if (enum_declaration->integer->signedness) { + int64_t start, end; + int nr_vals = 0; + + cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) { + int64_t *target; + + assert(iter->type == NODE_UNARY_EXPRESSION); + if (nr_vals == 0) + target = &start; + else + target = &end; + + switch (iter->u.unary_expression.type) { + case UNARY_SIGNED_CONSTANT: + *target = iter->u.unary_expression.u.signed_constant; + break; + case UNARY_UNSIGNED_CONSTANT: + *target = iter->u.unary_expression.u.unsigned_constant; + break; + default: + fprintf(stderr, "[error] %s: invalid enumerator\n", __func__); + return -EINVAL; + } + if (nr_vals > 1) { + fprintf(stderr, "[error] %s: invalid enumerator\n", __func__); + return -EINVAL; + } + nr_vals++; + } + if (nr_vals == 1) + end = start; + enum_signed_insert(enum_declaration, start, end, q); + } else + uint64_t start, end; + int nr_vals = 0; + + cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) { + int64_t *target; + + assert(iter->type == NODE_UNARY_EXPRESSION); + if (nr_vals == 0) + target = &start; + else + target = &end; + + switch (iter->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + *target = iter->u.unary_expression.u.unsigned_constant; + break; + case UNARY_SIGNED_CONSTANT: + /* + * We don't accept signed constants for enums with unsigned + * container type. + */ + fprintf(stderr, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__); + return -EINVAL; + default: + fprintf(stderr, "[error] %s: invalid enumerator\n", __func__); + return -EINVAL; + } + if (nr_vals > 1) { + fprintf(stderr, "[error] %s: invalid enumerator\n", __func__); + return -EINVAL; + } + nr_vals++; + } + if (nr_vals == 1) + end = start; + enum_unsigned_insert(enum_declaration, start, end, q); + } return 0; } static struct declaration *ctf_declaration_enum_visit(int fd, int depth, const char *name, - struct ctf_node *container_type, + struct cds_list_head *container_type, struct cds_list_head *enumerator_list, - int has_body) + int has_body, + struct declaration_scope *declaration_scope, + struct ctf_trace *trace) { struct declaration *declaration; struct declaration_enum *enum_declaration; struct declaration_integer *integer_declaration; - struct ctf_node *iter; + struct ctf_node *iter, *first; + GQuark dummy_id; /* * For named enum (without body), lookup in @@ -688,10 +805,27 @@ struct declaration *ctf_declaration_enum_visit(int fd, int depth, return NULL; } } - - /* TODO CHECK Enumerations need to have their size/type specifier (< >). */ - integer_declaration = integer_declaration_new(); /* TODO ... */ - ..... + if (cds_list_empty(container_type)) { + fprintf(stderr, "[error] %s: missing container type for enumeration\n", __func__, name); + return NULL; + + } + first = _cds_list_first_entry(container_type, struct node, siblings); + switch (first->type) { + case NODE_INTEGER: + case NODE_TYPE_SPECIFIER: + declaration = ctf_type_declarator_visit(fd, depth, + container_type, + &dummy_id, NULL, + declaration_scope, + NULL, trace); + assert(declaration->id == CTF_TYPE_INTEGER); + integer_declaration = container_of(declaration, struct declaration_integer, p); + break; + } + default: + assert(0); + } enum_declaration = enum_declaration_new(name, integer_declaration); declaration_unref(&integer_declaration->p); /* leave ref to enum */ cds_list_for_each_entry(iter, enumerator_list, siblings) { @@ -1009,9 +1143,10 @@ struct declaration *ctf_declaration_specifier_visit(FILE *fd, case NODE_ENUM: return ctf_declaration_enum_visit(fd, depth, first->u._enum.enum_id, - first->u._enum.container_type, + &first->u._enum.container_type, &first->u._enum.enumerator_list, first->u._enum.has_body, + declaration_scope, trace); case NODE_INTEGER: return ctf_declaration_integer_visit(fd, depth,