mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 09:37:02 +08:00
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:
parent
3118975871
commit
e0fff4b3a7
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
11
gcc/cp/pt.c
11
gcc/cp/pt.c
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user