From 262784be3dcf91a712502b1f4f73e72155171f20 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 11 Dec 2020 11:10:40 -0800 Subject: [PATCH] c++: Final module preparations This adds the final few preparations to drop modules in. I'd missed a couple of changes to core compiler -- a new pair of preprocessor options, and marking the boundary of fixed and lazy global trees. For C++, we need to add module.cc to the GTY scanner. Parsing final cleanups needs a few tweaks for modules. Lambdas used to initialize a global (for instance) get an extra scope, but we now need to point that object to the lambda too. Finally template instantiation needs to do lazy loading before looking at the available instantiations and specializations. gcc/ * gcc.c (cpp_unique_options): Add Mmodules, Mno-modules. * tree-core.h (enum tree_index): Add TI_MODULE_HWM. gcc/cp/ * config-lang.in (gtfiles): Add cp/module.cc. * decl2.c (c_parse_final_cleanups): Add module support. * lambda.c (record_lambda_scope): Call maybe_attach_decl. * module.cc (maybe_attach_decl, lazy_load_specializations): Stubs. (finish_module_procesing): Stub. * pt.c (lookup_template_class_1): Lazy load specializations. (instantiate_template_1): Likewise. --- gcc/cp/config-lang.in | 2 +- gcc/cp/decl2.c | 16 +++++++++++++--- gcc/cp/lambda.c | 8 ++++++++ gcc/cp/module.cc | 15 +++++++++++++++ gcc/cp/pt.c | 18 ++++++++++++++++++ gcc/gcc.c | 1 + gcc/tree-core.h | 4 ++++ 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index da70b35..4f5f8ec 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 b13c9d9..6d8158a 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 1a1647f..f6746d7 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 2417d67..d8012d7 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -155,11 +155,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) { } @@ -217,6 +227,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 6b8e486..e5f18d2 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 1d32375..d179de7 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 e457b91..a89f063 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, -- 2.7.4