https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99170
--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Nathan Sidwell <nat...@gcc.gnu.org>: https://gcc.gnu.org/g:c778a237c1c605c2c5606c212c1ace756739442b commit r11-7506-gc778a237c1c605c2c5606c212c1ace756739442b Author: Nathan Sidwell <nat...@acm.org> Date: Wed Mar 3 10:09:41 2021 -0800 c++: Redesign pending entity handling [PR 99170] This patch addresses 99170. with modules (and in particular header units), one module can provide a (maybe nested) class or template and another module can provide a definition or (maybe partial) specialization of said entity, or member thereof. when both are imported into a 3rd TU, and that TU instantiates or uses the class, it needs to stream in those entities (in general). But how does it key those entities to the original? It can't /just/ use the entity index, because, when header-units and/or partitions are in play, the entity index /is not unique/. I had two complicated schemes that tried to unify that, but it failed. Here's a simpler scheme. Such pending entities are keyed to the namespace and identifier of the namespace-scope entity that contains them. Thus the final TU needs to find that entity and look in a hash table for lists of sections that need loading just before instantiating a template or looking inside a class. I would like to make this more efficient, but given the complex scheme failed, I'm shooting for correctness right now. There will be a follow up patch to complete the cleanup this enables. PR c++/99170 gcc/cp/ * cp-tree.h * lex.c (cxx_dup_lang_specific_decl): Adjust for module_attached_p rename. * module.cc (class pending_key): New. (default_hash_traits<pending_key>): New specialization. (pending_map_t): New typedef. (pending_table): Replace old table. (trees_out::lang_decl_bools): Adjust. (trees_in::lang_decl_bools): Adjust. (trees_in::install_entity): Drop pending member and specialization handling. (find_pending_key): New. (depset::hash::fiund_dependencies): Use it. (pendset_lazy_load): Delete. (module_state::write_cluster): Don't count pendings here. Bye Duff's device-like thing. (module_state::write_pendings): Reimplement. (module_state::read_pendings): Reimplement. (lazy_specializations_p): Delete. (module_state::write): Adjust write_pendings call. (lazy_load_pendings): New. (lazy_load_specializations): Delete. (lazy_load_members): Delete. (init_modules): Adjust. * name-lookup.c (maybe_lazily_declare): Call lazy_load_pendings not lazy_load_members. (note_pending_specializations): Delete. (load_pending_specializations): Delete. * name-lookup.h (BINDING_VECTR_PENDING_SPECIALIZATIONS_P): Delete. (BINDING_VECTOR_PENDING_MEMBERS_P): Delete. (BINDING_VECTR_PENDING_MEMBERS_P): Delete. (note_pending_specializations): Delete. (load_pending_specializations): Delete. * pt.c (lookup_template_class_1): Call lazy_load_pendings not lazy_load_specializations. (instantiate_template_class_1): Likewise. (instantiate_decl): Call lazy_load_pendings. * typeck.c (complete_type): Likewise. gcc/testsuite/ * g++.dg/modules/pr99170-1_a.H: New. * g++.dg/modules/pr99170-1_b.C: New. * g++.dg/modules/pr99170-2.h: New. * g++.dg/modules/pr99170-2_a.C: New. * g++.dg/modules/pr99170-2_b.C: New. * g++.dg/modules/pr99170-3_a.H: New. * g++.dg/modules/pr99170-3_b.C: New. * g++.dg/modules/inst-2_b.C: Adjust scan. * g++.dg/modules/inst-4_a.C: Adjust scan. * g++.dg/modules/inst-4_b.C: Adjust scan. * g++.dg/modules/member-def-1_b.C: Adjust scan. * g++.dg/modules/member-def-1_c.C: Adjust scan. * g++.dg/modules/tpl-spec-1_a.C: Adjust scan. * g++.dg/modules/tpl-spec-1_b.C: Adjust scan. * g++.dg/modules/tpl-spec-2_b.C: Adjust scan. * g++.dg/modules/tpl-spec-2_c.C: Adjust scan. * g++.dg/modules/tpl-spec-2_d.C: Adjust scan. * g++.dg/modules/tpl-spec-3_a.C: Adjust scan. * g++.dg/modules/tpl-spec-3_b.C: Adjust scan. * g++.dg/modules/tpl-spec-4_a.C: Adjust scan. * g++.dg/modules/tpl-spec-4_b.C: Adjust scan. * g++.dg/modules/tpl-spec-5_a.C: Adjust scan. * g++.dg/modules/tpl-spec-5_b.C: Adjust scan.