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.
This commit is contained in:
Nathan Sidwell 2020-12-11 11:10:40 -08:00
parent 02fc65c726
commit 262784be3d
7 changed files with 60 additions and 4 deletions

View File

@ -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 \

View File

@ -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);

View File

@ -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

View File

@ -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 ()
{

View File

@ -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);

View File

@ -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()}}\

View File

@ -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,