From c1d781707eb611d65aa4e1275f246debba557a3d Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 15 Oct 2019 12:27:21 +0000 Subject: [PATCH] [C++ PATCH] clone_function_decl breakup 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 | 5 ++++ gcc/cp/class.c | 63 ++++++++++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a2fc0720b47..ecaf312639b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2019-10-15 Nathan Sidwell + * 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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b9266b39e28..a66c25b65be 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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 -- 2.30.2