Commit 68e0e461 by Wei Guozhi Committed by Wei Guozhi

optimize.c (build_delete_destructor_body): New function.

	* cp/optimize.c (build_delete_destructor_body): New function.
	(maybe_clone_body): Call build_delete_destructor_body for
	deleting destructor.

From-SVN: r151673
parent 933608b7
2009-09-13 Wei Guozhi <carrot@google.com>
PR c++/3187
* cp/optimize.c (build_delete_destructor_body): New function.
(maybe_clone_body): Call build_delete_destructor_body for
deleting destructor.
2009-09-10 Jason Merrill <jason@redhat.com> 2009-09-10 Jason Merrill <jason@redhat.com>
* repo.c (extract_string, get_base_filename, init_repo): constify. * repo.c (extract_string, get_base_filename, init_repo): constify.
......
/* Perform optimizations on tree structure. /* Perform optimizations on tree structure.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc. Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com). Written by Mark Michell (mark@codesourcery.com).
...@@ -106,6 +106,41 @@ clone_body (tree clone, tree fn, void *arg_map) ...@@ -106,6 +106,41 @@ clone_body (tree clone, tree fn, void *arg_map)
append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
} }
/* DELETE_DTOR is a delete destructor whose body will be built.
COMPLETE_DTOR is the corresponding complete destructor. */
static void
build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
{
tree call_dtor, call_delete;
tree parm = DECL_ARGUMENTS (delete_dtor);
tree virtual_size = cxx_sizeof (current_class_type);
/* Call the corresponding complete destructor. */
gcc_assert (complete_dtor);
call_dtor = build_cxx_call (complete_dtor, 1, &parm);
add_stmt (call_dtor);
add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
/* Call the delete function. */
call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
virtual_size,
/*global_p=*/false,
/*placement=*/NULL_TREE,
/*alloc_fn=*/NULL_TREE);
add_stmt (call_delete);
/* Return the address of the object. */
if (targetm.cxx.cdtor_returns_this ())
{
tree val = DECL_ARGUMENTS (delete_dtor);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (delete_dtor), val);
add_stmt (build_stmt (0, RETURN_EXPR, val));
}
}
/* FN is a function that has a complete body. Clone the body as /* FN is a function that has a complete body. Clone the body as
necessary. Returns nonzero if there's no longer any need to necessary. Returns nonzero if there's no longer any need to
process the main body. */ process the main body. */
...@@ -114,6 +149,7 @@ bool ...@@ -114,6 +149,7 @@ bool
maybe_clone_body (tree fn) maybe_clone_body (tree fn)
{ {
tree clone; tree clone;
tree complete_dtor = NULL_TREE;
bool first = true; bool first = true;
/* We only clone constructors and destructors. */ /* We only clone constructors and destructors. */
...@@ -124,6 +160,15 @@ maybe_clone_body (tree fn) ...@@ -124,6 +160,15 @@ maybe_clone_body (tree fn)
/* Emit the DWARF1 abstract instance. */ /* Emit the DWARF1 abstract instance. */
(*debug_hooks->deferred_inline_function) (fn); (*debug_hooks->deferred_inline_function) (fn);
/* Look for the complete destructor which may be used to build the
delete destructor. */
FOR_EACH_CLONE (clone, fn)
if (DECL_NAME (clone) == complete_dtor_identifier)
{
complete_dtor = clone;
break;
}
/* We know that any clones immediately follow FN in the TYPE_METHODS /* We know that any clones immediately follow FN in the TYPE_METHODS
list. */ list. */
push_to_top_level (); push_to_top_level ();
...@@ -176,6 +221,12 @@ maybe_clone_body (tree fn) ...@@ -176,6 +221,12 @@ maybe_clone_body (tree fn)
/* Start processing the function. */ /* Start processing the function. */
start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
/* Build the delete destructor by calling complete destructor
and delete function. */
if (DECL_NAME (clone) == deleting_dtor_identifier)
build_delete_destructor_body (clone, complete_dtor);
else
{
/* Remap the parameters. */ /* Remap the parameters. */
decl_map = pointer_map_create (); decl_map = pointer_map_create ();
for (parmno = 0, for (parmno = 0,
...@@ -224,11 +275,13 @@ maybe_clone_body (tree fn) ...@@ -224,11 +275,13 @@ maybe_clone_body (tree fn)
clone_parm = DECL_RESULT (clone); clone_parm = DECL_RESULT (clone);
*pointer_map_insert (decl_map, parm) = clone_parm; *pointer_map_insert (decl_map, parm) = clone_parm;
} }
/* Clone the body. */ /* Clone the body. */
clone_body (clone, fn, decl_map); clone_body (clone, fn, decl_map);
/* Clean up. */ /* Clean up. */
pointer_map_destroy (decl_map); pointer_map_destroy (decl_map);
}
/* The clone can throw iff the original function can throw. */ /* The clone can throw iff the original function can throw. */
cp_function_chain->can_throw = !TREE_NOTHROW (fn); cp_function_chain->can_throw = !TREE_NOTHROW (fn);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment