diff --git a/parse.y b/parse.y index dd12a9837..edd0fc47b 100644 --- a/parse.y +++ b/parse.y @@ -750,7 +750,7 @@ class_identifier perm_string name = lex_strings.make($1); class_type_t*tmp = new class_type_t(name); FILE_NAME(tmp, @1); - pform_set_typedef(name, tmp); + pform_set_typedef(name, tmp, NULL); delete[]$1; $$ = tmp; } @@ -2358,9 +2358,9 @@ block_item_decls_opt /* Type declarations are parsed here. The rule actions call pform functions that add the declaration to the current lexical scope. */ type_declaration - : K_typedef data_type IDENTIFIER ';' + : K_typedef data_type IDENTIFIER dimensions_opt ';' { perm_string name = lex_strings.make($3); - pform_set_typedef(name, $2); + pform_set_typedef(name, $2, $4); delete[]$3; } @@ -2373,7 +2373,7 @@ type_declaration yyerror(@3, "error: Typedef identifier \"%s\" is already a type name.", $3.text); } else { - pform_set_typedef(name, $2); + pform_set_typedef(name, $2, NULL); } delete[]$3.text; } @@ -2386,7 +2386,7 @@ type_declaration perm_string name = lex_strings.make($3); class_type_t*tmp = new class_type_t(name); FILE_NAME(tmp, @3); - pform_set_typedef(name, tmp); + pform_set_typedef(name, tmp, NULL); delete[]$3; } | K_typedef K_enum IDENTIFIER ';' @@ -2401,7 +2401,7 @@ type_declaration perm_string name = lex_strings.make($2); class_type_t*tmp = new class_type_t(name); FILE_NAME(tmp, @2); - pform_set_typedef(name, tmp); + pform_set_typedef(name, tmp, NULL); delete[]$2; } diff --git a/pform.cc b/pform.cc index 1e42fa0ad..b8318c792 100644 --- a/pform.cc +++ b/pform.cc @@ -593,8 +593,11 @@ PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetN return cur; } -void pform_set_typedef(perm_string name, data_type_t*data_type) +void pform_set_typedef(perm_string name, data_type_t*data_type, std::list*unp_ranges) { + if(unp_ranges) + data_type = new uarray_type_t(data_type, unp_ranges); + // If we are in a lexical scope (i.e. a package or module) // then put the typedef into that scope. Otherwise, put it // into the $root scope. @@ -1939,7 +1942,6 @@ static void pform_set_net_range(list*names, pform_set_net_range(txt, net_type, range, signed_flag, dt, SR_NET, attr); } - delete names; } /* @@ -3171,7 +3173,6 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list*attr) @@ -3247,7 +3248,6 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, pform_set_enum(li, enum_type, txt, net_type, attr); } - delete names; } /* @@ -3256,58 +3256,68 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, */ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, NetNet::Type net_type, list*attr) { + const std::list*unpacked_dims = NULL; + if (data_type == 0) { VLerror(li, "internal error: data_type==0."); assert(0); } + if(uarray_type_t*uarray_type = dynamic_cast (data_type)) { + unpacked_dims = uarray_type->dims.get(); + data_type = uarray_type->base_type; + } + if (atom2_type_t*atom2_type = dynamic_cast (data_type)) { pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, net_type, attr); - return; } - if (struct_type_t*struct_type = dynamic_cast (data_type)) { + else if (struct_type_t*struct_type = dynamic_cast (data_type)) { pform_set_struct_type(struct_type, names, net_type, attr); - return; } - if (enum_type_t*enum_type = dynamic_cast (data_type)) { + else if (enum_type_t*enum_type = dynamic_cast (data_type)) { pform_set_enum(li, enum_type, names, net_type, attr); - return; } - if (vector_type_t*vec_type = dynamic_cast (data_type)) { + else if (vector_type_t*vec_type = dynamic_cast (data_type)) { if (net_type==NetNet::REG && vec_type->integer_flag) net_type=NetNet::INTEGER; pform_set_net_range(names, vec_type->pdims.get(), vec_type->signed_flag, vec_type->base_type, net_type, attr); - return; } - if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { + else if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { pform_set_net_range(names, 0, true, IVL_VT_REAL, net_type, attr); - return; } - if (class_type_t*class_type = dynamic_cast (data_type)) { + else if (class_type_t*class_type = dynamic_cast (data_type)) { pform_set_class_type(class_type, names, net_type, attr); - return; } - if (parray_type_t*array_type = dynamic_cast (data_type)) { + else if (parray_type_t*array_type = dynamic_cast (data_type)) { pform_set2_data_type(li, array_type, names, net_type, attr); - return; } - if (string_type_t*string_type = dynamic_cast (data_type)) { + else if (string_type_t*string_type = dynamic_cast (data_type)) { pform_set_string_type(string_type, names, net_type, attr); - return; + + } else { + VLerror(li, "internal error: Unexpected data_type."); + assert(0); } - VLerror(li, "internal error: Unexpected data_type."); - assert(0); + if(unpacked_dims) { + for (list::iterator cur = names->begin() + ; cur != names->end() ; ++ cur ) { + PWire*wire = pform_get_wire_in_scope(*cur); + wire->set_unpacked_idx(*unpacked_dims); + } + } + + delete names; } vector* pform_make_udp_input_ports(list*names) diff --git a/pform.h b/pform.h index 5ea113c37..db36e73b4 100644 --- a/pform.h +++ b/pform.h @@ -287,7 +287,8 @@ extern void pform_endgenerate(); */ extern PGenerate* pform_parent_generate(void); -extern void pform_set_typedef(perm_string name, data_type_t*data_type); +extern void pform_set_typedef(perm_string name, data_type_t*data_type, + std::list*unp_ranges); /* * This function makes a PECallFunction of the named function. Decide