diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c7a1335e2d3..a9fea21b4b36 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,13 +1,32 @@ +2000-05-24 Mark Mitchell + + * 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 * semantics.c (begin_class_definition): make the packed attribute be sensitive to the "-fpack-struct" command line flag -2000-05-24 Mark Mitchell - - * init.c (sort_member_init): Fix typo in error message generation - code. - 2000-05-24 Nathan Sidwell Update new-abi upcast algorithm. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 05251bbb9bd3..93feaddd9e26 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 d58a5a50fabb..6080abde32ad 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 41cdb8cfed5c..05c17f620f09 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 f97397f1cfdc..5b7209827cc4 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 df5023b23741..7d6892e232d9 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; + tree name; - /* 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); + switch (dtor_kind) + { + case sfk_complete_destructor: + name = complete_dtor_identifier; + break; - /* 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); + case sfk_base_destructor: + name = base_dtor_identifier; + break; - /* 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; + 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;