summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-24 22:56:54 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-24 22:56:54 +0000
commit675996d9f6c4b824dfc03c5c9617faaee2b74929 (patch)
treeaab01c71ab2feb7c3a70dbb043d2cddecfd4de97
parent67630a35cabd804c2a2c6a4401a3dd74f144ea48 (diff)
downloadgcc-675996d9f6c4b824dfc03c5c9617faaee2b74929.tar.gz
* cp-tree.h (build_delete): Change prototype.
(build_vec_delete): Likewise. * call.c (build_scoped_method_call): Use special_function_kind values to indicate the kind of destruction to be done. (build_method_call): Likewise. * decl.c (finish_destructor_body): Likewise. (maybe_build_cleanup_1): Likewise. Rename to ... (maybe_build_cleanup): ... this. * decl2.c (delete_sanity): Use special_function_kind values to indicate the kind of destruction to be done. (build_cleanup): Likewise. * init.c (perform_member_init): Likewise. (build_vec_delete_1): Likewise. (build_dtor_call): Simplify. (build_delete): Use special_function_kind values to indicate the kind of destruction to be done. (build_vbase_delete): Likewise. (build_vec_delete): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34147 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog29
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c27
-rw-r--r--gcc/cp/decl2.c7
-rw-r--r--gcc/cp/init.c139
6 files changed, 96 insertions, 115 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5c7a1335e2d..a9fea21b4b3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,13 +1,32 @@
-Mon May 15 11:46:29 2000 Donald Lindsay <dlindsay@cygnus.com>
-
- * semantics.c (begin_class_definition): make the packed
- attribute be sensitive to the "-fpack-struct" command line flag
-
2000-05-24 Mark Mitchell <mark@codesourcery.com>
+ * cp-tree.h (build_delete): Change prototype.
+ (build_vec_delete): Likewise.
+ * call.c (build_scoped_method_call): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_method_call): Likewise.
+ * decl.c (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise. Rename to ...
+ (maybe_build_cleanup): ... this.
+ * decl2.c (delete_sanity): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_cleanup): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_dtor_call): Simplify.
+ (build_delete): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_vbase_delete): Likewise.
+ (build_vec_delete): Likewise.
+
* init.c (sort_member_init): Fix typo in error message generation
code.
+Mon May 15 11:46:29 2000 Donald Lindsay <dlindsay@cygnus.com>
+
+ * semantics.c (begin_class_definition): make the packed
+ attribute be sensitive to the "-fpack-struct" command line flag
+
2000-05-24 Nathan Sidwell <nathan@codesourcery.com>
Update new-abi upcast algorithm.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 05251bbb9bd..93feaddd9e2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -309,7 +309,8 @@ build_scoped_method_call (exp, basetype, name, parms)
if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
return cp_convert (void_type_node, exp);
- return build_delete (TREE_TYPE (decl), decl, integer_two_node,
+ return build_delete (TREE_TYPE (decl), decl,
+ sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
0);
}
@@ -516,7 +517,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
instance = default_conversion (instance);
instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
return build_delete (build_pointer_type (basetype),
- instance_ptr, integer_two_node,
+ instance_ptr, sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d58a5a50fab..6080abde32a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4122,9 +4122,9 @@ extern tree decl_constant_value PARAMS ((tree));
extern tree build_new PARAMS ((tree, tree, tree, int));
extern tree build_vec_init PARAMS ((tree, tree, tree, tree, int));
extern tree build_x_delete PARAMS ((tree, int, tree));
-extern tree build_delete PARAMS ((tree, tree, tree, int, int));
+extern tree build_delete PARAMS ((tree, tree, special_function_kind, int, int));
extern tree build_vbase_delete PARAMS ((tree, tree));
-extern tree build_vec_delete PARAMS ((tree, tree, tree, int));
+extern tree build_vec_delete PARAMS ((tree, tree, special_function_kind, int));
extern tree create_temporary_var PARAMS ((tree));
extern void begin_init_stmts PARAMS ((tree *, tree *));
extern tree finish_init_stmts PARAMS ((tree, tree));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 41cdb8cfed5..05c17f620f0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -112,7 +112,6 @@ static int unary_op_p PARAMS ((tree));
static tree store_bindings PARAMS ((tree, tree));
static tree lookup_tag_reverse PARAMS ((tree, tree));
static tree obscure_complex_init PARAMS ((tree, tree));
-static tree maybe_build_cleanup_1 PARAMS ((tree, tree));
static tree lookup_name_real PARAMS ((tree, int, int, int));
static void warn_extern_redeclared_static PARAMS ((tree, tree));
static void grok_reference_init PARAMS ((tree, tree, tree));
@@ -13845,7 +13844,7 @@ finish_destructor_body ()
exprstmt = build_delete (current_class_type,
current_class_ref,
- integer_zero_node,
+ sfk_base_destructor,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
0);
@@ -14513,14 +14512,15 @@ hack_incomplete_structures (type)
}
}
-/* If DECL is of a type which needs a cleanup, build that cleanup here.
- See build_delete for information about AUTO_DELETE. */
+/* If DECL is of a type which needs a cleanup, build that cleanup
+ here. */
-static tree
-maybe_build_cleanup_1 (decl, auto_delete)
- tree decl, auto_delete;
+tree
+maybe_build_cleanup (decl)
+ tree decl;
{
tree type = TREE_TYPE (decl);
+
if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
{
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
@@ -14539,7 +14539,8 @@ maybe_build_cleanup_1 (decl, auto_delete)
|| flag_expensive_optimizations)
flags |= LOOKUP_NONVIRTUAL;
- rval = build_delete (TREE_TYPE (rval), rval, auto_delete, flags, 0);
+ rval = build_delete (TREE_TYPE (rval), rval,
+ sfk_complete_destructor, flags, 0);
if (TYPE_USES_VIRTUAL_BASECLASSES (type)
&& ! TYPE_HAS_DESTRUCTOR (type))
@@ -14550,16 +14551,6 @@ maybe_build_cleanup_1 (decl, auto_delete)
}
return 0;
}
-
-/* If DECL is of a type which needs a cleanup, build that cleanup
- here. The cleanup does not free the storage with a call a delete. */
-
-tree
-maybe_build_cleanup (decl)
- tree decl;
-{
- return maybe_build_cleanup_1 (decl, integer_two_node);
-}
/* Expand a C++ expression at the statement level.
This is needed to ferret out nodes which have UNKNOWN_TYPE.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f97397f1cfd..5b7209827cc 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1241,7 +1241,8 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return build1 (NOP_EXPR, void_type_node, t);
if (doing_vec)
- return build_vec_delete (t, maxindex, integer_one_node, use_global_delete);
+ return build_vec_delete (t, maxindex, sfk_deleting_destructor,
+ use_global_delete);
else
{
if (IS_AGGR_TYPE (TREE_TYPE (type))
@@ -1255,7 +1256,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return error_mark_node;
}
- return build_delete (type, t, integer_three_node,
+ return build_delete (type, t, sfk_deleting_destructor,
LOOKUP_NORMAL, use_global_delete);
}
}
@@ -2788,7 +2789,7 @@ build_cleanup (decl)
temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
}
temp = build_delete (TREE_TYPE (temp), temp,
- integer_two_node,
+ sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
return temp;
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index df5023b2374..7d6892e232d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -38,7 +38,7 @@ static void expand_aggr_vbase_init_1 PARAMS ((tree, tree, tree, tree));
static void construct_virtual_bases PARAMS ((tree, tree, tree, tree, tree));
static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int));
static void expand_default_init PARAMS ((tree, tree, tree, tree, int));
-static tree build_vec_delete_1 PARAMS ((tree, tree, tree, tree, int));
+static tree build_vec_delete_1 PARAMS ((tree, tree, tree, special_function_kind, int));
static void perform_member_init PARAMS ((tree, tree, int));
static void sort_base_init PARAMS ((tree, tree *, tree *));
static tree build_builtin_delete_call PARAMS ((tree));
@@ -51,7 +51,7 @@ static tree get_temp_regvar PARAMS ((tree, tree));
static tree dfs_initialize_vtbl_ptrs PARAMS ((tree, void *));
static tree build_new_1 PARAMS ((tree));
static tree get_cookie_size PARAMS ((tree));
-static tree build_dtor_call PARAMS ((tree, tree, int));
+static tree build_dtor_call PARAMS ((tree, special_function_kind, int));
static tree build_field_list PARAMS ((tree, tree, int *));
/* Set up local variable for this file. MUST BE CALLED AFTER
@@ -276,7 +276,7 @@ perform_member_init (member, init, explicit)
expr = build_component_ref (current_class_ref, member, NULL_TREE,
explicit);
- expr = build_delete (type, expr, integer_zero_node,
+ expr = build_delete (type, expr, sfk_base_destructor,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
if (expr != error_mark_node)
@@ -2538,7 +2538,7 @@ build_new_1 (exp)
static tree
build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
tree base, maxindex, type;
- tree auto_delete_vec;
+ special_function_kind auto_delete_vec;
int use_global_delete;
{
tree virtual_size;
@@ -2586,7 +2586,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
body = NULL_TREE;
body = tree_cons (NULL_TREE,
- build_delete (ptype, tbase, integer_two_node,
+ build_delete (ptype, tbase, sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1),
body);
@@ -2608,9 +2608,8 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
no_destructor:
/* If the delete flag is one, or anything else with the low bit set,
delete the storage. */
- if (auto_delete_vec == integer_zero_node)
- deallocate_expr = integer_zero_node;
- else
+ deallocate_expr = integer_zero_node;
+ if (auto_delete_vec != sfk_base_destructor)
{
tree base_tbd;
@@ -2634,15 +2633,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
/* True size with header. */
virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
}
- deallocate_expr = build_x_delete (base_tbd,
- 2 | use_global_delete,
- virtual_size);
- deallocate_expr = fold (build (COND_EXPR, void_type_node,
- fold (build (BIT_AND_EXPR,
- integer_type_node,
- auto_delete_vec,
- integer_one_node)),
- deallocate_expr, integer_zero_node));
+
+ if (auto_delete_vec == sfk_deleting_destructor)
+ deallocate_expr = build_x_delete (base_tbd,
+ 2 | use_global_delete,
+ virtual_size);
}
if (loop && deallocate_expr != integer_zero_node)
@@ -2997,7 +2992,7 @@ build_vec_init (decl, base, maxindex, init, from_array)
build_binary_op (MINUS_EXPR, maxindex,
iterator),
type,
- /*auto_delete_vec=*/integer_zero_node,
+ sfk_base_destructor,
/*use_global_delete=*/0);
finish_cleanup (e, try_block);
}
@@ -3039,60 +3034,42 @@ build_x_delete (addr, which_delete, virtual_size)
return build_op_delete_call (code, addr, virtual_size, flags, NULL_TREE);
}
-/* Call the destructor for EXP using the IN_CHARGE parameter. FLAGS
- are as for build_delete. */
+/* Call the DTOR_KIND destructor for EXP. FLAGS are as for
+ build_delete. */
static tree
-build_dtor_call (exp, in_charge, flags)
+build_dtor_call (exp, dtor_kind, flags)
tree exp;
- tree in_charge;
+ special_function_kind dtor_kind;
int flags;
{
- tree name = NULL_TREE;
- tree call1;
- tree call2;
- tree call3;
- tree result;
-
- /* First, try to figure out statically which function to call. */
- in_charge = fold (in_charge);
- if (tree_int_cst_equal (in_charge, integer_zero_node))
- name = base_dtor_identifier;
- else if (tree_int_cst_equal (in_charge, integer_one_node))
- name = deleting_dtor_identifier;
- else if (tree_int_cst_equal (in_charge, integer_two_node))
- name = complete_dtor_identifier;
- if (name)
- return build_method_call (exp, name, NULL_TREE, NULL_TREE, flags);
-
- /* If that didn't work, build the various alternatives. */
- call1 = build_method_call (exp, complete_dtor_identifier,
- NULL_TREE, NULL_TREE, flags);
- call2 = build_method_call (exp, deleting_dtor_identifier,
- NULL_TREE, NULL_TREE, flags);
- call3 = build_method_call (exp, base_dtor_identifier,
- NULL_TREE, NULL_TREE, flags);
-
- /* Build the conditionals. */
- result = build (COND_EXPR, void_type_node,
- fold (build (BIT_AND_EXPR, integer_type_node,
- in_charge, integer_two_node)),
- call1,
- call3);
- result = build (COND_EXPR, void_type_node,
- fold (build (BIT_AND_EXPR, integer_type_node,
- in_charge, integer_one_node)),
- call2,
- result);
- return result;
+ tree name;
+
+ switch (dtor_kind)
+ {
+ case sfk_complete_destructor:
+ name = complete_dtor_identifier;
+ break;
+
+ case sfk_base_destructor:
+ name = base_dtor_identifier;
+ break;
+
+ case sfk_deleting_destructor:
+ name = deleting_dtor_identifier;
+ break;
+
+ default:
+ my_friendly_abort (20000524);
+ }
+ return build_method_call (exp, name, NULL_TREE, NULL_TREE, flags);
}
/* Generate a call to a destructor. TYPE is the type to cast ADDR to.
ADDR is an expression which yields the store to be destroyed.
- AUTO_DELETE is nonzero if a call to DELETE should be made or not.
- If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the
- virtual baseclasses.
- If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate.
+ AUTO_DELETE is the name of the destructor to call, i.e., either
+ sfk_complete_destructor, sfk_base_destructor, or
+ sfk_deleting_destructor.
FLAGS is the logical disjunction of zero or more LOOKUP_
flags. See cp-tree.h for more info.
@@ -3102,7 +3079,7 @@ build_dtor_call (exp, in_charge, flags)
tree
build_delete (type, addr, auto_delete, flags, use_global_delete)
tree type, addr;
- tree auto_delete;
+ special_function_kind auto_delete;
int flags;
int use_global_delete;
{
@@ -3173,7 +3150,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
{
- if (auto_delete == integer_zero_node)
+ if (auto_delete == sfk_base_destructor)
return void_zero_node;
return build_op_delete_call
@@ -3187,28 +3164,19 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
of the base classes; otherwise, we must do that here. */
if (TYPE_HAS_DESTRUCTOR (type))
{
- tree passed_auto_delete;
tree do_delete = NULL_TREE;
tree ifexp;
- if (use_global_delete)
+ if (use_global_delete && auto_delete == sfk_deleting_destructor)
{
- tree cond = fold (build (BIT_AND_EXPR, integer_type_node,
- auto_delete, integer_one_node));
- tree call = build_builtin_delete_call (addr);
-
- cond = fold (build (COND_EXPR, void_type_node, cond,
- call, void_zero_node));
- if (cond != void_zero_node)
- do_delete = cond;
-
- passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node,
- auto_delete, integer_two_node));
+ /* Delete the object. */
+ do_delete = build_builtin_delete_call (addr);
+ /* Otherwise, treat this like a complete object destructor
+ call. */
+ auto_delete = sfk_complete_destructor;
}
- else
- passed_auto_delete = auto_delete;
- expr = build_dtor_call (ref, passed_auto_delete, flags);
+ expr = build_dtor_call (ref, auto_delete, flags);
if (do_delete)
expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
@@ -3239,7 +3207,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
/* If we have member delete or vbases, we call delete in
finish_function. */
- my_friendly_assert (auto_delete == integer_zero_node, 20000411);
+ my_friendly_assert (auto_delete == sfk_base_destructor, 20000411);
/* Take care of the remaining baseclasses. */
for (i = 0; i < n_baseclasses; i++)
@@ -3264,7 +3232,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
{
tree this_member = build_component_ref (ref, DECL_NAME (member), NULL_TREE, 0);
tree this_type = TREE_TYPE (member);
- expr = build_delete (this_type, this_member, integer_two_node, flags, 0);
+ expr = build_delete (this_type, this_member,
+ sfk_complete_destructor, flags, 0);
exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
}
}
@@ -3295,7 +3264,7 @@ build_vbase_delete (type, decl)
addr, 0);
result = tree_cons (NULL_TREE,
build_delete (TREE_TYPE (this_addr), this_addr,
- integer_zero_node,
+ sfk_base_destructor,
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0),
result);
vbases = TREE_CHAIN (vbases);
@@ -3322,7 +3291,7 @@ build_vbase_delete (type, decl)
tree
build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
tree base, maxindex;
- tree auto_delete_vec;
+ special_function_kind auto_delete_vec;
int use_global_delete;
{
tree type;