From: Jason Merrill Date: Wed, 20 May 1998 02:46:16 +0000 (+0000) Subject: decl2.c (start_objects, [...]): Split out from... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=961ec1a55f026bfd67ad11991aaadaa2520fd57a;p=gcc.git decl2.c (start_objects, [...]): Split out from... * decl2.c (start_objects, finish_objects, do_dtors, do_ctors): Split out from... (finish_file): ...here. From-SVN: r19904 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 13e1312a09f..101b5986415 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +Wed May 20 02:16:01 1998 Jason Merrill + + * decl2.c (start_objects, finish_objects, do_dtors, + do_ctors): Split out from... + (finish_file): ...here. + Tue May 19 20:36:23 1998 Jason Merrill * tree.c (is_overloaded_fn): Don't abort on placeholders from @@ -65,10 +71,6 @@ Tue May 19 02:43:25 1998 Jason Merrill Mon May 18 23:22:52 1998 Jason Merrill - * decl2.c (setup_initp, start_objects, finish_objects): New fns. - (do_dtors, do_ctors): Split out from... - (finish_file): ...here. Support init_priority. - * decl2.c (get_sentry): Use end_temporary_allocation. Don't declare permanent_obstack. @@ -9610,10 +9612,3 @@ Wed Oct 11 16:30:34 1995 Brendan Kehoe * parse.y (fn.def1): Call split_specs_attrs in declmods notype_declarator case. - -Use a consistent time stamp format in ChangeLog entries. -Not everyone has Emacs 20 yet, so stick with Emacs 19 format for now. - -Local Variables: -add-log-time-format: current-time-string -End: diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 67795ab9bb2..a57bc3c40ed 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3926,12 +3926,10 @@ compare_ics (ics1, ics2) if (is_subseq (ics2, ics1)) return -1; } - else - /* One sequence cannot be a subsequence of the other; they don't - start with the same type. This can happen when comparing the - second standard conversion sequence in two user-defined - conversion sequences. */ - ; + /* Otherwise, one sequence cannot be a subsequence of the other; they + don't start with the same type. This can happen when comparing the + second standard conversion sequence in two user-defined conversion + sequences. */ /* [over.ics.rank] diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 694f1516724..57e3def6d9d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2800,6 +2800,204 @@ get_sentry (base) return sentry; } +/* Start the process of running a particular set of global constructors + or destructors. Subroutine of do_[cd]tors. */ + +static void +start_objects (method_type) + int method_type; +{ + tree fnname; + + /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ + + fnname = get_file_function_name (method_type); + + start_function (void_list_node, + make_call_declarator (fnname, void_list_node, NULL_TREE, + NULL_TREE), + NULL_TREE, 0); + + store_parm_decls (); + pushlevel (0); + clear_last_expr (); + push_momentary (); + expand_start_bindings (0); +} + +/* Finish the process of running a particular set of global constructors + or destructors. Subroutine of do_[cd]tors. */ + +static void +finish_objects (method_type) + int method_type; +{ + char *fnname; + + tree list = (method_type == 'I' ? static_ctors : static_dtors); + + if (! current_function_decl && list) + start_objects (method_type); + + for (; list; list = TREE_CHAIN (list)) + expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE)); + + if (! current_function_decl) + return; + + fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); + + /* Finish up. */ + expand_end_bindings (getdecls (), 1, 0); + poplevel (1, 0, 0); + pop_momentary (); + finish_function (lineno, 0, 0); + + if (method_type == 'I') + assemble_constructor (fnname); + else + assemble_destructor (fnname); +} + +/* Generate a function to run a set of global destructors. Subroutine of + finish_file. */ + +static void +do_dtors () +{ + tree vars = static_aggregates; + + for (; vars; vars = TREE_CHAIN (vars)) + { + tree decl = TREE_VALUE (vars); + tree type = TREE_TYPE (decl); + tree temp; + + if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars) + && ! DECL_EXTERNAL (decl)) + { + int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) + || DECL_ONE_ONLY (decl) + || DECL_WEAK (decl))); + + if (! current_function_decl) + start_objects ('D'); + + temp = build_cleanup (decl); + + if (protect) + { + tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); + sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0); + sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1); + expand_start_cond (sentry, 0); + } + + expand_expr_stmt (temp); + + if (protect) + expand_end_cond (); + } + } + + finish_objects ('D'); +} + +/* Generate a function to run a set of global constructors. Subroutine of + finish_file. */ + +static void +do_ctors () +{ + tree vars = static_aggregates; + + /* Reverse the list so it's in the right order for ctors. */ + vars = nreverse (vars); + + for (; vars; vars = TREE_CHAIN (vars)) + { + tree decl = TREE_VALUE (vars); + tree init = TREE_PURPOSE (vars); + + /* If this was a static attribute within some function's scope, + then don't initialize it here. Also, don't bother + with initializers that contain errors. */ + if (TREE_STATIC (vars) + || DECL_EXTERNAL (decl) + || (init && TREE_CODE (init) == TREE_LIST + && value_member (error_mark_node, init))) + continue; + + if (TREE_CODE (decl) == VAR_DECL) + { + int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) + || DECL_ONE_ONLY (decl) + || DECL_WEAK (decl))); + + if (! current_function_decl) + start_objects ('I'); + + /* Set these global variables so that GDB at least puts + us near the declaration which required the initialization. */ + input_filename = DECL_SOURCE_FILE (decl); + lineno = DECL_SOURCE_LINE (decl); + emit_note (input_filename, lineno); + + /* 9.5p5: The initializer of a static member of a class has + the same access rights as a member function. */ + if (member_p (decl)) + { + DECL_CLASS_CONTEXT (current_function_decl) + = DECL_CONTEXT (decl); + DECL_STATIC_FUNCTION_P (current_function_decl) = 1; + } + + if (protect) + { + tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); + sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0); + sentry = build_binary_op + (EQ_EXPR, sentry, integer_one_node, 1); + expand_start_cond (sentry, 0); + } + + expand_start_target_temps (); + + if (IS_AGGR_TYPE (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + expand_aggr_init (decl, init, 0, 0); + else if (TREE_CODE (init) == TREE_VEC) + { + expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), + TREE_VEC_ELT (init, 1), + TREE_VEC_ELT (init, 2), 0), + const0_rtx, VOIDmode, EXPAND_NORMAL); + } + else + expand_assignment (decl, init, 0, 0); + + /* The expression might have involved increments and + decrements. */ + emit_queue (); + + /* Cleanup any temporaries needed for the initial value. */ + expand_end_target_temps (); + + if (protect) + expand_end_cond (); + + DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; + DECL_STATIC_FUNCTION_P (current_function_decl) = 0; + } + else if (decl == error_mark_node) + /* OK */; + else + my_friendly_abort (22); + } + + finish_objects ('I'); +} + /* This routine is called from the last rule in yyparse (). Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction @@ -2901,193 +3099,19 @@ finish_file () if (static_ctors || vars) needs_messing_up = 1; - if (static_dtors) + if (static_dtors || vars) needs_cleaning = 1; - /* See if we really need the hassle. */ - while (vars && needs_cleaning == 0) - { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars)) - { - needs_cleaning = 1; - break; - } - - vars = TREE_CHAIN (vars); - } - - if (needs_cleaning == 0) - goto mess_up; - - fnname = get_file_function_name ('D'); - start_function (void_list_node, - make_call_declarator (fnname, void_list_node, NULL_TREE, - NULL_TREE), - NULL_TREE, 0); - fnname = DECL_ASSEMBLER_NAME (current_function_decl); - store_parm_decls (); - - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - - /* These must be done in backward order to destroy, - in which they happen to be! */ - for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars)) + /* The aggregates are listed in reverse declaration order, for cleaning. */ + if (needs_cleaning) { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - tree temp = TREE_PURPOSE (vars); - - if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars) - && ! DECL_EXTERNAL (decl)) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); - - temp = build_cleanup (decl); - - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0); - sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1); - expand_start_cond (sentry, 0); - } - - expand_expr_stmt (temp); - - if (protect) - expand_end_cond (); - } + do_dtors (); } - for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors)) - expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors), - NULL_TREE)); - - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - - finish_function (lineno, 0, 0); - - assemble_destructor (IDENTIFIER_POINTER (fnname)); - - /* If it needed cleaning, then it will need messing up: drop through. */ - - mess_up: - /* Must do this while we think we are at the top level. */ - vars = nreverse (static_aggregates); + /* do_ctors will reverse the lists for messing up. */ if (needs_messing_up) { - fnname = get_file_function_name ('I'); - start_function (void_list_node, - make_call_declarator (fnname, void_list_node, NULL_TREE, - NULL_TREE), - NULL_TREE, 0); - fnname = DECL_ASSEMBLER_NAME (current_function_decl); - store_parm_decls (); - - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - - while (vars) - { - tree decl = TREE_VALUE (vars); - tree init = TREE_PURPOSE (vars); - - /* If this was a static attribute within some function's scope, - then don't initialize it here. Also, don't bother - with initializers that contain errors. */ - if (TREE_STATIC (vars) - || DECL_EXTERNAL (decl) - || (init && TREE_CODE (init) == TREE_LIST - && value_member (error_mark_node, init))) - goto next_mess; - - if (TREE_CODE (decl) == VAR_DECL) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); - - /* Set these global variables so that GDB at least puts - us near the declaration which required the initialization. */ - input_filename = DECL_SOURCE_FILE (decl); - lineno = DECL_SOURCE_LINE (decl); - emit_note (input_filename, lineno); - - /* 9.5p5: The initializer of a static member of a class has - the same access rights as a member function. */ - if (member_p (decl)) - { - DECL_CLASS_CONTEXT (current_function_decl) - = DECL_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (current_function_decl) = 1; - } - - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0); - sentry = build_binary_op - (EQ_EXPR, sentry, integer_one_node, 1); - expand_start_cond (sentry, 0); - } - - expand_start_target_temps (); - - if (IS_AGGR_TYPE (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - expand_aggr_init (decl, init, 0, 0); - else if (TREE_CODE (init) == TREE_VEC) - { - expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), - TREE_VEC_ELT (init, 1), - TREE_VEC_ELT (init, 2), 0), - const0_rtx, VOIDmode, EXPAND_NORMAL); - } - else - expand_assignment (decl, init, 0, 0); - - /* The expression might have involved increments and - decrements. */ - emit_queue (); - - /* Cleanup any temporaries needed for the initial value. */ - expand_end_target_temps (); - - if (protect) - expand_end_cond (); - - DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; - DECL_STATIC_FUNCTION_P (current_function_decl) = 0; - } - else if (decl == error_mark_node) - ; - else my_friendly_abort (22); - - next_mess: - vars = TREE_CHAIN (vars); - } - - for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors)) - expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors), - NULL_TREE)); - - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - - finish_function (lineno, 0, 0); - assemble_constructor (IDENTIFIER_POINTER (fnname)); + do_ctors (); } permanent_allocation (1);