diff --git a/elaborate.cc b/elaborate.cc index 940d00365..21b131762 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -6766,18 +6766,18 @@ static void check_timescales() if (some_explicit && some_implicit) break; } - map::iterator pkg; + vector::iterator pkg; if (gn_system_verilog() && !(some_explicit && some_implicit)) { for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) { - const PPackage*pp = (*pkg).second; + const PPackage*pp = *pkg; check_timescales(some_explicit, some_implicit, pp); if (some_explicit && some_implicit) break; } } if (gn_system_verilog() && !(some_explicit && some_implicit)) { - for (unsigned idx = 0; idx < pform_units.size(); idx += 1) { - const PPackage*pp = pform_units[idx]; + for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) { + const PPackage*pp = *pkg; // We don't need a timescale if the compilation unit // contains no items outside a design element. if (pp->parameters.empty() && @@ -6828,15 +6828,15 @@ static void check_timescales() return; for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) { - PPackage*pp = (*pkg).second; + PPackage*pp = *pkg; if (pp->has_explicit_timescale()) continue; - cerr << " : -- package " << (*pkg).first + cerr << " : -- package " << pp->pscope_name() << " declared here: " << pp->get_fileline() << endl; } - for (unsigned idx = 0; idx < pform_units.size(); idx += 1) { - PPackage*pp = pform_units[idx]; + for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) { + PPackage*pp = *pkg; if (pp->has_explicit_timescale()) continue; @@ -6892,8 +6892,9 @@ Design* elaborate(listroots) // Elaborate the compilation unit scopes. From here on, these are // treated as an additional set of packages. if (gn_system_verilog()) { - for (i = 0; i < pform_units.size(); i += 1) { - PPackage*unit = pform_units[i]; + for (vector::iterator pkg = pform_units.begin() + ; pkg != pform_units.end() ; ++pkg) { + PPackage*unit = *pkg; NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true); scope->set_line(unit); scope->add_imports(&unit->explicit_imports); @@ -6904,6 +6905,7 @@ Design* elaborate(listroots) pack_elems[i].pack = unit; pack_elems[i].scope = scope; + i += 1; unit_scopes[unit] = scope; } @@ -6914,20 +6916,19 @@ Design* elaborate(listroots) // in SystemVerilog, packages are not allowed to refer to // the compilation unit scope, but the VHDL preprocessor // assumes they can. - for (map::iterator pac = pform_packages.begin() - ; pac != pform_packages.end() ; ++ pac) { + for (vector::iterator pkg = pform_packages.begin() + ; pkg != pform_packages.end() ; ++pkg) { + PPackage*pack = *pkg; + NetScope*unit_scope = unit_scopes[pack->parent_scope()]; + NetScope*scope = des->make_package_scope(pack->pscope_name(), unit_scope, false); + scope->set_line(pack); + scope->add_imports(&pack->explicit_imports); + set_scope_timescale(des, scope, pack); - ivl_assert(*pac->second, pac->first == pac->second->pscope_name()); - NetScope*unit_scope = unit_scopes[pac->second->parent_scope()]; - NetScope*scope = des->make_package_scope(pac->first, unit_scope, false); - scope->set_line(pac->second); - scope->add_imports(&pac->second->explicit_imports); - set_scope_timescale(des, scope, pac->second); - - elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second); + elaborator_work_item_t*es = new elaborate_package_t(des, scope, pack); des->elaboration_work_list.push_back(es); - pack_elems[i].pack = pac->second; + pack_elems[i].pack = pack; pack_elems[i].scope = scope; i += 1; } diff --git a/main.cc b/main.cc index 45b626f77..7da46989a 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,5 @@ const char COPYRIGHT[] = - "Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)"; + "Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)"; /* * This source code is free software; you can redistribute it @@ -1142,9 +1142,9 @@ int main(int argc, char*argv[]) pform_dump(out, *pac); } out << "PFORM DUMP PACKAGES:" << endl; - for (map::iterator pac = pform_packages.begin() + for (vector::iterator pac = pform_packages.begin() ; pac != pform_packages.end() ; ++ pac) { - pform_dump(out, pac->second); + pform_dump(out, *pac); } out << "PFORM DUMP MODULES:" << endl; for (map::iterator mod = pform_modules.begin() diff --git a/parse_api.h b/parse_api.h index 1b76b767b..0ed284b3c 100644 --- a/parse_api.h +++ b/parse_api.h @@ -1,7 +1,7 @@ #ifndef IVL_parse_api_H #define IVL_parse_api_H /* - * Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -43,7 +43,7 @@ struct enum_type_t; extern std::map pform_modules; extern std::map pform_primitives; extern std::vector pform_units; -extern std::map pform_packages; +extern std::vector pform_packages; extern void pform_dump(std::ostream&out, const PClass*pac); extern void pform_dump(std::ostream&out, const PPackage*pac); diff --git a/pform_package.cc b/pform_package.cc index 375523f41..100ae6b42 100644 --- a/pform_package.cc +++ b/pform_package.cc @@ -29,9 +29,14 @@ using namespace std; /* - * This is a map of packages that have been defined. + * This is a list of packages in the order that they were defined. */ -map pform_packages; +vector pform_packages; + +/* + * This allows us to easily check for name collisions. + */ +static map packages_by_name; static PPackage*pform_cur_package = 0; @@ -51,8 +56,8 @@ void pform_end_package_declaration(const struct vlltype&loc) ivl_assert(loc, pform_cur_package); perm_string use_name = pform_cur_package->pscope_name(); - map::const_iterator test = pform_packages.find(use_name); - if (test != pform_packages.end()) { + map::const_iterator test = packages_by_name.find(use_name); + if (test != packages_by_name.end()) { ostringstream msg; msg << "Package " << use_name << " was already declared here: " << test->second->get_fileline() << ends; @@ -60,7 +65,8 @@ void pform_end_package_declaration(const struct vlltype&loc) } - pform_packages[use_name] = pform_cur_package; + packages_by_name[use_name] = pform_cur_package; + pform_packages.push_back(pform_cur_package); pform_cur_package = 0; pform_pop_scope(); } @@ -152,8 +158,8 @@ data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt) PPackage* pform_test_package_identifier(const char*pkg_name) { perm_string use_name = lex_strings.make(pkg_name); - map::const_iterator pcur = pform_packages.find(use_name); - if (pcur == pform_packages.end()) + map::const_iterator pcur = packages_by_name.find(use_name); + if (pcur == packages_by_name.end()) return 0; assert(pcur->second);