Do put the VTT parameter in DECL_ARGUMENTS.

* cp-tree.h (struct cp_language_function): Add x_vtt_parm.
        (current_vtt_parm): New macro.
        (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
        (DECL_HAS_VTT_PARM_P): New macro.
        (DECL_VTT_PARM): Remove.
        (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
        * decl.c (duplicate_decls): Only copy the operator code if
        appropriate.
        (start_function): Set current_vtt_parm.
        (lang_mark_tree): Don't mark vtt_parm.
        * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
        DECL_ARGUMENTS.  Set DECL_HAS_VTT_PARM_P.
        * class.c (build_clone): Maybe remove the VTT parm.
        * optimize.c (maybe_clone_body): Set up the VTT parm.
        * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
        * call.c (build_over_call): Just allow the VTT arg.
        * method.c (make_thunk): Don't set DECL_VTT_PARM.
        (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
        (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
        * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
        * error.c (dump_function_decl): Likewise.
        * call.c (build_user_type_conversion_1, convert_like_real): Abort
        if we try to call a constructor with in-charge or VTT parms.
        * method.c (skip_artificial_parms_for): New fn.
        * call.c (add_function_candidate, build_over_call): Call it.
        * call.c (build_new_method_call): Use current_vtt_parm.
        * init.c (expand_virtual_init): Likewise.
        * class.c (same_signature_p): No longer static.
        * cp-tree.h: Declare it.
        * search.c (look_for_overrides_r): Use it.

From-SVN: r39841
This commit is contained in:
Jason Merrill 2001-02-18 14:08:00 -05:00 committed by Jason Merrill
parent 3118975871
commit e0fff4b3a7
12 changed files with 195 additions and 132 deletions

View File

@ -1,3 +1,37 @@
2001-02-18 Jason Merrill <jason@redhat.com>
Do put the VTT parameter in DECL_ARGUMENTS.
* cp-tree.h (struct cp_language_function): Add x_vtt_parm.
(current_vtt_parm): New macro.
(struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
(DECL_HAS_VTT_PARM_P): New macro.
(DECL_VTT_PARM): Remove.
(FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
* decl.c (duplicate_decls): Only copy the operator code if
appropriate.
(start_function): Set current_vtt_parm.
(lang_mark_tree): Don't mark vtt_parm.
* decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
DECL_ARGUMENTS. Set DECL_HAS_VTT_PARM_P.
* class.c (build_clone): Maybe remove the VTT parm.
* optimize.c (maybe_clone_body): Set up the VTT parm.
* pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
* call.c (build_over_call): Just allow the VTT arg.
* method.c (make_thunk): Don't set DECL_VTT_PARM.
(do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
(synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
* decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
* error.c (dump_function_decl): Likewise.
* call.c (build_user_type_conversion_1, convert_like_real): Abort
if we try to call a constructor with in-charge or VTT parms.
* method.c (skip_artificial_parms_for): New fn.
* call.c (add_function_candidate, build_over_call): Call it.
* call.c (build_new_method_call): Use current_vtt_parm.
* init.c (expand_virtual_init): Likewise.
* class.c (same_signature_p): No longer static.
* cp-tree.h: Declare it.
* search.c (look_for_overrides_r): Use it.
2001-02-17 Mark Mitchell <mark@codesourcery.com>
* init.c (build_new): Allow enumeration types for the array-bounds

View File

@ -1305,17 +1305,12 @@ add_function_candidate (candidates, fn, ctype, arglist, flags)
tree parmnode, argnode;
int viable = 1;
/* The `this' and `in_chrg' arguments to constructors are not considered
in overload resolution. */
/* The `this', `in_chrg' and VTT arguments to constructors are not
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
if (DECL_HAS_IN_CHARGE_PARM_P (fn))
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
}
parmlist = skip_artificial_parms_for (fn, parmlist);
arglist = skip_artificial_parms_for (fn, arglist);
}
len = list_length (arglist);
@ -2382,10 +2377,11 @@ build_user_type_conversion_1 (totype, expr, flags)
t = build_int_2 (0, 0);
TREE_TYPE (t) = build_pointer_type (totype);
args = build_tree_list (NULL_TREE, expr);
if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)))
args = tree_cons (NULL_TREE,
in_charge_arg_for_name (complete_ctor_identifier),
args);
if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
|| DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)))
/* We should never try to call the abstract or base constructor
from here. */
abort ();
args = tree_cons (NULL_TREE, t, args);
}
for (; ctors; ctors = OVL_NEXT (ctors))
@ -3735,8 +3731,11 @@ convert_like_real (convs, expr, fn, argnum, inner)
TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
args = build_tree_list (NULL_TREE, expr);
if (DECL_HAS_IN_CHARGE_PARM_P (convfn))
args = tree_cons (NULL_TREE, integer_one_node, args);
if (DECL_HAS_IN_CHARGE_PARM_P (convfn)
|| DECL_HAS_VTT_PARM_P (convfn))
/* We should never try to call the abstract or base constructor
from here. */
abort ();
args = tree_cons (NULL_TREE, t, args);
}
else
@ -4065,6 +4064,9 @@ build_over_call (cand, args, flags)
arg = TREE_CHAIN (arg);
parm = TREE_CHAIN (parm);
if (DECL_HAS_IN_CHARGE_PARM_P (fn))
/* We should never try to call the abstract constructor. */
abort ();
if (DECL_HAS_VTT_PARM_P (fn))
{
converted_args = tree_cons
(NULL_TREE, TREE_VALUE (arg), converted_args);
@ -4169,9 +4171,7 @@ build_over_call (cand, args, flags)
&& DECL_COPY_CONSTRUCTOR_P (fn))
{
tree targ;
arg = TREE_CHAIN (converted_args);
if (DECL_HAS_IN_CHARGE_PARM_P (fn))
arg = TREE_CHAIN (arg);
arg = skip_artificial_parms_for (fn, converted_args);
arg = TREE_VALUE (arg);
/* Pull out the real argument, disregarding const-correctness. */
@ -4439,7 +4439,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
vtt = build (COND_EXPR, TREE_TYPE (vtt),
build (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
DECL_VTT_PARM (current_function_decl),
current_vtt_parm,
vtt);
if (TREE_VIA_VIRTUAL (basebinfo))
basebinfo = binfo_for_vbase (basetype, current_class_type);

View File

@ -119,7 +119,6 @@ static void delete_duplicate_fields PARAMS ((tree));
static void finish_struct_bits PARAMS ((tree));
static int alter_access PARAMS ((tree, tree, tree));
static void handle_using_decl PARAMS ((tree, tree));
static int same_signature_p PARAMS ((tree, tree));
static int strictly_overrides PARAMS ((tree, tree));
static void mark_overriders PARAMS ((tree, tree));
static void check_for_override PARAMS ((tree, tree));
@ -2460,7 +2459,7 @@ layout_vtable_decl (binfo, n)
/* True iff FNDECL and BASE_FNDECL (both non-static member functions)
have the same signature. */
static int
int
same_signature_p (fndecl, base_fndecl)
tree fndecl, base_fndecl;
{
@ -4188,8 +4187,6 @@ build_clone (fn, name)
DECL_PENDING_INLINE_P (clone) = 0;
/* And it hasn't yet been deferred. */
DECL_DEFERRED_FN (clone) = 0;
/* There's no magic VTT parameter in the clone. */
DECL_VTT_PARM (clone) = NULL_TREE;
/* The base-class destructor is not virtual. */
if (name == base_dtor_identifier)
@ -4214,10 +4211,12 @@ build_clone (fn, name)
parmtypes = TREE_CHAIN (parmtypes);
/* 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))
parmtypes = TREE_CHAIN (parmtypes);
/* If this is subobject constructor or destructor, add the vtt
parameter. */
if (DECL_NEEDS_VTT_PARM_P (clone))
parmtypes = hash_tree_chain (vtt_parm_type, parmtypes);
TREE_TYPE (clone)
= build_cplus_method_type (basetype,
TREE_TYPE (TREE_TYPE (clone)),
@ -4227,8 +4226,8 @@ build_clone (fn, name)
exceptions);
}
/* Copy the function parameters. But, DECL_ARGUMENTS aren't
function parameters; instead, those are the template parameters. */
/* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL
aren't function parameters; those are the template parameters. */
if (TREE_CODE (clone) != TEMPLATE_DECL)
{
DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
@ -4239,16 +4238,17 @@ build_clone (fn, name)
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
}
/* Add the VTT parameter. */
if (DECL_NEEDS_VTT_PARM_P (clone))
/* And the VTT parm, in a complete [cd]tor. */
if (DECL_HAS_VTT_PARM_P (fn))
{
tree parm;
parm = build_artificial_parm (vtt_parm_identifier,
vtt_parm_type);
TREE_CHAIN (parm) = TREE_CHAIN (DECL_ARGUMENTS (clone));
TREE_CHAIN (DECL_ARGUMENTS (clone)) = parm;
if (DECL_NEEDS_VTT_PARM_P (clone))
DECL_HAS_VTT_PARM_P (clone) = 1;
else
{
TREE_CHAIN (DECL_ARGUMENTS (clone))
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_VTT_PARM_P (clone) = 0;
}
}
for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))

View File

@ -881,6 +881,7 @@ struct cp_language_function
tree x_current_class_ref;
tree x_eh_spec_try_block;
tree x_in_charge_parm;
tree x_vtt_parm;
tree *x_vcalls_possible_p;
@ -927,10 +928,15 @@ struct cp_language_function
#define current_eh_spec_try_block cp_function_chain->x_eh_spec_try_block
/* The `__in_chrg' parameter for the current function. Only used for
destructors. */
constructors and destructors. */
#define current_in_charge_parm cp_function_chain->x_in_charge_parm
/* The `__vtt_parm' parameter for the current function. Only used for
constructors and destructors. */
#define current_vtt_parm cp_function_chain->x_vtt_parm
/* In destructors, this is a pointer to a condition in an
if-statement. If the pointed-to value is boolean_true_node, then
there may be virtual function calls in this destructor. */
@ -1249,7 +1255,18 @@ enum languages { lang_c, lang_cplusplus, lang_java };
? (ENTRY) \
: DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
#define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
#define FUNCTION_ARG_CHAIN(NODE) \
(TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
which refers to a user-written parameter. */
#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
(skip_artificial_parms_for (NODE, TYPE_ARG_TYPES (TREE_TYPE (NODE))))
/* Similarly, but for DECL_ARGUMENTS. */
#define FUNCTION_FIRST_USER_PARM(NODE) \
(skip_artificial_parms_for (NODE, DECL_ARGUMENTS (NODE)))
#define PROMOTES_TO_AGGR_TYPE(NODE,CODE) \
(((CODE) == TREE_CODE (NODE) \
&& IS_AGGR_TYPE (TREE_TYPE (NODE))) \
@ -1825,7 +1842,7 @@ struct lang_decl_flags
unsigned assignment_operator_p : 1;
unsigned anticipated_p : 1;
unsigned generate_with_vtable_p : 1;
unsigned dummy : 1;
unsigned has_vtt_parm_p : 1;
union {
/* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
@ -1876,9 +1893,6 @@ struct lang_decl
/* In an overloaded operator, this is the value of
DECL_OVERLOADED_OPERATOR_P. */
enum tree_code operator_code;
/* In a maybe-in-charge constructor or destructor, this is
DECL_VTT_PARM. */
tree vtt_parm;
} u2;
};
@ -1978,10 +1992,9 @@ struct lang_decl
#define DECL_CLONED_FUNCTION(NODE) \
(DECL_LANG_SPECIFIC (NODE)->cloned_function)
/* In a maybe-in-charge constructor or destructor, this is the VTT
parameter. It's not actually on the DECL_ARGUMENTS list. */
#define DECL_VTT_PARM(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u2.vtt_parm)
/* Non-zero if the VTT parm has been added to NODE. */
#define DECL_HAS_VTT_PARM_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p)
/* Non-zero if NODE is a FUNCTION_DECL for which a VTT parameter is
required. */
@ -3723,6 +3736,7 @@ extern void pop_lang_context PARAMS ((void));
extern tree instantiate_type PARAMS ((tree, tree, enum instantiate_type_flags));
extern void print_class_statistics PARAMS ((void));
extern void build_self_reference PARAMS ((void));
extern int same_signature_p PARAMS ((tree, tree));
extern void warn_hidden PARAMS ((tree));
extern tree get_enclosing_class PARAMS ((tree));
int is_base_of_enclosing_class PARAMS ((tree, tree));
@ -4085,6 +4099,7 @@ extern tree make_thunk PARAMS ((tree, tree, tree, int));
extern void use_thunk PARAMS ((tree, int));
extern void synthesize_method PARAMS ((tree));
extern tree implicitly_declare_fn PARAMS ((special_function_kind, tree, int));
extern tree skip_artificial_parms_for PARAMS ((tree, tree));
/* In optimize.c */
extern void optimize_function PARAMS ((tree));

View File

@ -3399,7 +3399,9 @@ duplicate_decls (newdecl, olddecl)
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
SET_OVERLOADED_OPERATOR_CODE
(newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
/* Optionally warn about more than one declaration for the same
@ -11300,15 +11302,8 @@ friend declaration requires class-key, i.e. `friend %#T'",
/* The constructor can be called with exactly one
parameter if there is at least one parameter, and
any subsequent parameters have default arguments.
We don't look at the first parameter, which is
really just the `this' parameter for the new
object. */
tree arg_types =
TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
/* Skip the `in_chrg' argument too, if present. */
if (DECL_HAS_IN_CHARGE_PARM_P (decl))
arg_types = TREE_CHAIN (arg_types);
Ignore any compiler-added parms. */
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
if (arg_types == void_list_node
|| (arg_types
@ -11923,9 +11918,7 @@ copy_args_p (d)
if (!DECL_FUNCTION_MEMBER_P (d))
return 0;
t = FUNCTION_ARG_CHAIN (d);
if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
t = TREE_CHAIN (t);
t = FUNCTION_FIRST_USER_PARMTYPE (d);
if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
== DECL_CONTEXT (d))
@ -11948,22 +11941,9 @@ int
grok_ctor_properties (ctype, decl)
tree ctype, decl;
{
tree parmtypes = FUNCTION_ARG_CHAIN (decl);
tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
/* When a type has virtual baseclasses, a magical first int argument is
added to any ctor so we can tell if the class has been initialized
yet. This could screw things up in this function, so we deliberately
ignore the leading int if we're in that situation. */
if (DECL_HAS_IN_CHARGE_PARM_P (decl))
{
my_friendly_assert (parmtypes
&& TREE_VALUE (parmtypes) == integer_type_node,
980529);
parmtypes = TREE_CHAIN (parmtypes);
parmtype = TREE_VALUE (parmtypes);
}
/* [class.copy]
A non-template constructor for class X is a copy constructor if
@ -13473,8 +13453,18 @@ start_function (declspecs, declarator, attrs, flags)
/* Constructors and destructors need to know whether they're "in
charge" of initializing virtual base classes. */
t = TREE_CHAIN (t);
if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
current_in_charge_parm = TREE_CHAIN (t);
{
current_in_charge_parm = t;
t = TREE_CHAIN (t);
}
if (DECL_HAS_VTT_PARM_P (decl1))
{
if (DECL_NAME (t) != vtt_parm_identifier)
abort ();
current_vtt_parm = t;
}
}
if (DECL_INTERFACE_KNOWN (decl1))
@ -14425,8 +14415,6 @@ lang_mark_tree (t)
ggc_mark_tree (ld->befriending_classes);
ggc_mark_tree (ld->context);
ggc_mark_tree (ld->cloned_function);
if (!DECL_OVERLOADED_OPERATOR_P (t))
ggc_mark_tree (ld->u2.vtt_parm);
if (TREE_CODE (t) == TYPE_DECL)
ggc_mark_tree (ld->u.sorted_fields);
else if (TREE_CODE (t) == FUNCTION_DECL

View File

@ -932,7 +932,10 @@ build_artificial_parm (name, type)
This function adds the "in-charge" flag to member function FN if
appropriate. It is called from grokclassfn and tsubst.
FN must be either a constructor or destructor. */
FN must be either a constructor or destructor.
The in-charge flag follows the 'this' parameter, and is followed by the
VTT parm (if any), then the user-written parms. */
void
maybe_retrofit_in_chrg (fn)
@ -955,17 +958,38 @@ maybe_retrofit_in_chrg (fn)
&& !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
return;
/* First add it to DECL_ARGUMENTS... */
parm = build_artificial_parm (in_charge_identifier, integer_type_node);
TREE_READONLY (parm) = 1;
parms = DECL_ARGUMENTS (fn);
TREE_CHAIN (parm) = TREE_CHAIN (parms);
TREE_CHAIN (parms) = parm;
/* ...and then to TYPE_ARG_TYPES. */
arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
basetype = TREE_TYPE (TREE_VALUE (arg_types));
arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types));
arg_types = TREE_CHAIN (arg_types);
parms = TREE_CHAIN (DECL_ARGUMENTS (fn));
/* If this is a subobject constructor or destructor, our caller will
pass us a pointer to our VTT. */
if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
/* First add it to DECL_ARGUMENTS between 'this' and the real args... */
TREE_CHAIN (parm) = parms;
parms = parm;
/* ...and then to TYPE_ARG_TYPES. */
arg_types = hash_tree_chain (vtt_parm_type, arg_types);
DECL_HAS_VTT_PARM_P (fn) = 1;
}
/* Then add the in-charge parm (before the VTT parm). */
parm = build_artificial_parm (in_charge_identifier, integer_type_node);
TREE_CHAIN (parm) = parms;
parms = parm;
arg_types = hash_tree_chain (integer_type_node, arg_types);
/* Insert our new parameter(s) into the list. */
TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
/* And rebuild the function type. */
fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
arg_types);
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
@ -975,15 +999,6 @@ maybe_retrofit_in_chrg (fn)
/* Now we've got the in-charge parameter. */
DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
/* If this is a subobject constructor or destructor, our caller will
pass us a pointer to our VTT. */
if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
DECL_VTT_PARM (fn) = build_artificial_parm (vtt_parm_identifier,
vtt_parm_type);
DECL_CONTEXT (DECL_VTT_PARM (fn)) = fn;
}
}
/* Classes overload their constituent function names automatically.

View File

@ -1203,7 +1203,7 @@ dump_function_decl (t, flags)
}
fntype = TREE_TYPE (t);
parmtypes = TYPE_ARG_TYPES (fntype);
parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
if (DECL_CLASS_SCOPE_P (t))
cname = DECL_CONTEXT (t);
@ -1241,14 +1241,6 @@ dump_function_decl (t, flags)
if (flags & TFF_DECL_SPECIFIERS)
{
if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
/* Skip "this" parameter. */
parmtypes = TREE_CHAIN (parmtypes);
/* Skip past the "in_charge" parameter. */
if (DECL_HAS_IN_CHARGE_PARM_P (t))
parmtypes = TREE_CHAIN (parmtypes);
dump_parameters (parmtypes, flags);
if (show_return)

View File

@ -860,7 +860,7 @@ expand_virtual_init (binfo, decl)
tree vtt_parm;
/* Compute the value to use, when there's a VTT. */
vtt_parm = DECL_VTT_PARM (current_function_decl);
vtt_parm = current_vtt_parm;
vtbl2 = build (PLUS_EXPR,
TREE_TYPE (vtt_parm),
vtt_parm,

View File

@ -364,7 +364,6 @@ make_thunk (function, delta, vcall_index, generate_with_vtable_p)
DECL_CONSTRUCTOR_P (thunk) = 0;
DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1;
DECL_VTT_PARM (thunk) = NULL_TREE;
/* Even if this thunk is a member of a local class, we don't
need a static chain. */
DECL_NO_STATIC_CHAIN (thunk) = 1;
@ -536,11 +535,9 @@ static void
do_build_copy_constructor (fndecl)
tree fndecl;
{
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
tree t;
if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
parm = TREE_CHAIN (parm);
parm = convert_from_reference (parm);
if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
@ -760,9 +757,7 @@ synthesize_method (fndecl)
setup_vtbl_ptr (NULL_TREE, NULL_TREE);
else
{
tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
arg_chain = TREE_CHAIN (arg_chain);
tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
if (arg_chain != void_list_node)
do_build_copy_constructor (fndecl);
else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
@ -1041,3 +1036,22 @@ implicitly_declare_fn (kind, type, const_p)
return fn;
}
/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
as there are artificial parms in FN. */
tree
skip_artificial_parms_for (fn, list)
tree fn, list;
{
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
list = TREE_CHAIN (list);
else
return list;
if (DECL_HAS_IN_CHARGE_PARM_P (fn))
list = TREE_CHAIN (list);
if (DECL_HAS_VTT_PARM_P (fn))
list = TREE_CHAIN (list);
return list;
}

View File

@ -981,22 +981,25 @@ maybe_clone_body (fn)
splay_tree_insert (id.decl_map,
(splay_tree_key) parm,
(splay_tree_value) in_charge);
}
else if (DECL_ARTIFICIAL (parm)
&& DECL_NAME (parm) == vtt_parm_identifier)
{
/* For a subobject constructor or destructor, the next
argument is the VTT parameter. Remap the VTT_PARM
from the CLONE to this parameter. */
if (DECL_NEEDS_VTT_PARM_P (clone))
if (DECL_HAS_VTT_PARM_P (clone))
{
splay_tree_insert (id.decl_map,
(splay_tree_key) DECL_VTT_PARM (fn),
(splay_tree_key) parm,
(splay_tree_value) clone_parm);
clone_parm = TREE_CHAIN (clone_parm);
}
/* Otherwise, map the VTT parameter to `NULL'. */
else if (DECL_VTT_PARM (fn))
else
{
splay_tree_insert (id.decl_map,
(splay_tree_key) DECL_VTT_PARM (fn),
(splay_tree_key) parm,
(splay_tree_value) null_pointer_node);
}
}

View File

@ -1208,6 +1208,7 @@ copy_default_args_to_explicit_spec (decl)
tree t;
tree object_type = NULL_TREE;
tree in_charge = NULL_TREE;
tree vtt = NULL_TREE;
/* See if there's anything we need to do. */
tmpl = DECL_TI_TEMPLATE (decl);
@ -1236,6 +1237,11 @@ copy_default_args_to_explicit_spec (decl)
in_charge = spec_types;
spec_types = TREE_CHAIN (spec_types);
}
if (DECL_HAS_VTT_PARM_P (decl))
{
vtt = spec_types;
spec_types = TREE_CHAIN (spec_types);
}
}
/* Compute the merged default arguments. */
@ -1245,6 +1251,11 @@ copy_default_args_to_explicit_spec (decl)
/* Compute the new FUNCTION_TYPE. */
if (object_type)
{
if (vtt)
new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
TREE_VALUE (vtt),
new_spec_types);
if (in_charge)
/* Put the in-charge parameter back. */
new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),

View File

@ -2046,22 +2046,13 @@ look_for_overrides_r (type, fndecl)
return 1;
}
}
else
else if (same_signature_p (fndecl, fn))
{
if (/* The first parameter is the `this' parameter,
which has POINTER_TYPE, and we can therefore
safely use TYPE_QUALS, rather than
CP_TYPE_QUALS. */
(TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
== TYPE_QUALS (thistype))
&& compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
{
/* It's definitely virtual, even if not explicitly set. */
DECL_VIRTUAL_P (fndecl) = 1;
check_final_overrider (fndecl, fn);
return 1;
}
/* It's definitely virtual, even if not explicitly set. */
DECL_VIRTUAL_P (fndecl) = 1;
check_final_overrider (fndecl, fn);
return 1;
}
}
}