diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ad77934cfd..95077ca7b47 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,28 @@ 2000-04-11 Mark Mitchell + * cp-tree.h (lang_decl_flags): Rename constructor_for_vbase_attr + to has_in_charge_parm_p. + (DECL_CONSTRUCTOR_FOR_VBASE_P): Rename to ... + (DECL_HAS_IN_CHARGE_PARM_P): ... this. + (DECL_COPY_CONSTRUCTOR_P): New macro. + * call.c (add_function_candidate): Use DECL_HAS_IN_CHARGE_PARM_P. + (build_user_type_conversion_1): Likewise. + (convert_like_real): Likewise. + (build_over_call): Likeiwse. Use DECL_COPY_CONSTRUCTOR_P. + * decl.c (grokdeclarator): Use DECL_HAS_IN_CHARGE_PARM_P. + (copy_args_p): Likewise. + (grok_ctor_properties): Likewise. + (start_function): Likewise. + * decl2.c (maybe_retrofit_in_charge): Likewise. Set it. + * error.c (dump_function_decl): Use DECL_HAS_IN_CHARGE_PARM_P. + * init.c (emit_base_init): Use DECL_COPY_CONSTRUCTOR_P. + * method.c (do_build_copy_constructor): Use + DECL_HAS_IN_CHARGE_PARM_P. + (synthesize_method): Likewise. + * pt.c (instantiate_template): Remove goto. + * tree.c (build_cplus_method_type): Remove mention of obstacks in + comment. + * cp-tre.h (finish_function): Change prototype. * decl.c (end_cleanup_fn): Adjust caller. (finish_function): Take only one parameter. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 83eaac27cd2..040801b76ec 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1265,7 +1265,7 @@ add_function_candidate (candidates, fn, ctype, arglist, flags) { parmlist = TREE_CHAIN (parmlist); arglist = TREE_CHAIN (arglist); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + if (DECL_HAS_IN_CHARGE_PARM_P (fn)) { parmlist = TREE_CHAIN (parmlist); arglist = TREE_CHAIN (arglist); @@ -2287,14 +2287,16 @@ build_user_type_conversion_1 (totype, expr, flags) if (ctors) { - tree t = build_int_2 (0, 0); - TREE_TYPE (t) = build_pointer_type (totype); - args = build_tree_list (NULL_TREE, expr); - if (TYPE_USES_VIRTUAL_BASECLASSES (totype)) - args = tree_cons (NULL_TREE, integer_one_node, args); - args = tree_cons (NULL_TREE, t, args); + tree t; ctors = TREE_VALUE (ctors); + + 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, integer_one_node, args); + args = tree_cons (NULL_TREE, t, args); } for (; ctors; ctors = OVL_NEXT (ctors)) { @@ -3658,7 +3660,7 @@ convert_like_real (convs, expr, fn, argnum, inner) TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn)); args = build_tree_list (NULL_TREE, expr); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + if (DECL_HAS_IN_CHARGE_PARM_P (fn)) args = tree_cons (NULL_TREE, integer_one_node, args); args = tree_cons (NULL_TREE, t, args); } @@ -3930,7 +3932,7 @@ build_over_call (cand, args, flags) converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args); arg = TREE_CHAIN (arg); parm = TREE_CHAIN (parm); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + if (DECL_HAS_IN_CHARGE_PARM_P (fn)) { converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args); @@ -4031,13 +4033,12 @@ build_over_call (cand, args, flags) if (! flag_elide_constructors) /* Do things the hard way. */; - else if (DECL_CONSTRUCTOR_P (fn) - && TREE_VEC_LENGTH (convs) == 1 - && copy_args_p (fn)) + else if (TREE_VEC_LENGTH (convs) == 1 + && DECL_COPY_CONSTRUCTOR_P (fn)) { tree targ; arg = TREE_CHAIN (converted_args); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + if (DECL_HAS_IN_CHARGE_PARM_P (fn)) arg = TREE_CHAIN (arg); arg = TREE_VALUE (arg); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b556236b1df..b9fa50e7424 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1834,7 +1834,7 @@ struct lang_decl_flags unsigned const_memfunc : 1; unsigned volatile_memfunc : 1; unsigned pure_virtual : 1; - unsigned constructor_for_vbase_attr : 1; + unsigned has_in_charge_parm_p : 1; unsigned mutable_flag : 1; unsigned deferred : 1; @@ -1909,6 +1909,10 @@ struct lang_decl /* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr) +/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */ +#define DECL_COPY_CONSTRUCTOR_P(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) && copy_args_p (NODE)) + /* There ought to be a better way to find out whether or not something is a destructor. */ #define DECL_DESTRUCTOR_P(NODE) \ @@ -1923,9 +1927,11 @@ struct lang_decl #define DECL_OVERLOADED_OPERATOR_P(NODE) \ (IDENTIFIER_OPNAME_P (DECL_NAME ((NODE)))) -/* For FUNCTION_DECLs: nonzero means that this function is a constructor - for an object with virtual baseclasses. */ -#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) +/* For FUNCTION_DECLs: nonzero means that this function is a + constructor or a destructor with an extra in-charge parameter to + control whether or not virtual bases are constructed. */ +#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p) /* Non-zero for a FUNCTION_DECL that declares a type-info function. This only happens in the old abi. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 85ab135eaa8..a07cb3acad4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11250,7 +11250,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))); /* Skip the `in_chrg' argument too, if present. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl))) + if (DECL_HAS_IN_CHARGE_PARM_P (decl)) arg_types = TREE_CHAIN (arg_types); if (arg_types == void_list_node @@ -11968,8 +11968,7 @@ copy_args_p (d) return 0; t = FUNCTION_ARG_CHAIN (d); - if (DECL_CONSTRUCTOR_P (d) - && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d))) + if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d)) t = TREE_CHAIN (t); if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t))) @@ -12000,7 +11999,7 @@ grok_ctor_properties (ctype, decl) 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 (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) + if (DECL_HAS_IN_CHARGE_PARM_P (decl)) { my_friendly_assert (parmtypes && TREE_VALUE (parmtypes) == integer_type_node, @@ -13444,8 +13443,7 @@ start_function (declspecs, declarator, attrs, flags) /* Constructors and destructors need to know whether they're "in charge" of initializing virtual base classes. */ - if (DECL_CONSTRUCTOR_FOR_VBASE_P (decl1) - || DECL_DESTRUCTOR_P (decl1)) + if (DECL_HAS_IN_CHARGE_PARM_P (decl1)) current_in_charge_parm = TREE_CHAIN (t); } @@ -13925,9 +13923,6 @@ finish_destructor_body () all the way to assembler language output. The free the storage for the function definition. - This is called after parsing the body of the function definition. - LINENO is the current line number. - FLAGS is a bitwise or of the following values: 1 - CALL_POPLEVEL An extra call to poplevel (and expand_end_bindings) must be diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 07f2d545faf..3e0a9df8c39 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -929,18 +929,15 @@ maybe_retrofit_in_chrg (fn) { tree basetype, arg_types, parms, parm, fntype; - if (DECL_CONSTRUCTOR_P (fn) - && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)) - && ! DECL_CONSTRUCTOR_FOR_VBASE_P (fn)) - /* OK */; - else if (! DECL_CONSTRUCTOR_P (fn) - && TREE_CHAIN (DECL_ARGUMENTS (fn)) == NULL_TREE) - /* OK */; - else + /* If we've already add the in-charge parameter don't do it again. */ + if (DECL_HAS_IN_CHARGE_PARM_P (fn)) return; - if (DECL_CONSTRUCTOR_P (fn)) - DECL_CONSTRUCTOR_FOR_VBASE_P (fn) = 1; + /* We don't need an in-charge parameter for constructors that don't + have virtual bases. */ + if (DECL_CONSTRUCTOR_P (fn) + && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + return; /* First add it to DECL_ARGUMENTS... */ parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); @@ -962,6 +959,9 @@ maybe_retrofit_in_chrg (fn) fntype = build_exception_variant (fntype, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))); TREE_TYPE (fn) = fntype; + + /* Now we've got the in-charge parameter. */ + DECL_HAS_IN_CHARGE_PARM_P (fn) = 1; } /* Classes overload their constituent function names automatically. diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 5600176d1c0..8f0fdf346e6 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1169,8 +1169,8 @@ dump_function_decl (t, flags) /* Skip "this" parameter. */ parmtypes = TREE_CHAIN (parmtypes); - if (DECL_DESTRUCTOR_P (t) || DECL_CONSTRUCTOR_FOR_VBASE_P (t)) - /* Skip past "in_charge" identifier. */ + /* Skip past the "in_charge" parameter. */ + if (DECL_HAS_IN_CHARGE_PARM_P (t)) parmtypes = TREE_CHAIN (parmtypes); dump_parameters (parmtypes, flags); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5d9b968db1b..d94c69c635b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -564,7 +564,8 @@ emit_base_init (t) else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) { init = NULL_TREE; - if (extra_warnings && copy_args_p (current_function_decl)) + if (extra_warnings + && DECL_COPY_CONSTRUCTOR_P (current_function_decl)) cp_warning ("base class `%#T' should be explicitly initialized in the copy constructor", BINFO_TYPE (base_binfo)); } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 010469d6d02..c5e4805d7d9 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -2179,7 +2179,7 @@ do_build_copy_constructor (fndecl) tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); tree t; - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + if (DECL_HAS_IN_CHARGE_PARM_P (fndecl)) parm = TREE_CHAIN (parm); parm = convert_from_reference (parm); @@ -2388,7 +2388,7 @@ synthesize_method (fndecl) else { tree arg_chain = FUNCTION_ARG_CHAIN (fndecl); - if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl)) + if (DECL_HAS_IN_CHARGE_PARM_P (fndecl)) arg_chain = TREE_CHAIN (arg_chain); if (arg_chain != void_list_node) do_build_copy_constructor (fndecl); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6bb482ad13f..0e3277e6d94 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7420,8 +7420,7 @@ instantiate_template (tmpl, targ_ptr) { cp_error ("type `%T' composed from a local class is not a valid template-argument", t); cp_error (" trying to instantiate `%D'", gen_tmpl); - fndecl = error_mark_node; - goto out; + return error_mark_node; } } } @@ -7436,7 +7435,6 @@ instantiate_template (tmpl, targ_ptr) if (flag_external_templates) add_pending_template (fndecl); - out: return fndecl; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index db3c418d520..77973d6d59d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -460,9 +460,7 @@ build_cplus_method_type (basetype, rettype, argtypes) ptype = build_pointer_type (basetype); /* The actual arglist for this function includes a "hidden" argument - which is "this". Put it into the list of argument types. Make - sure that the new argument list is allocated on the same obstack - as the type. */ + which is "this". Put it into the list of argument types. */ argtypes = tree_cons (NULL_TREE, ptype, argtypes); TYPE_ARG_TYPES (t) = argtypes; TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */