aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2001-02-18 14:08:00 -0500
committerJason Merrill <jason@gcc.gnu.org>2001-02-18 14:08:00 -0500
commite0fff4b3a7312cd08165c9a010dbafc1a4c98316 (patch)
tree78833bf4bd67d918c1690aabd6f664e5a2d426ff /gcc
parent31189758710a6ea118e5f8a65aad04ea5ef968fd (diff)
downloadgcc-e0fff4b3a7312cd08165c9a010dbafc1a4c98316.zip
gcc-e0fff4b3a7312cd08165c9a010dbafc1a4c98316.tar.gz
gcc-e0fff4b3a7312cd08165c9a010dbafc1a4c98316.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/call.c38
-rw-r--r--gcc/cp/class.c34
-rw-r--r--gcc/cp/cp-tree.h35
-rw-r--r--gcc/cp/decl.c48
-rw-r--r--gcc/cp/decl2.c53
-rw-r--r--gcc/cp/error.c10
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/method.c28
-rw-r--r--gcc/cp/optimize.c13
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/search.c21
12 files changed, 195 insertions, 132 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 99dfb50..b94cd78 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 184ffeb..b7e6e94 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 55bac37..7c210210 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f35dd95..f7ed02c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4e727ad..3b38d68 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 20aa6a8..37e6d4a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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.
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 3091236..0ec7405 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 68139d8..4d498aa 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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,
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index ccaec60..349afcb 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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;
+}
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 442cac0..9d700f6 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -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);
}
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b28c60a..ab420b5 100644
--- a/gcc/cp/pt.c
+++ b/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),
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 75d33e8..6b13469 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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;
}
}
}