diff options
-rw-r--r-- | gcc/cp/ChangeLog | 34 | ||||
-rw-r--r-- | gcc/cp/call.c | 38 | ||||
-rw-r--r-- | gcc/cp/class.c | 34 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 35 | ||||
-rw-r--r-- | gcc/cp/decl.c | 48 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 53 | ||||
-rw-r--r-- | gcc/cp/error.c | 10 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/method.c | 28 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 13 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/cp/search.c | 21 |
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; } } } |