From 699ceb15a5016bf63f0df7ecc2d351b95ca4fa89 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 28 Apr 2022 11:26:20 +0200 Subject: [PATCH] Elaborate enum type on demand Enum types are currently elaborated in lexical declaration order. With forward typedefs it is possible that a type is referenced before it is declared. To support this elaborate the enum type on demand when it is used. This is similar to what is being done for other types. Signed-off-by: Lars-Peter Clausen --- elab_scope.cc | 27 ++------------------------- elab_type.cc | 33 +++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index a03d4df75..716c3bed4 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -169,34 +169,11 @@ static void collect_scope_specparams(Design*des, NetScope*scope, static void elaborate_scope_enumeration(Design*des, NetScope*scope, enum_type_t*enum_type) { - ivl_type_t base_type; bool rc_flag; - base_type = enum_type->base_type->elaborate_type(des, scope); + enum_type->elaborate_type(des, scope); - const struct netvector_t *vec_type = dynamic_cast(base_type); - - if (!vec_type && !dynamic_cast(base_type)) { - cerr << enum_type->get_fileline() << ": error: " - << "Invalid enum base type `" << *base_type << "`." - << endl; - des->errors++; - } else if (base_type->slice_dimensions().size() > 1) { - cerr << enum_type->get_fileline() << ": error: " - << "Enum type must not have more than 1 packed dimension." - << endl; - des->errors++; - } - - bool integer_flag = false; - if (vec_type) - integer_flag = vec_type->get_isint(); - - netenum_t*use_enum = new netenum_t(base_type, enum_type->names->size(), - integer_flag); - - use_enum->set_line(*enum_type); - scope->add_enumeration_set(enum_type, use_enum); + netenum_t *use_enum = scope->enumeration_for_key(enum_type); size_t name_idx = 0; // Find the enumeration width. diff --git a/elab_type.cc b/elab_type.cc index aeb8e5492..cb0156dfd 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -136,13 +136,34 @@ ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const * available at the right time. At that time, the netenum_t* object is * stashed in the scope so that I can retrieve it here. */ -ivl_type_t enum_type_t::elaborate_type_raw(Design*, NetScope*scope) const +ivl_type_t enum_type_t::elaborate_type_raw(Design *des, NetScope *scope) const { - ivl_assert(*this, scope); - ivl_type_t tmp = scope->enumeration_for_key(this); - if (tmp == 0 && scope->unit()) - tmp = scope->unit()->enumeration_for_key(this); - return tmp; + ivl_type_t base = base_type->elaborate_type(des, scope); + + const struct netvector_t *vec_type = dynamic_cast(base); + + if (!vec_type && !dynamic_cast(base)) { + cerr << get_fileline() << ": error: " + << "Invalid enum base type `" << *base << "`." + << endl; + des->errors++; + } else if (base->slice_dimensions().size() > 1) { + cerr << get_fileline() << ": error: " + << "Enum type must not have more than 1 packed dimension." + << endl; + des->errors++; + } + + bool integer_flag = false; + if (vec_type) + integer_flag = vec_type->get_isint(); + + netenum_t *type = new netenum_t(base, names->size(), integer_flag); + type->set_line(*this); + + scope->add_enumeration_set(this, type); + + return type; } ivl_type_t vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const