diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-05-29 02:33:54 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-05-29 02:33:54 +0000 |
commit | e46cb6639b7e7c3b80ba0e21683a6591fe462354 (patch) | |
tree | 25e2c12ee0d8b3ffa267282b86a0afbbe7af373e | |
parent | 2d9da7e153115324b70e529abf5bd4e9f18cc8c3 (diff) | |
download | gcc-e46cb6639b7e7c3b80ba0e21683a6591fe462354.tar.gz |
* cp-tree.h (DECL_DESTRUCTOR_P): New macro.
* method.c (build_destructor_name): New fn.
* decl2.c (maybe_retrofit_in_chrg): Split out...
(grokclassfn): From here. Reorganize.
* decl.c (grok_ctor_properties): Make sure ctors for types with
vbases have the in_chrg parm.
* pt.c (instantiate_class_template): Update
TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call
grok_*_properties.
(tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg.
* pt.c (instantiate_decl): Make test for whether or not static
variables should be instantiated early match its comment.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20136 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 7 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 149 | ||||
-rw-r--r-- | gcc/cp/method.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 80 |
6 files changed, 144 insertions, 124 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 684c2af544e..ea4e5fb1726 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +1998-05-29 Jason Merrill <jason@yorick.cygnus.com> + + * cp-tree.h (DECL_DESTRUCTOR_P): New macro. + * method.c (build_destructor_name): New fn. + * decl2.c (maybe_retrofit_in_chrg): Split out... + (grokclassfn): From here. Reorganize. + * decl.c (grok_ctor_properties): Make sure ctors for types with + vbases have the in_chrg parm. + * pt.c (instantiate_class_template): Update + TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call + grok_*_properties. + (tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg. + +1998-05-28 Mark Mitchell <mark@markmitchell.com> + + * pt.c (instantiate_decl): Make test for whether or not static + variables should be instantiated early match its comment. + 1998-05-28 Jason Merrill <jason@yorick.cygnus.com> * decl.c (start_decl): Always pedwarn about vacuously redeclaring diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 129047a5d16..2c7917b2a6a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1087,6 +1087,8 @@ 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) +#define DECL_DESTRUCTOR_P(NODE) (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_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) @@ -2396,6 +2398,7 @@ extern int lang_decode_option PROTO((char *)); extern tree grok_method_quals PROTO((tree, tree, tree)); extern void warn_if_unknown_interface PROTO((tree)); extern tree grok_x_components PROTO((tree, tree)); +extern void maybe_retrofit_in_chrg PROTO((tree)); extern void grokclassfn PROTO((tree, tree, tree, enum overload_flags, tree)); extern tree grok_alignof PROTO((tree)); extern tree grok_array_decl PROTO((tree, tree)); @@ -2584,6 +2587,7 @@ extern tree build_decl_overload PROTO((tree, tree, int)); extern tree build_template_decl_overload PROTO((tree, tree, tree, tree, tree, int)); extern tree build_typename_overload PROTO((tree)); extern tree build_overload_with_type PROTO((tree, tree)); +extern tree build_destructor_name PROTO((tree)); extern tree build_opfncall PROTO((enum tree_code, int, tree, tree, tree)); extern tree hack_identifier PROTO((tree, tree)); extern tree make_thunk PROTO((tree, int)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e3d1dd1a4ad..d61642c1402 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10606,10 +10606,11 @@ 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 (parmtypes - && TREE_VALUE (parmtypes) == integer_type_node - && TYPE_USES_VIRTUAL_BASECLASSES (ctype)) + if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) { + my_friendly_assert (parmtypes + && TREE_VALUE (parmtypes) == integer_type_node, + 980529); parmtypes = TREE_CHAIN (parmtypes); parmtype = TREE_VALUE (parmtypes); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 9fb08acb6bf..5f4d5e9bcf8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -958,6 +958,57 @@ grok_x_components (specs, components) return grok_enum_decls (components); } +/* Constructors for types with virtual baseclasses need an "in-charge" flag + saying whether this constructor is responsible for initialization of + virtual baseclasses or not. All destructors also need this "in-charge" + flag, which additionally determines whether or not the destructor should + free the memory for the object. + + 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. */ + +void +maybe_retrofit_in_chrg (fn) + tree fn; +{ + tree basetype, arg_types, parms, parm, fntype; + + if (DECL_CONSTRUCTOR_P (fn) + && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CLASS_CONTEXT (fn)) + && ! DECL_CONSTRUCTOR_FOR_VBASE_P (fn)) + /* OK */; + else if (! DECL_CONSTRUCTOR_P (fn) + && TREE_CHAIN (DECL_ARGUMENTS (fn)) == NULL_TREE) + /* OK */; + else + return; + + if (DECL_CONSTRUCTOR_P (fn)) + DECL_CONSTRUCTOR_FOR_VBASE_P (fn) = 1; + + /* First add it to DECL_ARGUMENTS... */ + parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); + /* Mark the artificial `__in_chrg' parameter as "artificial". */ + SET_DECL_ARTIFICIAL (parm); + DECL_ARG_TYPE (parm) = 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)); + fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), + arg_types); + if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) + fntype = build_exception_variant (fntype, + TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))); + TREE_TYPE (fn) = fntype; +} + /* Classes overload their constituent function names automatically. When a function name is declared in a record structure, its name is changed to it overloaded name. Since names for @@ -988,8 +1039,6 @@ grokclassfn (ctype, cname, function, flags, quals) tree arg_types; tree parm; tree qualtype; - tree fntype = TREE_TYPE (function); - tree raises = TYPE_RAISES_EXCEPTIONS (fntype); if (fn_name == NULL_TREE) { @@ -1016,24 +1065,6 @@ grokclassfn (ctype, cname, function, flags, quals) && (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))) constp = 0; - if (DECL_CONSTRUCTOR_P (function)) - { - if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) - { - DECL_CONSTRUCTOR_FOR_VBASE_P (function) = 1; - /* In this case we need "in-charge" flag saying whether - this constructor is responsible for initialization - of virtual baseclasses or not. */ - parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); - /* Mark the artificial `__in_chrg' parameter as "artificial". */ - SET_DECL_ARTIFICIAL (parm); - DECL_ARG_TYPE (parm) = integer_type_node; - TREE_READONLY (parm) = 1; - TREE_CHAIN (parm) = last_function_parms; - last_function_parms = parm; - } - } - parm = build_decl (PARM_DECL, this_identifier, type); /* Mark the artificial `this' parameter as "artificial". */ SET_DECL_ARTIFICIAL (parm); @@ -1047,81 +1078,33 @@ grokclassfn (ctype, cname, function, flags, quals) last_function_parms = parm; } + DECL_ARGUMENTS (function) = last_function_parms; + /* First approximations. */ + DECL_CONTEXT (function) = ctype; + DECL_CLASS_CONTEXT (function) = ctype; + + if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)) + { + maybe_retrofit_in_chrg (function); + arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); + } + if (flags == DTOR_FLAG) { - char *buf, *dbuf; - int len = sizeof (DESTRUCTOR_DECL_PREFIX)-1; - - arg_types = hash_tree_chain (integer_type_node, void_list_node); - TREE_SIDE_EFFECTS (arg_types) = 1; - /* Build the overload name. It will look like `7Example'. */ - if (IDENTIFIER_TYPE_VALUE (cname)) - dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); - else if (IDENTIFIER_LOCAL_VALUE (cname)) - dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), - 1, 1); - else - /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when - it's defined out of the class definition, since poplevel_class wipes - it out. This used to be internal error 346. */ - dbuf = build_overload_name (ctype, 1, 1); - buf = (char *) alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX)); - bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); - buf[len] = '\0'; - strcat (buf, dbuf); - DECL_ASSEMBLER_NAME (function) = get_identifier (buf); - parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); - /* Mark the artificial `__in_chrg' parameter as "artificial". */ - SET_DECL_ARTIFICIAL (parm); - TREE_READONLY (parm) = 1; - DECL_ARG_TYPE (parm) = integer_type_node; - /* This is the same chain as DECL_ARGUMENTS (...). */ - TREE_CHAIN (last_function_parms) = parm; - - fntype = build_cplus_method_type (qualtype, void_type_node, - arg_types); - if (raises) - { - fntype = build_exception_variant (fntype, raises); - } - TREE_TYPE (function) = fntype; + DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype); TYPE_HAS_DESTRUCTOR (ctype) = 1; } else { - tree these_arg_types; - - if (DECL_CONSTRUCTOR_FOR_VBASE_P (function)) - { - arg_types = hash_tree_chain (integer_type_node, - TREE_CHAIN (arg_types)); - fntype = build_cplus_method_type (qualtype, - TREE_TYPE (TREE_TYPE (function)), - arg_types); - if (raises) - { - fntype = build_exception_variant (fntype, raises); - } - TREE_TYPE (function) = fntype; - arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); - } - - these_arg_types = arg_types; - if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) /* Only true for static member functions. */ - these_arg_types = hash_tree_chain (build_pointer_type (qualtype), - arg_types); + arg_types = hash_tree_chain (build_pointer_type (qualtype), + arg_types); DECL_ASSEMBLER_NAME (function) - = build_decl_overload (fn_name, these_arg_types, + = build_decl_overload (fn_name, arg_types, 1 + DECL_CONSTRUCTOR_P (function)); } - - DECL_ARGUMENTS (function) = last_function_parms; - /* First approximations. */ - DECL_CONTEXT (function) = ctype; - DECL_CLASS_CONTEXT (function) = ctype; } /* Work on the expr used by alignof (this is only called by the parser). */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 054cfddb9f3..2679d3e539b 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1728,6 +1728,16 @@ get_id_2 (name, name2) OB_FINISH (); return get_identifier (obstack_base (&scratch_obstack)); } + +/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */ + +tree +build_destructor_name (type) + tree type; +{ + return build_overload_with_type (get_identifier (DESTRUCTOR_DECL_PREFIX), + type); +} /* Given a tree_code CODE, and some arguments (at least one), attempt to use an overloaded operator on the arguments. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e13135c66c8..a214906eaaa 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3777,19 +3777,33 @@ instantiate_class_template (type) bases = make_tree_vec (len); for (i = 0; i < len; ++i) { - tree elt; + tree elt, basetype; TREE_VEC_ELT (bases, i) = elt = tsubst (TREE_VEC_ELT (pbases, i), args, NULL_TREE); BINFO_INHERITANCE_CHAIN (elt) = binfo; - if (! IS_AGGR_TYPE (TREE_TYPE (elt))) + basetype = TREE_TYPE (elt); + + if (! IS_AGGR_TYPE (basetype)) cp_error ("base type `%T' of `%T' fails to be a struct or class type", - TREE_TYPE (elt), type); - else if (TYPE_SIZE (complete_type (TREE_TYPE (elt))) == NULL_TREE) + basetype, type); + else if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE) cp_error ("base class `%T' of `%T' has incomplete type", - TREE_TYPE (elt), type); + basetype, type); + + /* These are set up in xref_basetypes for normal classes, so + we have to handle them here for template bases. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) + { + TYPE_USES_VIRTUAL_BASECLASSES (type) = 1; + TYPE_USES_COMPLEX_INHERITANCE (type) = 1; + } + TYPE_GETS_NEW (type) |= TYPE_GETS_NEW (basetype); + TYPE_GETS_DELETE (type) |= TYPE_GETS_DELETE (basetype); + CLASSTYPE_LOCAL_TYPEDECLS (type) + |= CLASSTYPE_LOCAL_TYPEDECLS (basetype); } /* Don't initialize this until the vector is filled out, or lookups will crash. */ @@ -3837,13 +3851,6 @@ instantiate_class_template (type) } TYPE_METHODS (type) = tsubst_chain (TYPE_METHODS (pattern), args); - for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t)) - { - if (DECL_CONSTRUCTOR_P (t)) - grok_ctor_properties (type, t); - else if (IDENTIFIER_OPNAME_P (DECL_NAME (t))) - grok_op_properties (t, DECL_VIRTUAL_P (t), 0); - } /* Construct the DECL_FRIENDLIST for the new class type. */ typedecl = TYPE_MAIN_DECL (type); @@ -4542,17 +4549,30 @@ tsubst (t, args, in_decl) DECL_NAME (r) = build_typename_overload (TREE_TYPE (type)); } - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))) + DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t); + DECL_MAIN_VARIANT (r) = r; + DECL_RESULT (r) = NULL_TREE; + DECL_INITIAL (r) = NULL_TREE; + + TREE_STATIC (r) = 0; + TREE_PUBLIC (r) = TREE_PUBLIC (t); + DECL_EXTERNAL (r) = 1; + DECL_INTERFACE_KNOWN (r) = 0; + DECL_DEFER_OUTPUT (r) = 0; + TREE_CHAIN (r) = NULL_TREE; + DECL_PENDING_INLINE_INFO (r) = 0; + TREE_USED (r) = 0; + + if (DECL_CONSTRUCTOR_P (r)) { - char *buf, *dbuf = build_overload_name (ctx, 1, 1); - int len = sizeof (DESTRUCTOR_DECL_PREFIX) - 1; - buf = (char *) alloca (strlen (dbuf) - + sizeof (DESTRUCTOR_DECL_PREFIX)); - bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); - buf[len] = '\0'; - strcat (buf, dbuf); - DECL_ASSEMBLER_NAME (r) = get_identifier (buf); + maybe_retrofit_in_chrg (r); + grok_ctor_properties (ctx, r); } + if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) + grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r)); + + if (DECL_DESTRUCTOR_P (t)) + DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx); else { /* Instantiations of template functions must be mangled @@ -4645,23 +4665,6 @@ tsubst (t, args, in_decl) DECL_RTL (r) = 0; make_decl_rtl (r, NULL_PTR, 1); - DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t); - DECL_MAIN_VARIANT (r) = r; - DECL_RESULT (r) = NULL_TREE; - DECL_INITIAL (r) = NULL_TREE; - - TREE_STATIC (r) = 0; - TREE_PUBLIC (r) = TREE_PUBLIC (t); - DECL_EXTERNAL (r) = 1; - DECL_INTERFACE_KNOWN (r) = 0; - DECL_DEFER_OUTPUT (r) = 0; - TREE_CHAIN (r) = NULL_TREE; - DECL_PENDING_INLINE_INFO (r) = 0; - TREE_USED (r) = 0; - - if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r)); - if (DECL_TEMPLATE_INFO (t) != NULL_TREE) { DECL_TEMPLATE_INFO (r) = perm_tree_cons (tmpl, argvec, NULL_TREE); @@ -7141,6 +7144,7 @@ instantiate_decl (d) goto out; if (TREE_CODE (d) == VAR_DECL + && TREE_READONLY (d) && DECL_INITIAL (d) == NULL_TREE && DECL_INITIAL (code_pattern) != NULL_TREE) /* We need to set up DECL_INITIAL regardless of pattern_defined if |