summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndreas Fried <andreas.fried@kit.edu>2019-07-29 22:24:08 +0200
committerAndreas Fried <andreas.fried@kit.edu>2019-07-29 22:35:49 +0200
commit83e7ce225c500e5f00412de58fc35ccbad451b4f (patch)
tree118fb5f46f3b1e8e2b5acdf05db7961ba4f133ae
parent08b16d3bd1c00df47f690c02a5048269f9fe94f0 (diff)
Handle anonymous struct/union members in walk_designator (ast2firm.c).
-rw-r--r--src/firm/ast2firm.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/src/firm/ast2firm.c b/src/firm/ast2firm.c
index c940ec2..5509c9f 100644
--- a/src/firm/ast2firm.c
+++ b/src/firm/ast2firm.c
@@ -3409,40 +3409,51 @@ static void walk_designator(type_path_t *path, const designator_t *designator)
if (designator->symbol != NULL) {
assert(is_type_compound(type));
- size_t index_int = 0;
- symbol_t *symbol = designator->symbol;
-
+ symbol_t *symbol = designator->symbol;
compound_t *compound = type->compound.compound;
- entity_t *iter = compound->members.first_entity;
- for (; iter->base.symbol != symbol; iter = iter->base.next,
- ++index_int) {}
- assert(iter->kind == ENTITY_COMPOUND_MEMBER);
-
- /* revert previous initialisations of other union elements */
- if (type->kind == TYPE_COMPOUND_UNION) {
- ir_initializer_t *initializer = top->initializer;
- if (initializer != NULL
- && get_initializer_kind(initializer) == IR_INITIALIZER_COMPOUND) {
- /* are we writing to a new element? */
- ir_initializer_t *oldi
- = get_initializer_compound_value(initializer, index_int);
- if (get_initializer_kind(oldi) == IR_INITIALIZER_NULL) {
- /* clear initializer */
- size_t len
- = get_initializer_compound_n_entries(initializer);
- ir_initializer_t *nulli = get_initializer_null();
- for (size_t i = 0; i < len; ++i) {
- set_initializer_compound_value(initializer, i,
- nulli);
+
+ for (;;) {
+ entity_t *member = find_compound_entry(compound, symbol);
+ assert(member->kind == ENTITY_COMPOUND_MEMBER);
+
+ ir_entity *irent = member->compound_member.entity;
+ ir_type *parent = get_entity_owner(irent);
+ size_t index_int = get_compound_member_index(parent, irent);
+
+ /* revert previous initialisations of other union elements */
+ if (type->kind == TYPE_COMPOUND_UNION) {
+ ir_initializer_t *initializer = top->initializer;
+ if (initializer != NULL
+ && get_initializer_kind(initializer) == IR_INITIALIZER_COMPOUND) {
+ /* are we writing to a new element? */
+ ir_initializer_t *oldi
+ = get_initializer_compound_value(initializer, index_int);
+ if (get_initializer_kind(oldi) == IR_INITIALIZER_NULL) {
+ /* clear initializer */
+ size_t len
+ = get_initializer_compound_n_entries(initializer);
+ ir_initializer_t *nulli = get_initializer_null();
+ for (size_t i = 0; i < len; ++i) {
+ set_initializer_compound_value(initializer, i,
+ nulli);
+ }
}
}
}
- }
- top->type = orig_type;
- top->compound_entry = iter;
- top->index = index_int;
- orig_type = iter->declaration.type;
+ top->type = orig_type;
+ top->compound_entry = member;
+ top->index = index_int;
+ orig_type = member->declaration.type;
+
+ if (member->base.symbol) {
+ break;
+ }
+
+ descend_into_subtype(path, &designator->pos);
+ top = get_type_path_top(path);
+ compound = skip_typeref(orig_type)->compound.compound;
+ }
} else {
expression_t *array_index = designator->array_index;
assert(is_type_array(type));