From 27aebb7d6cf14175aac862ab29f83a93538bfad8 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 1 Jul 2020 08:56:32 -0700 Subject: [PATCH] c++: Expose cloning form predicates A further adjustment of the function cloning. Rather than have copy_fndecl_with_name deduce whether a particular cdtor needs a vtt_parm and/or has inherited parms to drop, pass that information in from the caller. In particular build_cdtor_clones knows when its building the particular cdtors that might need these. On the modules branch I need to clone cdtors before the underlying class information is necessarily complete. There build_cdtor_clones is externally callable to facilitate that. gcc/cp/ * class.c (copy_fndecl_with_name): Add additional predicate args, do not deduce them locally. (copy_operator_fn): Adjust copy_fndecl_with_name call. (build_clone): Add vtt and inherited predicate args. Pass through to copy_fndecl_with_name call. (build_cdtor_clones): Likewise, pass through to build_clone as needed. (build_cdtor): Determine vtt and inherited here. * cp-tree.h (DECL_NEEDS_CTT_PARM_P): Delete. --- gcc/cp/class.c | 68 +++++++++++++++++++++++++++++------------------- gcc/cp/cp-tree.h | 7 ----- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b0cc027e0de..7b5f1669d04 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -182,7 +182,6 @@ static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree, static void build_rtti_vtbl_entries (tree, vtbl_init_data *); static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *); static void clone_constructors_and_destructors (tree); -static tree build_clone (tree, tree); static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned); static void build_ctor_vtbl_group (tree, tree); static void build_vtt (tree); @@ -4697,7 +4696,8 @@ check_methods (tree t) } static tree -copy_fndecl_with_name (tree fn, tree name) +copy_fndecl_with_name (tree fn, tree name, tree_code code, + bool need_vtt_parm_p, bool omit_inherited_parms_p) { /* Copy the function. */ tree clone = copy_decl (fn); @@ -4714,23 +4714,24 @@ copy_fndecl_with_name (tree fn, tree name) DECL_PENDING_INLINE_INFO (clone) = NULL; DECL_PENDING_INLINE_P (clone) = 0; - /* The base-class destructor is not virtual. */ if (name == base_dtor_identifier) { + /* The base-class destructor is not virtual. */ DECL_VIRTUAL_P (clone) = 0; DECL_VINDEX (clone) = NULL_TREE; } - else if (IDENTIFIER_OVL_OP_P (name)) + else if (code != ERROR_MARK) { - const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (name); + /* Set the operator code. */ + const ovl_op_info_t *ovl_op = OVL_OP_INFO (false, code); DECL_OVERLOADED_OPERATOR_CODE_RAW (clone) = ovl_op->ovl_op_code; - } - if (DECL_VIRTUAL_P (clone)) - IDENTIFIER_VIRTUAL_P (name) = true; + /* The operator could be virtual. */ + if (DECL_VIRTUAL_P (clone)) + IDENTIFIER_VIRTUAL_P (name) = true; + } - bool ctor_omit_inherited_parms_p = ctor_omit_inherited_parms (clone); - if (ctor_omit_inherited_parms_p) + if (omit_inherited_parms_p) gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (clone)); /* If there was an in-charge parameter, drop it from the function @@ -4744,13 +4745,12 @@ copy_fndecl_with_name (tree fn, tree name) /* Skip the in-charge parameter. */ parmtypes = TREE_CHAIN (parmtypes); /* And the VTT parm, in a complete [cd]tor. */ - if (DECL_HAS_VTT_PARM_P (fn) - && ! DECL_NEEDS_VTT_PARM_P (clone)) + if (DECL_HAS_VTT_PARM_P (fn) && !need_vtt_parm_p) parmtypes = TREE_CHAIN (parmtypes); - if (ctor_omit_inherited_parms_p) + if (omit_inherited_parms_p) { /* If we're omitting inherited parms, that just leaves the VTT. */ - gcc_assert (DECL_NEEDS_VTT_PARM_P (clone)); + gcc_assert (need_vtt_parm_p); parmtypes = tree_cons (NULL_TREE, vtt_parm_type, void_list_node); } TREE_TYPE (clone) @@ -4766,6 +4766,7 @@ copy_fndecl_with_name (tree fn, tree name) /* Copy the function parameters. */ DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone)); + /* Remove the in-charge parameter. */ if (DECL_HAS_IN_CHARGE_PARM_P (clone)) { @@ -4773,10 +4774,11 @@ copy_fndecl_with_name (tree fn, tree name) = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))); DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; } + /* And the VTT parm, in a complete [cd]tor. */ if (DECL_HAS_VTT_PARM_P (fn)) { - if (DECL_NEEDS_VTT_PARM_P (clone)) + if (need_vtt_parm_p) DECL_HAS_VTT_PARM_P (clone) = 1; else { @@ -4788,7 +4790,7 @@ copy_fndecl_with_name (tree fn, tree name) /* A base constructor inheriting from a virtual base doesn't get the arguments. */ - if (ctor_omit_inherited_parms_p) + if (omit_inherited_parms_p) DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE; for (tree parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) @@ -4809,7 +4811,8 @@ copy_fndecl_with_name (tree fn, tree name) tree copy_operator_fn (tree fn, tree_code code) { - return copy_fndecl_with_name (fn, ovl_op_identifier (code)); + return copy_fndecl_with_name (fn, ovl_op_identifier (code), + code, false, false); } /* FN is a constructor or destructor. Clone the declaration to create @@ -4817,7 +4820,8 @@ copy_operator_fn (tree fn, tree_code code) NAME. */ static tree -build_clone (tree fn, tree name) +build_clone (tree fn, tree name, bool need_vtt_parm_p, + bool omit_inherited_parms_p) { tree clone; @@ -4827,7 +4831,8 @@ build_clone (tree fn, tree name) clone = copy_decl (fn); DECL_NAME (clone) = name; - tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name); + tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name, + need_vtt_parm_p, omit_inherited_parms_p); DECL_TEMPLATE_RESULT (clone) = result; DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result)); @@ -4837,7 +4842,8 @@ build_clone (tree fn, tree name) } else { - clone = copy_fndecl_with_name (fn, name); + clone = copy_fndecl_with_name (fn, name, ERROR_MARK, + need_vtt_parm_p, omit_inherited_parms_p); DECL_CLONED_FUNCTION (clone) = fn; } @@ -4856,7 +4862,7 @@ build_clone (tree fn, tree name) will be inserted onto DECL_CHAIN of FN. */ static unsigned -build_cdtor_clones (tree fn) +build_cdtor_clones (tree fn, bool needs_vtt_parm_p, bool omit_inherited_parms_p) { unsigned count = 0; @@ -4864,8 +4870,9 @@ build_cdtor_clones (tree fn) { /* For each constructor, we need two variants: an in-charge version and a not-in-charge version. */ - build_clone (fn, complete_ctor_identifier); - build_clone (fn, base_ctor_identifier); + build_clone (fn, complete_ctor_identifier, false, false); + build_clone (fn, base_ctor_identifier, needs_vtt_parm_p, + omit_inherited_parms_p); count += 2; } else @@ -4883,11 +4890,11 @@ build_cdtor_clones (tree fn) destructor. */ if (DECL_VIRTUAL_P (fn)) { - build_clone (fn, deleting_dtor_identifier); + build_clone (fn, deleting_dtor_identifier, false, false); count++; } - build_clone (fn, complete_dtor_identifier); - build_clone (fn, base_dtor_identifier); + build_clone (fn, complete_dtor_identifier, false, false); + build_clone (fn, base_dtor_identifier, needs_vtt_parm_p, false); count += 2; } @@ -4906,7 +4913,14 @@ clone_cdtor (tree fn, bool update_methods) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn))) return; - unsigned count = build_cdtor_clones (fn); + /* Base cdtors need a vtt parm if there are virtual bases. */ + bool vtt = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)); + + /* Base ctor omits inherited parms it needs a vttparm and inherited + from a virtual nase ctor. */ + bool omit_inherited = ctor_omit_inherited_parms (fn); + + unsigned count = build_cdtor_clones (fn, vtt, omit_inherited); /* Note that this is an abstract function that is never emitted. */ DECL_ABSTRACT_P (fn) = true; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9b31eaf4a07..2aa8ebe64c0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2997,13 +2997,6 @@ struct GTY(()) lang_decl { #define DECL_HAS_VTT_PARM_P(NODE) \ (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p) -/* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is - required. */ -#define DECL_NEEDS_VTT_PARM_P(NODE) \ - (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (NODE)) \ - && (DECL_BASE_CONSTRUCTOR_P (NODE) \ - || DECL_BASE_DESTRUCTOR_P (NODE))) - /* Nonzero if NODE is a user-defined conversion operator. */ #define DECL_CONV_FN_P(NODE) IDENTIFIER_CONV_OP_P (DECL_NAME (NODE))