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
This commit is contained in:
parent
6b55276ed9
commit
32291f940e
@ -1,3 +1,12 @@
|
||||
Thu Apr 22 23:08:37 1999 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* 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 <rth@cygnus.com>
|
||||
|
||||
* c-parse.in (expr_no_commas): Verify we've an expr before
|
||||
|
373
gcc/toplev.c
373
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. */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user