diff options
Diffstat (limited to 'gcc/cp/decl.c')
| -rw-r--r-- | gcc/cp/decl.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f456dbb..d5da38f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -180,6 +180,7 @@ static void save_function_data PROTO((tree)); static void check_function_type PROTO((tree)); static void destroy_local_static PROTO((tree)); static void destroy_local_var PROTO((tree)); +static void finish_constructor_body PROTO((void)); static void finish_destructor_body PROTO((void)); #if defined (DEBUG_CP_BINDING_LEVELS) @@ -4064,7 +4065,10 @@ pushdecl (x) } if (need_new_binding) - add_decl_to_level (x, current_binding_level); + add_decl_to_level (x, + DECL_NAMESPACE_SCOPE_P (x) + ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x)) + : current_binding_level); return x; } @@ -13329,9 +13333,26 @@ save_function_data (decl) f->cannot_inline = current_function_cannot_inline; } +/* At the end of every constructor we generate to code to return + `this'. Do that now. */ + +static void +finish_constructor_body () +{ + /* Any return from a constructor will end up here. */ + add_tree (build_min_nt (LABEL_STMT, ctor_label)); + + /* Clear CTOR_LABEL so that finish_return_stmt knows to really + generate the return, rather than a goto to CTOR_LABEL. */ + ctor_label = NULL_TREE; + /* In check_return_expr we translate an empty return from a + constructor to a return of `this'. */ + finish_return_stmt (NULL_TREE); +} + /* At the end of every destructor we generate code to restore virtual function tables to the values desired by base classes and to call - to base class destructors. Do that now, for DECL. */ + to base class destructors. Do that now. */ static void finish_destructor_body () @@ -13344,6 +13365,9 @@ finish_destructor_body () /* Create a block to contain all the extra code. */ compound_stmt = begin_compound_stmt (/*has_no_scope=*/0); + /* Any return from a destructor will end up here. */ + add_tree (build_min_nt (LABEL_STMT, dtor_label)); + /* Generate the code to call destructor on base class. If this destructor belongs to a class with virtual functions, then set the virtual function table pointer to represent the type of our @@ -13372,13 +13396,12 @@ finish_destructor_body () || TREE_OPERAND (exprstmt, 0) != integer_zero_node || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))) { - add_tree (build_min_nt (LABEL_STMT, dtor_label)); if (exprstmt != void_zero_node) /* Don't call `expand_expr_stmt' if we're not going to do anything, since -Wall will give a diagnostic. */ finish_expr_stmt (exprstmt); - /* Run destructor on all virtual baseclasses. */ + /* Run destructors for all virtual baseclasses. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) { tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); @@ -13496,10 +13519,23 @@ finish_function (lineno, flags) if (building_stmt_tree ()) { - if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel) - do_poplevel (); + if (DECL_CONSTRUCTOR_P (fndecl)) + { + finish_constructor_body (); + if (call_poplevel) + do_poplevel (); + } else if (DECL_DESTRUCTOR_P (fndecl) && !processing_template_decl) finish_destructor_body (); + else if (DECL_MAIN_P (fndecl)) + { + /* Make it so that `main' always returns 0 by default. */ +#ifdef VMS + finish_return_stmt (integer_one_node); +#else + finish_return_stmt (integer_zero_node); +#endif + } /* Finish dealing with exception specifiers. */ if (flag_exceptions && !processing_template_decl @@ -13535,28 +13571,11 @@ finish_function (lineno, flags) ; else if (DECL_CONSTRUCTOR_P (fndecl)) { - /* This is where the body of the constructor begins. All - subobjects have been fully constructed at this point. */ + /* All subobjects have been fully constructed at this point. */ end_protect_partials (); - /* This is where the body of the constructor ends. */ - expand_label (ctor_label); - ctor_label = NULL_TREE; - if (call_poplevel) do_poplevel (); - - /* c_expand_return knows to return 'this' from a constructor. */ - c_expand_return (NULL_TREE); - } - else if (DECL_MAIN_P (fndecl)) - { - /* Make it so that `main' always returns 0 by default. */ -#ifdef VMS - c_expand_return (integer_one_node); -#else - c_expand_return (integer_zero_node); -#endif } else if (return_label != NULL_RTX && flag_this_is_variable <= 0 |
