c++: Final module preparations
authorNathan Sidwell <nathan@acm.org>
Fri, 11 Dec 2020 19:10:40 +0000 (11:10 -0800)
committerNathan Sidwell <nathan@acm.org>
Fri, 11 Dec 2020 19:15:30 +0000 (11:15 -0800)
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
gcc/cp/decl2.c
gcc/cp/lambda.c
gcc/cp/module.cc
gcc/cp/pt.c
gcc/gcc.c
gcc/tree-core.h

index da70b358413b798780653274cb2b3e82d1f989fc..4f5f8eca130084572c60c44b8fdd4ffd40ad4520 100644 (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 \
index b13c9d9f73d127d1f355d84a8dcdbba6bfa5f11a..6d8158a66f046594a85b120dfeec09ab37765393 100644 (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);
index 1a1647f465e804f64adefbb279bf61945fdeac11..f6746d7304be70920dcc01b56dbf53709e47560f 100644 (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
index 2417d67ee410e10dfb82952b4d77548dce1f4d16..d8012d75ca4a3d3bb6474c9f9b5e90d38161e0d1 100644 (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 ()
 {
index 6b8e486a642c75f74025aac363f66f98db17a911..e5f18d23ea06c26898dce76ad3b16ad0d785e98c 100644 (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);
index 1d32375f64885c7e5acccbcc336acebea0aa2f5c..d179de7d97f3fe1eac1ef55050890d9ce715b094 100644 (file)
--- 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()}}\
index e457b917b98e08a2fe83adc0610ef364169bc9de..a89f063ab55a748551802092c627c10324354473 100644 (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,