diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index da70b358413..4f5f8eca130 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -47,7 +47,7 @@ gtfiles="\ \$(srcdir)/cp/friend.c \ \$(srcdir)/cp/init.c \ \$(srcdir)/cp/lambda.c \$(srcdir)/cp/lex.c \$(srcdir)/cp/logic.cc \ -\$(srcdir)/cp/mangle.c \$(srcdir)/cp/method.c \ +\$(srcdir)/cp/mangle.c \$(srcdir)/cp/method.c \$(srcdir)/cp/module.cc \ \$(srcdir)/cp/name-lookup.c \ \$(srcdir)/cp/parser.c \$(srcdir)/cp/pt.c \ \$(srcdir)/cp/rtti.c \ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b13c9d9f73d..6d8158a66f0 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4964,6 +4964,11 @@ c_parse_final_cleanups (void) instantiate_pending_templates (retries); ggc_collect (); + if (header_module_p ()) + /* A header modules initializations are handled in its + importer. */ + continue; + /* Write out virtual tables as required. Writing out the virtual table for a template class may cause the instantiation of members of that class. If we write out @@ -5162,6 +5167,8 @@ c_parse_final_cleanups (void) reconsider = true; } + finish_module_processing (parse_in); + lower_var_init (); generate_mangling_aliases (); @@ -5177,6 +5184,10 @@ c_parse_final_cleanups (void) #pragma interface, etc.) we decided not to emit the definition here. */ && !DECL_INITIAL (decl) + /* A defaulted fn in a header module can be synthesized on + demand later. (In non-header modules we should have + synthesized it above.) */ + && !(DECL_DEFAULTED_FN (decl) && header_module_p ()) /* Don't complain if the template was defined. */ && !(DECL_TEMPLATE_INSTANTIATION (decl) && DECL_INITIAL (DECL_TEMPLATE_RESULT @@ -5210,9 +5221,8 @@ c_parse_final_cleanups (void) splay_tree_foreach (priority_info_map, generate_ctor_and_dtor_functions_for_priority, /*data=*/&locus_at_end_of_parsing); - else if (c_dialect_objc () && objc_static_init_needed_p ()) - /* If this is obj-c++ and we need a static init, call - generate_ctor_or_dtor_function. */ + else if ((c_dialect_objc () && objc_static_init_needed_p ()) + || module_initializer_kind ()) generate_ctor_or_dtor_function (/*constructor_p=*/true, DEFAULT_INIT_PRIORITY, &locus_at_end_of_parsing); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 1a1647f465e..f6746d7304b 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -1114,6 +1114,8 @@ maybe_add_lambda_conv_op (tree type) while (src) { tree new_node = copy_node (src); + /* We set DECL_CONTEXT of NEW_NODE to the statfn below. + Notice this is creating a recursive type! */ /* Clear TREE_ADDRESSABLE on thunk arguments. */ TREE_ADDRESSABLE (new_node) = 0; @@ -1393,6 +1395,12 @@ record_lambda_scope (tree lambda) { LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope; LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++; + if (lambda_scope) + { + tree closure = LAMBDA_EXPR_CLOSURE (lambda); + gcc_checking_assert (closure); + maybe_attach_decl (lambda_scope, TYPE_NAME (closure)); + } } /* This lambda is an instantiation of a lambda in a template default argument diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 2417d67ee41..d8012d75ca4 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -154,11 +154,21 @@ set_originating_module (tree, bool) { } +void +maybe_attach_decl (tree, tree) +{ +} + void lazy_load_binding (unsigned, tree, tree, binding_slot *) { } +void +lazy_load_specializations (tree) +{ +} + void lazy_load_members (tree) { @@ -216,6 +226,11 @@ maybe_check_all_macros (cpp_reader *) { } +void +finish_module_processing (cpp_reader *) +{ +} + void fini_modules () { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6b8e486a642..e5f18d23ea0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9788,6 +9788,15 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, return error_mark_node; gen_tmpl = most_general_template (templ); + if (modules_p ()) + { + tree origin = get_originating_module_decl (gen_tmpl); + load_pending_specializations (CP_DECL_CONTEXT (origin), + DECL_NAME (origin)); + if (DECL_MODULE_PENDING_SPECIALIZATIONS_P (gen_tmpl)) + lazy_load_specializations (gen_tmpl); + } + parmlist = DECL_TEMPLATE_PARMS (gen_tmpl); parm_depth = TMPL_PARMS_DEPTH (parmlist); arg_depth = TMPL_ARGS_DEPTH (arglist); @@ -20907,6 +20916,15 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (tmpl)), targ_ptr)); + if (modules_p ()) + { + tree origin = get_originating_module_decl (gen_tmpl); + load_pending_specializations (CP_DECL_CONTEXT (origin), + DECL_NAME (origin)); + if (DECL_MODULE_PENDING_SPECIALIZATIONS_P (gen_tmpl)) + lazy_load_specializations (gen_tmpl); + } + /* It would be nice to avoid hashing here and then again in tsubst_decl, but it doesn't seem to be on the hot path. */ spec = retrieve_specialization (gen_tmpl, targ_ptr, 0); diff --git a/gcc/gcc.c b/gcc/gcc.c index 1d32375f648..d179de7d97f 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -1232,6 +1232,7 @@ static const char *cpp_unique_options = %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\ %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\ %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\ + %{Mmodules} %{Mno-modules}\ %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\ %{remap} %{%:debug-level-gt(2):-dD}\ %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\ diff --git a/gcc/tree-core.h b/gcc/tree-core.h index e457b917b98..a89f063ab55 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -773,6 +773,10 @@ enum tree_index { TI_SAT_UDA_TYPE, TI_SAT_UTA_TYPE, + TI_MODULE_HWM, + /* Nodes below here change during compilation, and should therefore + not be in the C++ module's global tree table. */ + TI_OPTIMIZATION_DEFAULT, TI_OPTIMIZATION_CURRENT, TI_TARGET_OPTION_DEFAULT,