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.
This commit is contained in:
parent
0d7e5fa655
commit
27aebb7d6c
@ -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;
|
||||
|
@ -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))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user