C++ PATCH: More cleanups
Mark Mitchell
mark@codesourcery.com
Tue Apr 11 09:58:00 GMT 2000
Here's another round of cleanups in front of the constructor-cloning
patch. This one adds a macro DECL_HAS_IN_CHARGE_PARM_P and uses it
throughout to test whether or not a function has an in-charge
parameter, rather than checking whether or not the class in which the
function is defined has virtual baseclasses. (It's better to check
for the property you want, rather than checking for a property
correlated with the one you want.) Also, I've introduced
DECL_COPY_CONSTRUCTOR_P as a way of telling whether or not something
is a copy constructor.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-04-11 Mark Mitchell <mark@codesourcery.com>
* 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.
Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.207
diff -c -p -r1.207 call.c
*** call.c 2000/04/09 06:44:18 1.207
--- call.c 2000/04/11 16:50:40
*************** add_function_candidate (candidates, fn,
*** 1265,1271 ****
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
! if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
--- 1265,1271 ----
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
! if (DECL_HAS_IN_CHARGE_PARM_P (fn))
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
*************** build_user_type_conversion_1 (totype, ex
*** 2287,2300 ****
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);
-
- ctors = TREE_VALUE (ctors);
}
for (; ctors; ctors = OVL_NEXT (ctors))
{
--- 2287,2302 ----
if (ctors)
{
! 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))
{
*************** convert_like_real (convs, expr, fn, argn
*** 3658,3664 ****
TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
args = build_tree_list (NULL_TREE, expr);
! if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
args = tree_cons (NULL_TREE, integer_one_node, args);
args = tree_cons (NULL_TREE, t, args);
}
--- 3660,3666 ----
TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
args = build_tree_list (NULL_TREE, expr);
! if (DECL_HAS_IN_CHARGE_PARM_P (fn))
args = tree_cons (NULL_TREE, integer_one_node, args);
args = tree_cons (NULL_TREE, t, args);
}
*************** build_over_call (cand, args, flags)
*** 3930,3936 ****
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)))
{
converted_args = tree_cons
(NULL_TREE, TREE_VALUE (arg), converted_args);
--- 3932,3938 ----
converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
arg = TREE_CHAIN (arg);
parm = TREE_CHAIN (parm);
! if (DECL_HAS_IN_CHARGE_PARM_P (fn))
{
converted_args = tree_cons
(NULL_TREE, TREE_VALUE (arg), converted_args);
*************** build_over_call (cand, args, flags)
*** 4031,4043 ****
if (! flag_elide_constructors)
/* Do things the hard way. */;
! else if (DECL_CONSTRUCTOR_P (fn)
! && TREE_VEC_LENGTH (convs) == 1
! && copy_args_p (fn))
{
tree targ;
arg = TREE_CHAIN (converted_args);
! if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
arg = TREE_CHAIN (arg);
arg = TREE_VALUE (arg);
--- 4033,4044 ----
if (! flag_elide_constructors)
/* Do things the hard way. */;
! else if (TREE_VEC_LENGTH (convs) == 1
! && 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 = TREE_VALUE (arg);
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.439
diff -c -p -r1.439 cp-tree.h
*** cp-tree.h 2000/04/11 16:27:37 1.439
--- cp-tree.h 2000/04/11 16:50:44
*************** struct lang_decl_flags
*** 1834,1840 ****
unsigned const_memfunc : 1;
unsigned volatile_memfunc : 1;
unsigned pure_virtual : 1;
! unsigned constructor_for_vbase_attr : 1;
unsigned mutable_flag : 1;
unsigned deferred : 1;
--- 1834,1840 ----
unsigned const_memfunc : 1;
unsigned volatile_memfunc : 1;
unsigned pure_virtual : 1;
! unsigned has_in_charge_parm_p : 1;
unsigned mutable_flag : 1;
unsigned deferred : 1;
*************** struct lang_decl
*** 1909,1914 ****
--- 1909,1918 ----
/* 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) \
*************** struct lang_decl
*** 1923,1931 ****
#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)
/* Non-zero for a FUNCTION_DECL that declares a type-info function.
This only happens in the old abi. */
--- 1927,1937 ----
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
(IDENTIFIER_OPNAME_P (DECL_NAME ((NODE))))
! /* 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. */
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.587
diff -c -p -r1.587 decl.c
*** decl.c 2000/04/11 16:27:37 1.587
--- decl.c 2000/04/11 16:50:53
*************** grokdeclarator (declarator, declspecs, d
*** 11250,11256 ****
TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
/* Skip the `in_chrg' argument too, if present. */
! if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl)))
arg_types = TREE_CHAIN (arg_types);
if (arg_types == void_list_node
--- 11250,11256 ----
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);
if (arg_types == void_list_node
*************** copy_args_p (d)
*** 11968,11975 ****
return 0;
t = FUNCTION_ARG_CHAIN (d);
! if (DECL_CONSTRUCTOR_P (d)
! && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d)))
t = TREE_CHAIN (t);
if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
--- 11968,11974 ----
return 0;
t = FUNCTION_ARG_CHAIN (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)))
*************** grok_ctor_properties (ctype, decl)
*** 12000,12006 ****
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))
{
my_friendly_assert (parmtypes
&& TREE_VALUE (parmtypes) == integer_type_node,
--- 11999,12005 ----
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,
*************** start_function (declspecs, declarator, a
*** 13444,13451 ****
/* 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))
current_in_charge_parm = TREE_CHAIN (t);
}
--- 13443,13449 ----
/* Constructors and destructors need to know whether they're "in
charge" of initializing virtual base classes. */
! if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
current_in_charge_parm = TREE_CHAIN (t);
}
*************** finish_destructor_body ()
*** 13924,13932 ****
/* Finish up a function declaration and compile that function
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
--- 13922,13927 ----
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.331
diff -c -p -r1.331 decl2.c
*** decl2.c 2000/04/11 16:27:37 1.331
--- decl2.c 2000/04/11 16:50:56
*************** maybe_retrofit_in_chrg (fn)
*** 929,946 ****
{
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
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);
--- 929,943 ----
{
tree basetype, arg_types, parms, parm, fntype;
! /* If we've already add the in-charge parameter don't do it again. */
! if (DECL_HAS_IN_CHARGE_PARM_P (fn))
return;
! /* 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);
*************** maybe_retrofit_in_chrg (fn)
*** 962,967 ****
--- 959,967 ----
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.
Index: error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.111
diff -c -p -r1.111 error.c
*** error.c 2000/03/28 19:27:14 1.111
--- error.c 2000/04/11 16:50:57
*************** dump_function_decl (t, flags)
*** 1169,1176 ****
/* Skip "this" parameter. */
parmtypes = TREE_CHAIN (parmtypes);
! if (DECL_DESTRUCTOR_P (t) || DECL_CONSTRUCTOR_FOR_VBASE_P (t))
! /* Skip past "in_charge" identifier. */
parmtypes = TREE_CHAIN (parmtypes);
dump_parameters (parmtypes, flags);
--- 1169,1176 ----
/* 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);
Index: init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.182
diff -c -p -r1.182 init.c
*** init.c 2000/04/09 06:44:20 1.182
--- init.c 2000/04/11 16:50:59
*************** emit_base_init (t)
*** 564,570 ****
else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo)))
{
init = NULL_TREE;
! if (extra_warnings && copy_args_p (current_function_decl))
cp_warning ("base class `%#T' should be explicitly initialized in the copy constructor",
BINFO_TYPE (base_binfo));
}
--- 564,571 ----
else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo)))
{
init = NULL_TREE;
! 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));
}
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.146
diff -c -p -r1.146 method.c
*** method.c 2000/04/11 16:27:38 1.146
--- method.c 2000/04/11 16:51:00
*************** do_build_copy_constructor (fndecl)
*** 2179,2185 ****
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
tree t;
! if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
parm = TREE_CHAIN (parm);
parm = convert_from_reference (parm);
--- 2179,2185 ----
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
tree t;
! if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
parm = TREE_CHAIN (parm);
parm = convert_from_reference (parm);
*************** synthesize_method (fndecl)
*** 2388,2394 ****
else
{
tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
! if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
arg_chain = TREE_CHAIN (arg_chain);
if (arg_chain != void_list_node)
do_build_copy_constructor (fndecl);
--- 2388,2394 ----
else
{
tree arg_chain = FUNCTION_ARG_CHAIN (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);
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.418
diff -c -p -r1.418 pt.c
*** pt.c 2000/04/11 16:27:42 1.418
--- pt.c 2000/04/11 16:51:06
*************** instantiate_template (tmpl, targ_ptr)
*** 7420,7427 ****
{
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;
}
}
}
--- 7420,7426 ----
{
cp_error ("type `%T' composed from a local class is not a valid template-argument", t);
cp_error (" trying to instantiate `%D'", gen_tmpl);
! return error_mark_node;
}
}
}
*************** instantiate_template (tmpl, targ_ptr)
*** 7436,7442 ****
if (flag_external_templates)
add_pending_template (fndecl);
- out:
return fndecl;
}
--- 7435,7440 ----
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tree.c,v
retrieving revision 1.191
diff -c -p -r1.191 tree.c
*** tree.c 2000/04/11 16:27:42 1.191
--- tree.c 2000/04/11 16:51:07
*************** build_cplus_method_type (basetype, retty
*** 460,468 ****
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. */
argtypes = tree_cons (NULL_TREE, ptype, argtypes);
TYPE_ARG_TYPES (t) = argtypes;
TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
--- 460,466 ----
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. */
argtypes = tree_cons (NULL_TREE, ptype, argtypes);
TYPE_ARG_TYPES (t) = argtypes;
TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
More information about the Gcc-patches
mailing list