c++: template and clone fns for modules
authorNathan Sidwell <nathan@acm.org>
Tue, 8 Dec 2020 18:38:10 +0000 (10:38 -0800)
committerNathan Sidwell <nathan@acm.org>
Tue, 8 Dec 2020 18:41:15 +0000 (10:41 -0800)
We need to expose build_cdtor_clones, it fortunately has the desired
API -- gosh, how did that happen? :) The template machinery will need
to cache path-of-instantiation information, so add two more fields to
the tinst_level struct.  I also had to adjust the
match_mergeable_specialization API since adding it, so including that
change too.

gcc/cp/
* cp-tree.h (struct tinst_level): Add path & visible fields.
(build_cdtor_clones): Declare.
(match_mergeable_specialization): Use a spec_entry, add insert parm.
* class.c (build_cdtor_clones): Externalize.
* pt.c (push_tinst_level_loc): Clear new fields.
(match_mergeable_specialization): Adjust API.

gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/pt.c

index ec47b0698ab4413327b60bd956db9fa1c8fe0e4f..2ab123d6ccfb4a68fae8650d7334c2996b667a2c 100644 (file)
@@ -4920,7 +4920,7 @@ build_clone (tree fn, tree name, bool need_vtt_parm_p,
 /* Build the clones of FN, return the number of clones built.  These
    will be inserted onto DECL_CHAIN of FN.  */
 
-static void
+void
 build_cdtor_clones (tree fn, bool needs_vtt_p, bool base_omits_inherited_p,
                    bool update_methods)
 {
index f11cf87f190cb258c286dcd9595a3a5f3602f9a6..66ad114567d64262edd9ac9ad0ab1156d2ac6380 100644 (file)
@@ -6196,6 +6196,13 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
      arguments.  */
   tree tldcl, targs;
 
+  /* For modules we need to know (a) the modules on the path of
+     instantiation and (b) the transitive imports along that path.
+     Note that these two bitmaps may be inherited from NEXT, if this
+     decl is in the same module as NEXT (or has no new information).  */
+  bitmap path;
+  bitmap visible;
+
  private:
   /* Return TRUE iff the original node is a split list.  */
   bool split_list_p () const { return targs; }
@@ -6497,6 +6504,7 @@ extern void check_abi_tags                        (tree);
 extern tree missing_abi_tags                   (tree);
 extern void fixup_type_variants                        (tree);
 extern void fixup_attribute_variants           (tree);
+extern void build_cdtor_clones                         (tree, bool, bool, bool);
 extern void clone_cdtor                                (tree, bool);
 extern tree copy_operator_fn                   (tree, tree_code code);
 extern void adjust_clone_args                  (tree);
@@ -7189,8 +7197,8 @@ extern void walk_specializations          (bool,
                                                 void (*)(bool, spec_entry *,
                                                          void *),
                                                 void *);
-extern tree match_mergeable_specialization     (bool is_decl, tree tmpl,
-                                                tree args, tree spec);
+extern tree match_mergeable_specialization     (bool is_decl, spec_entry *,
+                                                bool insert = true);
 extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec);
 extern void add_mergeable_specialization        (tree tmpl, tree args,
                                                 tree spec, unsigned);
index 2d3ab92dfd1713993158762dfccc76179760c805..56d7b56022919013a511bac00ae21e4d49841187 100644 (file)
@@ -1704,10 +1704,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
   return spec;
 }
 
-/* Returns true iff two spec_entry nodes are equivalent.  */
-
+/* Restricts tree and type comparisons.  */
 int comparing_specializations;
 
+/* Returns true iff two spec_entry nodes are equivalent.  */
+
 bool
 spec_hasher::equal (spec_entry *e1, spec_entry *e2)
 {
@@ -10909,6 +10910,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
   new_level->errors = errorcount + sorrycount;
   new_level->next = NULL;
   new_level->refcount = 0;
+  new_level->path = new_level->visible = nullptr;
   set_refcount_ptr (new_level->next, current_tinst_level);
   set_refcount_ptr (current_tinst_level, new_level);
 
@@ -29668,29 +29670,27 @@ walk_specializations (bool decls_p,
     fn (decls_p, *iter, data);
 }
 
-/* Lookup the specialization of TMPL, ARGS in the decl or type
-   specialization table.  Return what's there, or if SPEC is non-null,
-   add it and return NULL.  */
+/* Lookup the specialization of *ELT, in the decl or type
+   specialization table.  Return the SPEC that's already there (NULL if
+   nothing).  If INSERT is true, and there was nothing, add the new
+   spec.  */
 
 tree
-match_mergeable_specialization (bool decl_p, tree tmpl, tree args, tree spec)
+match_mergeable_specialization (bool decl_p, spec_entry *elt, bool insert)
 {
-  spec_entry elt = {tmpl, args, spec};
   hash_table<spec_hasher> *specializations
     = decl_p ? decl_specializations : type_specializations;
-  hashval_t hash = spec_hasher::hash (&elt);
+  hashval_t hash = spec_hasher::hash (elt);
   spec_entry **slot
-    = specializations->find_slot_with_hash (&elt, hash,
-                                           spec ? INSERT : NO_INSERT);
-  spec_entry *entry = slot ? *slot: NULL;
-  
-  if (entry)
-    return entry->spec;
+    = specializations->find_slot_with_hash (elt, hash,
+                                           insert ? INSERT : NO_INSERT);
+  if (slot && *slot)
+    return (*slot)->spec;
 
-  if (spec)
+  if (insert)
     {
-      entry = ggc_alloc<spec_entry> ();
-      *entry = elt;
+      auto entry = ggc_alloc<spec_entry> ();
+      *entry = *elt;
       *slot = entry;
     }