From: Mark Mitchell Date: Thu, 22 Apr 1999 23:06:09 +0000 (+0000) Subject: toplev.h (wrapup_global_declarations): Declare. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=32291f940ea10975e1555e2c0ae8189e34979482;p=gcc.git toplev.h (wrapup_global_declarations): Declare. * toplev.h (wrapup_global_declarations): Declare. (check_global_declarations): Likewise. * toplev.c (wrapup_global_declarations): New function, split out from ... (check_global_declarations): Likewise... (compile_file): Here. From-SVN: r26593 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e906fe17605..573bfb1407e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Thu Apr 22 23:08:37 1999 Mark Mitchell + + * toplev.h (wrapup_global_declarations): Declare. + (check_global_declarations): Likewise. + * toplev.c (wrapup_global_declarations): New function, split out + from ... + (check_global_declarations): Likewise... + (compile_file): Here. + Thu Apr 22 22:34:41 1999 Richard Henderson * c-parse.in (expr_no_commas): Verify we've an expr before diff --git a/gcc/toplev.c b/gcc/toplev.c index a9de70209f7..f0e84f42e3a 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2675,6 +2675,207 @@ clean_dump_file (suffix) return; } +/* Do any final processing required for the declarations in VEC, of + which there are LEN. We write out inline functions and variables + that have been deferred until this point, but which are required. + Returns non-zero if anything was put out. */ +int +wrapup_global_declarations (vec, len) + tree *vec; + int len; +{ + tree decl; + int i; + int reconsider; + int output_something = 0; + + for (i = 0; i < len; i++) + { + decl = vec[i]; + + /* We're not deferring this any longer. */ + DECL_DEFER_OUTPUT (decl) = 0; + + if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 + && incomplete_decl_finalize_hook != 0) + (*incomplete_decl_finalize_hook) (decl); + } + + /* Now emit any global variables or functions that we have been + putting off. We need to loop in case one of the things emitted + here references another one which comes earlier in the list. */ + do + { + reconsider = 0; + for (i = 0; i < len; i++) + { + decl = vec[i]; + + if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) + continue; + + /* Don't write out static consts, unless we still need them. + + We also keep static consts if not optimizing (for debugging), + unless the user specified -fno-keep-static-consts. + ??? They might be better written into the debug information. + This is possible when using DWARF. + + A language processor that wants static constants to be always + written out (even if it is not used) is responsible for + calling rest_of_decl_compilation itself. E.g. the C front-end + calls rest_of_decl_compilation from finish_decl. + One motivation for this is that is conventional in some + environments to write things like: + static const char rcsid[] = "... version string ..."; + intending to force the string to be in the executable. + + A language processor that would prefer to have unneeded + static constants "optimized away" would just defer writing + them out until here. E.g. C++ does this, because static + constants are often defined in header files. + + ??? A tempting alternative (for both C and C++) would be + to force a constant to be written if and only if it is + defined in a main file, as opposed to an include file. */ + + if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) + && (! TREE_READONLY (decl) + || TREE_PUBLIC (decl) + || (!optimize && flag_keep_static_consts) + || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) + { + reconsider = 1; + rest_of_decl_compilation (decl, NULL_PTR, 1, 1); + } + + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_INITIAL (decl) != 0 + && DECL_SAVED_INSNS (decl) != 0 + && (flag_keep_inline_functions + || TREE_PUBLIC (decl) + || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) + { + reconsider = 1; + temporary_allocation (); + output_inline_function (decl); + permanent_allocation (1); + } + } + + if (reconsider) + output_something = 1; + } + while (reconsider); + + return output_something; +} + +/* Issue appropriate warnings for the global declarations in VEC (of + which there are LEN). Output debugging information for them. */ +void +check_global_declarations (vec, len) + tree *vec; + int len; +{ + tree decl; + int i; + + for (i = 0; i < len; i++) + { + decl = vec[i]; + + if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) + && ! TREE_ASM_WRITTEN (decl)) + /* Cancel the RTL for this decl so that, if debugging info + output for global variables is still to come, + this one will be omitted. */ + DECL_RTL (decl) = NULL; + + /* Warn about any function + declared static but not defined. + We don't warn about variables, + because many programs have static variables + that exist only to get some text into the object file. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && (warn_unused + || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + && DECL_INITIAL (decl) == 0 + && DECL_EXTERNAL (decl) + && ! DECL_ARTIFICIAL (decl) + && ! TREE_PUBLIC (decl)) + { + if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + pedwarn_with_decl (decl, + "`%s' used but never defined"); + else + warning_with_decl (decl, + "`%s' declared `static' but never defined"); + /* This symbol is effectively an "extern" declaration now. */ + TREE_PUBLIC (decl) = 1; + assemble_external (decl); + } + + /* Warn about static fns or vars defined but not used, + but not about inline functions or static consts + since defining those in header files is normal practice. */ + if (warn_unused + && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) + || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) + && ! DECL_IN_SYSTEM_HEADER (decl) + && ! DECL_EXTERNAL (decl) + && ! TREE_PUBLIC (decl) + && ! TREE_USED (decl) + && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) + /* The TREE_USED bit for file-scope decls + is kept in the identifier, to handle multiple + external decls in different scopes. */ + && ! TREE_USED (DECL_NAME (decl))) + warning_with_decl (decl, "`%s' defined but not used"); + +#ifdef SDB_DEBUGGING_INFO + /* The COFF linker can move initialized global vars to the end. + And that can screw up the symbol ordering. + By putting the symbols in that order to begin with, + we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ + if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL + && TREE_PUBLIC (decl) && DECL_INITIAL (decl) + && ! DECL_EXTERNAL (decl) + && DECL_RTL (decl) != 0) + TIMEVAR (symout_time, sdbout_symbol (decl, 0)); + + /* Output COFF information for non-global + file-scope initialized variables. */ + if (write_symbols == SDB_DEBUG + && TREE_CODE (decl) == VAR_DECL + && DECL_INITIAL (decl) + && ! DECL_EXTERNAL (decl) + && DECL_RTL (decl) != 0 + && GET_CODE (DECL_RTL (decl)) == MEM) + TIMEVAR (symout_time, sdbout_toplevel_data (decl)); +#endif /* SDB_DEBUGGING_INFO */ +#ifdef DWARF_DEBUGGING_INFO + /* Output DWARF information for file-scope tentative data object + declarations, file-scope (extern) function declarations (which + had no corresponding body) and file-scope tagged type declarations + and definitions which have not yet been forced out. */ + + if (write_symbols == DWARF_DEBUG + && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) + TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); +#endif +#ifdef DWARF2_DEBUGGING_INFO + /* Output DWARF2 information for file-scope tentative data object + declarations, file-scope (extern) function declarations (which + had no corresponding body) and file-scope tagged type declarations + and definitions which have not yet been forced out. */ + + if (write_symbols == DWARF2_DEBUG + && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) + TIMEVAR (symout_time, dwarf2out_decl (decl)); +#endif + } +} /* Compile an entire file of output from cpp, named NAME. Write a file of assembly output and various debugging dumps. */ @@ -3075,7 +3276,6 @@ compile_file (name) tree *vec = (tree *) alloca (sizeof (tree) * len); int i; tree decl; - int reconsider = 1; /* Process the decls in reverse order--earliest first. Put them into VEC from back to front, then take out from front. */ @@ -3083,80 +3283,8 @@ compile_file (name) for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) vec[len - i - 1] = decl; - for (i = 0; i < len; i++) - { - decl = vec[i]; - - /* We're not deferring this any longer. */ - DECL_DEFER_OUTPUT (decl) = 0; - - if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 - && incomplete_decl_finalize_hook != 0) - (*incomplete_decl_finalize_hook) (decl); - } - - /* Now emit any global variables or functions that we have been putting - off. We need to loop in case one of the things emitted here - references another one which comes earlier in the list. */ - while (reconsider) - { - reconsider = 0; - for (i = 0; i < len; i++) - { - decl = vec[i]; - - if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) - continue; - - /* Don't write out static consts, unless we still need them. - - We also keep static consts if not optimizing (for debugging), - unless the user specified -fno-keep-static-consts. - ??? They might be better written into the debug information. - This is possible when using DWARF. - - A language processor that wants static constants to be always - written out (even if it is not used) is responsible for - calling rest_of_decl_compilation itself. E.g. the C front-end - calls rest_of_decl_compilation from finish_decl. - One motivation for this is that is conventional in some - environments to write things like: - static const char rcsid[] = "... version string ..."; - intending to force the string to be in the executable. - - A language processor that would prefer to have unneeded - static constants "optimized away" would just defer writing - them out until here. E.g. C++ does this, because static - constants are often defined in header files. - - ??? A tempting alternative (for both C and C++) would be - to force a constant to be written if and only if it is - defined in a main file, as opposed to an include file. */ - - if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) - && (! TREE_READONLY (decl) - || TREE_PUBLIC (decl) - || (!optimize && flag_keep_static_consts) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) - { - reconsider = 1; - rest_of_decl_compilation (decl, NULL_PTR, 1, 1); - } - - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_INITIAL (decl) != 0 - && DECL_SAVED_INSNS (decl) != 0 - && (flag_keep_inline_functions - || TREE_PUBLIC (decl) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) - { - reconsider = 1; - temporary_allocation (); - output_inline_function (decl); - permanent_allocation (1); - } - } - } + wrapup_global_declarations (vec, len); + check_global_declarations (vec, len); /* This must occur after the loop to output deferred functions. Else the profiler initializer would not be emitted if all the functions @@ -3171,101 +3299,6 @@ compile_file (name) the exception table. */ output_exception_table (); - - for (i = 0; i < len; i++) - { - decl = vec[i]; - - if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) - && ! TREE_ASM_WRITTEN (decl)) - /* Cancel the RTL for this decl so that, if debugging info - output for global variables is still to come, - this one will be omitted. */ - DECL_RTL (decl) = NULL; - - /* Warn about any function - declared static but not defined. - We don't warn about variables, - because many programs have static variables - that exist only to get some text into the object file. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && (warn_unused - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) - && DECL_INITIAL (decl) == 0 - && DECL_EXTERNAL (decl) - && ! DECL_ARTIFICIAL (decl) - && ! TREE_PUBLIC (decl)) - { - if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) - pedwarn_with_decl (decl, - "`%s' used but never defined"); - else - warning_with_decl (decl, - "`%s' declared `static' but never defined"); - /* This symbol is effectively an "extern" declaration now. */ - TREE_PUBLIC (decl) = 1; - assemble_external (decl); - } - - /* Warn about static fns or vars defined but not used, - but not about inline functions or static consts - since defining those in header files is normal practice. */ - if (warn_unused - && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) - || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) - && ! DECL_IN_SYSTEM_HEADER (decl) - && ! DECL_EXTERNAL (decl) - && ! TREE_PUBLIC (decl) - && ! TREE_USED (decl) - && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) - /* The TREE_USED bit for file-scope decls - is kept in the identifier, to handle multiple - external decls in different scopes. */ - && ! TREE_USED (DECL_NAME (decl))) - warning_with_decl (decl, "`%s' defined but not used"); - -#ifdef SDB_DEBUGGING_INFO - /* The COFF linker can move initialized global vars to the end. - And that can screw up the symbol ordering. - By putting the symbols in that order to begin with, - we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ - if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL - && TREE_PUBLIC (decl) && DECL_INITIAL (decl) - && ! DECL_EXTERNAL (decl) - && DECL_RTL (decl) != 0) - TIMEVAR (symout_time, sdbout_symbol (decl, 0)); - - /* Output COFF information for non-global - file-scope initialized variables. */ - if (write_symbols == SDB_DEBUG - && TREE_CODE (decl) == VAR_DECL - && DECL_INITIAL (decl) - && ! DECL_EXTERNAL (decl) - && DECL_RTL (decl) != 0 - && GET_CODE (DECL_RTL (decl)) == MEM) - TIMEVAR (symout_time, sdbout_toplevel_data (decl)); -#endif /* SDB_DEBUGGING_INFO */ -#ifdef DWARF_DEBUGGING_INFO - /* Output DWARF information for file-scope tentative data object - declarations, file-scope (extern) function declarations (which - had no corresponding body) and file-scope tagged type declarations - and definitions which have not yet been forced out. */ - - if (write_symbols == DWARF_DEBUG - && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) - TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); -#endif -#ifdef DWARF2_DEBUGGING_INFO - /* Output DWARF2 information for file-scope tentative data object - declarations, file-scope (extern) function declarations (which - had no corresponding body) and file-scope tagged type declarations - and definitions which have not yet been forced out. */ - - if (write_symbols == DWARF2_DEBUG - && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) - TIMEVAR (symout_time, dwarf2out_decl (decl)); -#endif - } } /* Write out any pending weak symbol declarations. */ diff --git a/gcc/toplev.h b/gcc/toplev.h index d933a7e803e..3ffad1f5995 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -113,5 +113,6 @@ extern void fnotice PROTO ((FILE *, const char *, ...)) #undef trim_filename extern const char *trim_filename PROTO ((const char *)); - +extern int wrapup_global_declarations PROTO ((union tree_node **, int)); +extern void check_global_declarations PROTO ((union tree_node **, int)); #endif /* __GCC_TOPLEV_H */