[C++ PATCH] clone_function_decl breakup
authorNathan Sidwell <nathan@acm.org>
Tue, 15 Oct 2019 12:27:21 +0000 (12:27 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 15 Oct 2019 12:27:21 +0000 (12:27 +0000)
https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01083.html
This patch, from the modules branch, breaks out function cloning from the
method vector updating. We have a new function, build_clones,
which does the building, returning a count of the number of clones
(2 or 3). clone_function_decl separately adds them to the method
vector, if they should be added. I suppose this could have used
FOR_EVERY_CLONE, but I went with the counting scheme.

* class.c (build_clones): Break out of clone_function_decl.  Just
build the clones.
(clone_function_decl): Call build_clones, then maybe add them to
the method vector.

From-SVN: r276998

gcc/cp/ChangeLog
gcc/cp/class.c

index a2fc0720b47a09e6fddd4880f79999a89f477733..ecaf312639bf0ce0a3d2e140a5a5bd2c36c3e60e 100644 (file)
@@ -1,5 +1,10 @@
 2019-10-15  Nathan Sidwell  <nathan@acm.org>
 
+       * class.c (build_clones): Break out of clone_function_decl.  Just
+       build the clones.
+       (clone_function_decl): Call build_clones, then maybe add them to
+       the method vector.
+
        * class.c (build_clone): Refactor to clarify recursiveness.
 
 2019-10-14  Jason Merrill  <jason@redhat.com>
index b9266b39e287705a7b287ddfdb683ce09bea19e3..a66c25b65be9f7f61fe899f587b1a1095d3628a7 100644 (file)
@@ -4699,30 +4699,21 @@ build_clone (tree fn, tree name)
   return clone;
 }
 
-/* Produce declarations for all appropriate clones of FN.  If
-   UPDATE_METHODS is true, the clones are added to the
-   CLASSTYPE_MEMBER_VEC.  */
+/* Build the clones of FN, return the number of clones built.  These
+   will be inserted onto DECL_CHAIN of FN.  */
 
-void
-clone_function_decl (tree fn, bool update_methods)
+unsigned
+build_clones (tree fn)
 {
-  tree clone;
-
-  /* Avoid inappropriate cloning.  */
-  if (DECL_CHAIN (fn)
-      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
-    return;
+  unsigned count = 0;
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
     {
       /* For each constructor, we need two variants: an in-charge version
         and a not-in-charge version.  */
-      clone = build_clone (fn, complete_ctor_identifier);
-      if (update_methods)
-       add_method (DECL_CONTEXT (clone), clone, false);
-      clone = build_clone (fn, base_ctor_identifier);
-      if (update_methods)
-       add_method (DECL_CONTEXT (clone), clone, false);
+      build_clone (fn, complete_ctor_identifier);
+      build_clone (fn, base_ctor_identifier);
+      count += 2;
     }
   else
     {
@@ -4739,20 +4730,40 @@ clone_function_decl (tree fn, bool update_methods)
         destructor.  */
       if (DECL_VIRTUAL_P (fn))
        {
-         clone = build_clone (fn, deleting_dtor_identifier);
-         if (update_methods)
-           add_method (DECL_CONTEXT (clone), clone, false);
+         build_clone (fn, deleting_dtor_identifier);
+         count++;
        }
-      clone = build_clone (fn, complete_dtor_identifier);
-      if (update_methods)
-       add_method (DECL_CONTEXT (clone), clone, false);
-      clone = build_clone (fn, base_dtor_identifier);
-      if (update_methods)
-       add_method (DECL_CONTEXT (clone), clone, false);
+      build_clone (fn, complete_dtor_identifier);
+      build_clone (fn, base_dtor_identifier);
+      count += 2;
     }
 
+  return count;
+}
+
+/* Produce declarations for all appropriate clones of FN.  If
+   UPDATE_METHODS is true, the clones are added to the
+   CLASSTYPE_MEMBER_VEC.  */
+
+void
+clone_function_decl (tree fn, bool update_methods)
+{
+  /* Avoid inappropriate cloning.  */
+  if (DECL_CHAIN (fn)
+      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
+    return;
+
+  unsigned count = build_clones (fn);
+
   /* Note that this is an abstract function that is never emitted.  */
   DECL_ABSTRACT_P (fn) = true;
+
+  if (update_methods)
+    for (tree clone = fn; count--;)
+      {
+       clone = DECL_CHAIN (clone);
+       add_method (DECL_CONTEXT (clone), clone, false);
+      }
 }
 
 /* DECL is an in charge constructor, which is being defined. This will