/* Top level of GNU C compiler
- Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
#include "rtl.h"
#include "flags.h"
#include "insn-attr.h"
+#include "defaults.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
extern int rtx_equal_function_value_matters;
+#if ! (defined (VMS) || defined (OS2))
extern char **environ;
+#endif
extern char *version_string, *language_string;
extern void init_lex ();
for the definitions of the different possible levels. */
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-/* Nonzero means can use our own extensions to DBX format.
- Relevant only when write_symbols == DBX_DEBUG or XCOFF_DEBUG. */
-int use_gdb_dbx_extensions = 0;
-#endif
+/* Nonzero means use GNU-only extensions in the generated symbolic
+ debugging information. */
+/* Currently, this only has an effect when write_symbols is set to
+ DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */
+int use_gnu_debug_info_extensions = 0;
/* Nonzero means do optimizations. -O.
Particular numeric values stand for particular amounts of optimization;
struct rtx_def *(*lang_expand_expr) ();
+/* Pointer to function to finish handling an incomplete decl at the
+ end of compilation. */
+
+void (*incomplete_decl_finalize_hook) () = 0;
+
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
int flag_caller_saves = 0;
#endif
+/* Nonzero if structures and unions should be returned in memory.
+
+ This should only be defined if compatibility with another compiler or
+ with an ABI is needed, because it results in slower code. */
+
+#ifndef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+#endif
+
/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */
-int flag_pcc_struct_return = 0;
+int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
/* Nonzero for -fforce-mem: load memory value into a register
before arithmetic on it. This makes better cse but slower compilation. */
/* Nonzero for -fdefer-pop: don't pop args after each function call;
instead save them up to pop many calls' args with one insns. */
-int flag_defer_pop = 1;
+int flag_defer_pop = 0;
/* Nonzero for -ffloat-store: don't allocate floats and doubles
in extended-precision registers. */
int flag_cse_follow_jumps;
+/* Nonzero for -fcse-skip-blocks:
+ have cse follow a branch around a block. */
+int flag_cse_skip_blocks;
+
/* Nonzero for -fexpensive-optimizations:
perform miscellaneous relatively-expensive optimizations. */
int flag_expensive_optimizations;
int flag_no_peephole = 0;
+/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
+ operations in the interest of optimization. For example it allows
+ GCC to assume arguments to sqrt are nonnegative numbers, allowing
+ faster code for sqrt to be generated. */
+
+int flag_fast_math = 0;
+
/* Nonzero means all references through pointers are volatile. */
int flag_volatile;
+/* Nonzero means treat all global and extern variables as global. */
+
+int flag_volatile_global;
+
/* Nonzero means just do syntax checking; don't output anything. */
int flag_syntax_only = 0;
int flag_inline_functions;
/* Nonzero for -fkeep-inline-functions: even if we make a function
- go inline everywhere, keep its defintion around for debugging
+ go inline everywhere, keep its definition around for debugging
purposes. */
int flag_keep_inline_functions;
needed for crtstuff.c on other systems. */
int flag_inhibit_size_directive = 0;
+/* -fverbose-asm causes extra commentary information to be produced in
+ the generated assembly code (to make it more readable). This option
+ is generally only of use to those who actually need to read the
+ generated assembly code (perhaps while debugging the compiler itself). */
+
+int flag_verbose_asm = 0;
+
/* -fgnu-linker specifies use of the GNU linker for initializations.
(Or, more generally, a linker that handles initializations.)
-fno-gnu-linker says that collect2 will be used. */
{
{"float-store", &flag_float_store, 1},
{"volatile", &flag_volatile, 1},
+ {"volatile-global", &flag_volatile_global, 1},
{"defer-pop", &flag_defer_pop, 1},
{"omit-frame-pointer", &flag_omit_frame_pointer, 1},
{"cse-follow-jumps", &flag_cse_follow_jumps, 1},
+ {"cse-skip-blocks", &flag_cse_skip_blocks, 1},
{"expensive-optimizations", &flag_expensive_optimizations, 1},
{"thread-jumps", &flag_thread_jumps, 1},
{"strength-reduce", &flag_strength_reduce, 1},
{"shared-data", &flag_shared_data, 1},
{"caller-saves", &flag_caller_saves, 1},
{"pcc-struct-return", &flag_pcc_struct_return, 1},
+ {"reg-struct-return", &flag_pcc_struct_return, 0},
{"delayed-branch", &flag_delayed_branch, 1},
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
{"pretend-float", &flag_pretend_float, 1},
{"schedule-insns2", &flag_schedule_insns_after_reload, 1},
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
+ {"fast-math", &flag_fast_math, 1},
{"common", &flag_no_common, 0},
{"inhibit-size-directive", &flag_inhibit_size_directive, 1},
+ {"verbose-asm", &flag_verbose_asm, 1},
{"gnu-linker", &flag_gnu_linker, 1}
};
+
+/* Table of language-specific options. */
+
+char *lang_options[] =
+{
+ "-ftraditional",
+ "-traditional",
+ "-fnotraditional",
+ "-fno-traditional",
+ "-fsigned-char",
+ "-funsigned-char",
+ "-fno-signed-char",
+ "-fno-unsigned-char",
+ "-fsigned-bitfields",
+ "-funsigned-bitfields",
+ "-fno-signed-bitfields",
+ "-fno-unsigned-bitfields",
+ "-fshort-enums",
+ "-fno-short-enums",
+ "-fcond-mismatch",
+ "-fno-cond-mismatch",
+ "-fshort-double",
+ "-fno-short-double",
+ "-fasm",
+ "-fno-asm",
+ "-fbuiltin",
+ "-fno-builtin",
+ "-fno-ident",
+ "-fident",
+ "-fdollars-in-identifiers",
+ "-fnodollars-in-identifiers",
+ "-ansi",
+ "-Wimplicit",
+ "-Wno-implicit",
+ "-Wwrite-strings",
+ "-Wno-write-strings",
+ "-Wcast-qual",
+ "-Wno-cast-qual",
+ "-Wpointer-arith",
+ "-Wno-pointer-arith",
+ "-Wstrict-prototypes",
+ "-Wno-strict-prototypes",
+ "-Wmissing-prototypes",
+ "-Wno-missing-prototypes",
+ "-Wredundant-decls",
+ "-Wno-redundant-decls",
+ "-Wnested-externs",
+ "-Wno-nested-externs",
+ "-Wtraditional",
+ "-Wno-traditional",
+ "-Wformat",
+ "-Wno-format",
+ "-Wchar-subscripts",
+ "-Wno-char-subscripts",
+ "-Wconversion",
+ "-Wno-conversion",
+ "-Wparentheses",
+ "-Wno-parentheses",
+ "-Wcomment",
+ "-Wno-comment",
+ "-Wcomments",
+ "-Wno-comments",
+ "-Wtrigraphs",
+ "-Wno-trigraphs",
+ "-Wimport",
+ "-Wno-import",
+ "-Wmissing-braces",
+ "-Wno-missing-braces",
+ "-Wall",
+
+ /* These are for C++. */
+ "-+e0", /* gcc.c tacks the `-' on the front. */
+ "-+e1",
+ "-+e2",
+ "-fsave-memoized",
+ "-fno-save-memoized",
+ "-fcadillac",
+ "-fno-cadillac",
+ "-fgc",
+ "-fno-gc",
+ "-flabels-ok",
+ "-fno-labels-ok",
+ "-fstats",
+ "-fno-stats",
+ "-fthis-is-variable",
+ "-fno-this-is-variable",
+ "-fstrict-prototype",
+ "-fno-strict-prototype",
+ "-fall-virtual",
+ "-fno-all-virtual",
+ "-fmemoize-lookups",
+ "-fno-memoize-lookups",
+ "-felide-constructors",
+ "-fno-elide-constructors",
+ "-finline-debug",
+ "-fno-inline-debug",
+ "-fhandle-exceptions",
+ "-fno-handle-exceptions",
+ "-fansi-exceptions",
+ "-fno-ansi-exceptions",
+ "-fspring-exceptions",
+ "-fno-spring-exceptions",
+ "-fdefault-inline",
+ "-fno-default-inline",
+ "-fenum-int-equiv",
+ "-fno-enum-int-equiv",
+ "-fdossier",
+ "-fno-dossier",
+ "-fxref",
+ "-fno-xref",
+ "-fnonnull-objects",
+ "-fno-nonnull-objects",
+ "-fimplement-inlines",
+ "-fno-implement-inlines",
+ "-fexternal-templates",
+ "-fno-external-templates",
+
+ "-Wreturn-type",
+ "-Wno-return-type",
+ "-Woverloaded-virtual",
+ "-Wno-overloaded-virtual",
+ "-Wenum-clash",
+ "-Wno-enum-clash",
+ "-Wtemplate-debugging",
+ "-Wno-template-debugging",
+ "-Wctor-dtor-privacy",
+ "-Wno-ctor-dtor-privacy",
+
+ /* these are for obj c */
+ "-lang-objc",
+ "-gen-decls",
+ "-fgnu-runtime",
+ "-fno-gnu-runtime",
+ "-fnext-runtime",
+ "-fno-next-runtime",
+ "-Wselector",
+ "-Wno-selector",
+ "-Wprotocol",
+ "-Wno-protocol",
+ 0
+};
\f
/* Options controlling warnings */
{"error", &warnings_are_errors, 1},
{"shadow", &warn_shadow, 1},
{"switch", &warn_switch, 1},
- {"return-type", &warn_return_type, 1},
{"aggregate-return", &warn_aggregate_return, 1},
{"cast-align", &warn_cast_align, 1},
{"uninitialized", &warn_uninitialized, 1},
{
fprintf (stderr, " from %s:%d", p->name, p->line);
if (p->next)
- fprintf (stderr, ",");
+ fprintf (stderr, ",\n ");
}
fprintf (stderr, ":\n");
last_error_tick = input_file_stack_tick;
}
/* Report an error at the current line number.
- S and V are a string and an arg for `printf'. */
+ S is a string and V and V2 are args for `printf'. We use HOST_WIDE_INT
+ as the type for these args assuming it is wide enough to hold a
+ pointer. This isn't terribly portable, but is the best we can do
+ without vprintf universally available. */
void
error (s, v, v2)
char *s;
- int v; /* @@also used as pointer */
- int v2; /* @@also used as pointer */
+ HOST_WIDE_INT v; /* Also used as pointer */
+ HOST_WIDE_INT v2; /* Also used as pointer */
{
error_with_file_and_line (input_filename, lineno, s, v, v2);
}
char *file;
int line;
char *s;
- int v;
- int v2;
+ HOST_WIDE_INT v;
+ HOST_WIDE_INT v2;
{
count_error (0);
}
/* Report an error at the declaration DECL.
- S and V are a string and an arg which uses %s to substitute the declaration name. */
+ S and V are a string and an arg which uses %s to substitute
+ the declaration name. */
void
error_with_decl (decl, s, v)
tree decl;
char *s;
- int v;
+ HOST_WIDE_INT v;
{
char *junk;
count_error (0);
error_for_asm (insn, s, v, v2)
rtx insn;
char *s;
- int v; /* @@also used as pointer */
- int v2; /* @@also used as pointer */
+ HOST_WIDE_INT v; /* Also used as pointer */
+ HOST_WIDE_INT v2; /* Also used as pointer */
{
char *filename;
int line;
char *file;
int line;
char *s;
- int v;
- int v2;
- int v3;
+ HOST_WIDE_INT v, v2, v3;
{
if (count_error (1) == 0)
return;
void
warning (s, v, v2, v3)
char *s;
- int v; /* @@also used as pointer */
- int v2;
- int v3;
+ HOST_WIDE_INT v, v2, v3; /* Also used as pointer */
{
warning_with_file_and_line (input_filename, lineno, s, v, v2, v3);
}
warning_with_decl (decl, s, v)
tree decl;
char *s;
- int v;
+ HOST_WIDE_INT v;
{
char *junk;
warning_for_asm (insn, s, v, v2)
rtx insn;
char *s;
- int v; /* @@also used as pointer */
- int v2; /* @@also used as pointer */
+ HOST_WIDE_INT v; /* Also used as pointer */
+ HOST_WIDE_INT v2; /* Also used as pointer */
{
char *filename;
int line;
void
pedwarn (s, v, v2)
char *s;
- int v; /* @@also used as pointer */
- int v2;
+ HOST_WIDE_INT v; /* Also used as pointer */
+ HOST_WIDE_INT v2;
{
if (flag_pedantic_errors)
error (s, v, v2);
pedwarn_with_decl (decl, s, v)
tree decl;
char *s;
- int v;
+ HOST_WIDE_INT v;
{
if (flag_pedantic_errors)
error_with_decl (decl, s, v);
char *file;
int line;
char *s;
- int v;
- int v2;
+ HOST_WIDE_INT v;
+ HOST_WIDE_INT v2;
{
if (flag_pedantic_errors)
error_with_file_and_line (file, line, s, v, v2);
void
sorry (s, v, v2)
char *s;
- int v, v2;
+ HOST_WIDE_INT v, v2;
{
sorrycount++;
if (input_filename)
void
really_sorry (s, v, v2)
char *s;
- int v, v2;
+ HOST_WIDE_INT v, v2;
{
if (input_filename)
fprintf (stderr, "%s:%d: ", input_filename, lineno);
else
- fprintf (stderr, "c++: ");
+ fprintf (stderr, "%s: ", progname);
fprintf (stderr, "sorry, not implemented: ");
fprintf (stderr, s, v, v2);
/* Same as `malloc' but report error if no memory available. */
-int
+char *
xmalloc (size)
unsigned size;
{
- register int value = (int) malloc (size);
+ register char *value = (char *) malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
/* Same as `realloc' but report error if no memory available. */
-int
+char *
xrealloc (ptr, size)
char *ptr;
int size;
{
- int result = realloc (ptr, size);
+ char *result = (char *) realloc (ptr, size);
if (!result)
fatal ("virtual memory exhausted");
return result;
}
\f
/* Return the logarithm of X, base 2, considering X unsigned,
- if X is a power of 2. Otherwise, returns -1. */
+ if X is a power of 2. Otherwise, returns -1.
+
+ This should be used via the `exact_log2' macro. */
int
-exact_log2 (x)
- register unsigned int x;
+exact_log2_wide (x)
+ register unsigned HOST_WIDE_INT x;
{
register int log = 0;
/* Test for 0 or a power of 2. */
}
/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
- If X is 0, return -1. */
+ If X is 0, return -1.
+
+ This should be used via the floor_log2 macro. */
int
-floor_log2 (x)
- register unsigned int x;
+floor_log2_wide (x)
+ register unsigned HOST_WIDE_INT x;
{
register int log = -1;
while (x != 0)
bcopy (handler, float_handler, sizeof (float_handler));
}
+/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
+ error happens, pushing the previous specification into OLD_HANDLER.
+ Return an indication of whether there was a previous handler in effect. */
+
+int
+push_float_handler (handler, old_handler)
+ jmp_buf handler, old_handler;
+{
+ int was_handled = float_handled;
+
+ float_handled = 1;
+ if (was_handled)
+ bcopy (float_handler, old_handler, sizeof (float_handler));
+ bcopy (handler, float_handler, sizeof (float_handler));
+ return was_handled;
+}
+
+/* Restore the previous specification of whether and where to longjmp to
+ when a floating arithmetic error happens. */
+
+void
+pop_float_handler (handled, handler)
+ int handled;
+ jmp_buf handler;
+{
+ float_handled = handled;
+ if (handled)
+ bcopy (handler, float_handler, sizeof (float_handler));
+}
+
/* Signals actually come here. */
static void
name[len - 3] = 0;
else if (len > 3 && ! strcmp (".cc", name + len - 3))
name[len - 3] = 0;
+ else if (len > 2 && ! strcmp (".C", name + len - 2))
+ name[len - 2] = 0;
+ else if (len > 4 && ! strcmp (".cxx", name + len - 4))
+ name[len - 4] = 0;
else if (len > 2 && ! strcmp (".f", name + len - 2))
name[len - 2] = 0;
else if (len > 4 && ! strcmp (".ada", name + len - 4))
name[len - 4] = 0;
+ else if (len > 4 && ! strcmp (".atr", name + len - 4))
+ name[len - 4] = 0;
}
/* Output a file name in the form wanted by System V. */
#endif
}
\f
+/* Routine to build language identifier for object file. */
+static void
+output_lang_identify (asm_out_file)
+ FILE *asm_out_file;
+{
+ int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
+ char *s = (char *) alloca (len);
+ sprintf (s, "__gnu_compiled_%s", lang_identify ());
+ ASM_OUTPUT_LABEL (asm_out_file, s);
+}
+
/* Compile an entire file of output from cpp, named NAME.
Write a file of assembly output and various debugging dumps. */
if (finput == 0)
pfatal_with_name (name);
+#ifdef IO_BUFFER_SIZE
+ setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+#endif
+
/* Initialize data in various passes. */
init_obstacks ();
init_optabs ();
init_stmt ();
init_expmed ();
+ init_expr_once ();
init_loop ();
init_reload ();
}
#ifdef IO_BUFFER_SIZE
- setvbuf (asm_out_file, xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+ setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+ _IOFBF, IO_BUFFER_SIZE);
#endif
input_filename = name;
#else
ASM_IDENTIFY_GCC (asm_out_file);
#endif
+
+ /* Output something to identify which front-end produced this file. */
+#ifdef ASM_IDENTIFY_LANGUAGE
+ ASM_IDENTIFY_LANGUAGE (asm_out_file);
+#endif
+
+/* ??? Note: There used to be a conditional here
+ to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
+ This was to guarantee separation between gcc_compiled. and
+ the first function, for the sake of dbx on Suns.
+ However, having the extra zero here confused the Emacs
+ code for unexec, and might confuse other programs too.
+ Therefore, I took out that change.
+ In future versions we should find another way to solve
+ that dbx problem. -- rms, 23 May 93. */
+
/* Don't let the first function fall at the same address
as gcc_compiled., if profiling. */
if (profile_flag || profile_block_flag)
for (i = 0; i < len; i++)
{
decl = vec[i];
+ if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
+ && incomplete_decl_finalize_hook != 0)
+ (*incomplete_decl_finalize_hook) (decl);
+
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& ! TREE_ASM_WRITTEN (decl))
{
|| TREE_USED (decl)
|| TREE_ADDRESSABLE (decl)
|| TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl)))
- rest_of_decl_compilation (decl, 0, 1, 1);
+ rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
else
/* Cancel the RTL for this decl so that, if debugging info
output for global variables is still to come,
&& DECL_INITIAL (decl) != 0
&& (TREE_ADDRESSABLE (decl)
|| TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl)))
- && ! TREE_EXTERNAL (decl))
- output_inline_function (decl);
+ && ! DECL_EXTERNAL (decl))
+ {
+ temporary_allocation ();
+ output_inline_function (decl);
+ permanent_allocation ();
+ }
/* Warn about any function
declared static but not defined.
|| (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl))))
&& TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl) == 0
- && TREE_EXTERNAL (decl)
+ && DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl))
- warning_with_decl (decl, "`%s' declared `static' but never defined");
+ {
+ /* This should be a pedwarn, except that there is
+ no easy way to prevent it from happening when the
+ name is used only inside a sizeof.
+ This at least avoids being incorrect. */
+ 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
since unused inline statics is normal practice. */
if (warn_unused
&& (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
- && ! TREE_EXTERNAL (decl)
+ && ! DECL_IN_SYSTEM_HEADER (decl)
+ && ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
&& ! TREE_USED (decl)
- && ! TREE_INLINE (decl)
+ && ! DECL_INLINE (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. */
TIMEVAR (symout_time, sdbout_toplevel_data (decl));
#endif /* SDB_DEBUGGING_INFO */
#ifdef DWARF_DEBUGGING_INFO
- /* Output DWARF information for file-scope tenative data object
+ /* 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. */
/* Forward declarations for nested functions are not "external",
but we need to treat them as if they were. */
- if (TREE_STATIC (decl) || TREE_EXTERNAL (decl)
+ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| TREE_CODE (decl) == FUNCTION_DECL)
TIMEVAR (varconst_time,
{
make_decl_rtl (decl, asmspec, top_level);
- /* Don't output anything
- when a tentative file-scope definition is seen.
- But at end of compilation, do output code for them. */
- if (! (! at_end && top_level
- && (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node)))
- assemble_variable (decl, top_level, at_end);
+ /* For a user-invisible decl that should be replaced
+ by its value when used, don't output anything. */
+ if (! (TREE_CODE (decl) == VAR_DECL
+ && DECL_IGNORED_P (decl) && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != 0))
+ /* Don't output anything
+ when a tentative file-scope definition is seen.
+ But at end of compilation, do output code for them. */
+ if (! (! at_end && top_level
+ && (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node
+ || DECL_IGNORED_P (decl))))
+ assemble_variable (decl, top_level, at_end);
});
- else if (TREE_REGDECL (decl) && asmspec != 0)
+ else if (DECL_REGISTER (decl) && asmspec != 0)
{
if (decode_reg_name (asmspec) >= 0)
{
to be restored after we finish compiling the function
(for use when compiling inline calls to this function). */
tree saved_block_tree = 0;
+ /* Likewise, for DECL_ARGUMENTS. */
+ tree saved_arguments = 0;
+ int failure = 0;
/* If we are reconsidering an inline function
at the end of compilation, skip the stuff for making it inline. */
if (DECL_SAVED_INSNS (decl) == 0)
{
- int specd = TREE_INLINE (decl);
+ int specd = DECL_INLINE (decl);
char *lose;
/* If requested, consider whether to make this function inline. */
{
if (warn_inline && specd)
warning_with_decl (decl, lose);
- TREE_INLINE (decl) = 0;
+ DECL_INLINE (decl) = 0;
}
else
- TREE_INLINE (decl) = 1;
+ DECL_INLINE (decl) = 1;
});
insns = get_insns ();
finish_compilation will call rest_of_compilation again
for those functions that need to be output. */
- if (TREE_INLINE (decl)
+ if (DECL_INLINE (decl)
&& ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
&& ! flag_keep_inline_functions)
- || TREE_EXTERNAL (decl)))
+ || DECL_EXTERNAL (decl)))
{
+#ifdef DWARF_DEBUGGING_INFO
+ /* Generate the DWARF info for the "abstract" instance
+ of a function which we may later generate inlined and/or
+ out-of-line instances of. */
+ if (write_symbols == DWARF_DEBUG)
+ {
+ set_decl_abstract_flags (decl, 1);
+ TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+ set_decl_abstract_flags (decl, 0);
+ }
+#endif
TIMEVAR (integration_time, save_for_inline_nocopy (decl));
goto exit_rest_of_compilation;
}
- /* If we have to compile the function now, save its rtl
+ /* If we have to compile the function now, save its rtl and subdecls
so that its compilation will not affect what others get. */
- if (TREE_INLINE (decl))
+ if (DECL_INLINE (decl))
{
+#ifdef DWARF_DEBUGGING_INFO
+ /* Generate the DWARF info for the "abstract" instance of
+ a function which we will generate an out-of-line instance
+ of almost immediately (and which we may also later generate
+ various inlined instances of). */
+ if (write_symbols == DWARF_DEBUG)
+ {
+ set_decl_abstract_flags (decl, 1);
+ TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+ set_decl_abstract_flags (decl, 0);
+ }
+#endif
saved_block_tree = DECL_INITIAL (decl);
+ saved_arguments = DECL_ARGUMENTS (decl);
TIMEVAR (integration_time, save_for_inline_copying (decl));
}
}
- /* Suppress warnings for unused static functions
- defined (not just declared) in system headers. */
- if (in_system_header && TREE_STATIC (decl) && !TREE_INLINE (decl))
- TREE_USED (decl) = 1;
-
TREE_ASM_WRITTEN (decl) = 1;
/* Now that integrate will no longer see our rtl, we need not distinguish
functions. */
rtx_equal_function_value_matters = 0;
- if (rtl_dump_and_exit || flag_syntax_only)
+ /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
+ if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
{
goto exit_rest_of_compilation;
}
TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
}
+ /* Now is when we stop if -fsyntax-only and -Wreturn-type. */
+ if (rtl_dump_and_exit || flag_syntax_only)
+ goto exit_rest_of_compilation;
+
/* Dump rtl code after jump, if we are doing that. */
if (jump_opt_dump)
{
TIMEVAR (loop_time,
{
- loop_optimize (insns, loop_dump ? loop_dump_file : 0);
+ loop_optimize (insns, loop_dump_file);
});
}
TIMEVAR (global_alloc_time,
{
if (!obey_regdecls)
- global_alloc (global_reg_dump ? global_reg_dump_file : 0);
+ failure = global_alloc (global_reg_dump_file);
else
- reload (insns, 0,
- global_reg_dump ? global_reg_dump_file : 0);
+ failure = reload (insns, 0, global_reg_dump_file);
});
if (global_reg_dump)
fflush (global_reg_dump_file);
});
+ if (failure)
+ goto exit_rest_of_compilation;
+
reload_completed = 1;
+ /* On some machines, the prologue and epilogue code, or parts thereof,
+ can be represented as RTL. Doing so lets us schedule insns between
+ it and the rest of the code and also allows delayed branch
+ scheduling to operate in the epilogue. */
+
+ thread_prologue_and_epilogue_insns (insns);
+
if (optimize > 0 && flag_schedule_insns_after_reload)
{
if (sched2_dump)
#ifdef LEAF_REGISTERS
leaf_function = 0;
if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
- leaf_function = 1;
+ leaf_function = 1;
#endif
/* One more attempt to remove jumps to .+1
queued up for sdb output. */
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
- sdbout_types (0);
+ sdbout_types (NULL_TREE);
#endif
- /* Put back the tree of subblocks from before we copied it.
+ /* Put back the tree of subblocks and list of arguments
+ from before we copied them.
Code generation and the output of debugging info may have modified
the copy, but the original is unchanged. */
if (saved_block_tree != 0)
DECL_INITIAL (decl) = saved_block_tree;
+ if (saved_arguments != 0)
+ DECL_ARGUMENTS (decl) = saved_arguments;
reload_completed = 0;
signal (SIGFPE, float_signal);
+#ifdef SIGPIPE
signal (SIGPIPE, pipe_closed);
+#endif
decl_printable_name = decl_name;
lang_expand_expr = (struct rtx_def *(*)()) do_abort;
if (optimize >= 1)
{
+ flag_defer_pop = 1;
flag_thread_jumps = 1;
#ifdef DELAY_SLOTS
flag_delayed_branch = 1;
if (optimize >= 2)
{
flag_cse_follow_jumps = 1;
+ flag_cse_skip_blocks = 1;
flag_expensive_optimizations = 1;
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
for (i = 1; i < argc; i++)
{
- if (argv[i][0] == '-' && argv[i][1] != 0)
+ int j;
+ /* If this is a language-specific option,
+ decode it in a language-specific way. */
+ for (j = 0; lang_options[j] != 0; j++)
+ if (!strncmp (argv[i], lang_options[j],
+ strlen (lang_options[j])))
+ break;
+ if (lang_options[j] != 0)
+ /* If the option is valid for *some* language,
+ treat it as valid even if this language doesn't understand it. */
+ lang_decode_option (argv[i]);
+ else if (argv[i][0] == '-' && argv[i][1] != 0)
{
register char *str = argv[i] + 1;
if (str[0] == 'Y')
}
else if (str[0] == 'f')
{
- int j;
register char *p = &str[1];
int found = 0;
fix_register (&p[10], 0, 1);
else if (!strncmp (p, "call-saved-", 11))
fix_register (&p[11], 0, 0);
- else if (! lang_decode_option (argv[i]))
+ else
error ("Invalid option `%s'", argv[i]);
}
else if (str[0] == 'O')
pedantic = 1;
else if (!strcmp (str, "pedantic-errors"))
flag_pedantic_errors = pedantic = 1;
- else if (lang_decode_option (argv[i]))
- ;
else if (!strcmp (str, "quiet"))
quiet_flag = 1;
else if (!strcmp (str, "version"))
}
else if (str[0] == 'W')
{
- int j;
register char *p = &str[1];
int found = 0;
if (*endp >= '0' && *endp <= '9')
endp++;
else
- error ("Invalid option `%s'", argv[i]);
+ {
+ error ("Invalid option `%s'", argv[i]);
+ goto id_clash_lose;
+ }
}
warn_id_clash = 1;
id_clash_len = atoi (str + 10);
+ id_clash_lose: ;
}
else
error ("Invalid option `%s'", argv[i]);
/* If more than one debugging type is supported,
you must define PREFERRED_DEBUGGING_TYPE
to choose a format in a system-dependent way. */
-#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) \
- + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
+ /* This is one long line cause VAXC can't handle a \-newline. */
+#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
#ifdef PREFERRED_DEBUGGING_TYPE
if (!strncmp (str, "ggdb", len))
write_symbols = PREFERRED_DEBUGGING_TYPE;
write_symbols = DBX_DEBUG;
else if (!strncmp (str, "gstabs", len))
write_symbols = DBX_DEBUG;
+ else if (!strncmp (str, "gstabs+", len))
+ write_symbols = DBX_DEBUG;
/* Always enable extensions for -ggdb or -gstabs+,
always disable for -gstabs.
For plain -g, use system-specific default. */
if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len)
&& len >= 2)
- use_gdb_dbx_extensions = 1;
- else if (write_symbols == DBX_DEBUG && !strcmp (str, "gstabs+"))
- use_gdb_dbx_extensions = 1;
+ use_gnu_debug_info_extensions = 1;
+ else if (write_symbols == DBX_DEBUG && !strncmp (str, "gstabs+", len)
+ && len >= 7)
+ use_gnu_debug_info_extensions = 1;
else if (write_symbols == DBX_DEBUG
&& !strncmp (str, "gstabs", len) && len >= 2)
- use_gdb_dbx_extensions = 0;
+ use_gnu_debug_info_extensions = 0;
else
- use_gdb_dbx_extensions = DEFAULT_GDB_EXTENSIONS;
+ use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
#endif /* DBX_DEBUGGING_INFO */
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols != NO_DEBUG)
;
+ else if (!strncmp (str, "g", len))
+ write_symbols = DWARF_DEBUG;
else if (!strncmp (str, "ggdb", len))
write_symbols = DWARF_DEBUG;
- /* For orthogonality. */
else if (!strncmp (str, "gdwarf", len))
write_symbols = DWARF_DEBUG;
+
+ /* Always enable extensions for -ggdb or -gdwarf+,
+ always disable for -gdwarf.
+ For plain -g, use system-specific default. */
+ if (write_symbols == DWARF_DEBUG && !strncmp (str, "ggdb", len)
+ && len >= 2)
+ use_gnu_debug_info_extensions = 1;
+ else if (write_symbols == DWARF_DEBUG && !strcmp (str, "gdwarf+"))
+ use_gnu_debug_info_extensions = 1;
+ else if (write_symbols == DWARF_DEBUG
+ && !strncmp (str, "gdwarf", len) && len >= 2)
+ use_gnu_debug_info_extensions = 0;
+ else
+ use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols != NO_DEBUG)
;
- else if (!strncmp (str, "ggdb", len))
+ else if (!strncmp (str, "g", len))
+ write_symbols = SDB_DEBUG;
+ else if (!strncmp (str, "gdb", len))
write_symbols = SDB_DEBUG;
else if (!strncmp (str, "gcoff", len))
write_symbols = SDB_DEBUG;
#ifdef XCOFF_DEBUGGING_INFO
if (write_symbols != NO_DEBUG)
;
+ else if (!strncmp (str, "g", len))
+ write_symbols = XCOFF_DEBUG;
else if (!strncmp (str, "ggdb", len))
write_symbols = XCOFF_DEBUG;
else if (!strncmp (str, "gxcoff", len))
write_symbols = XCOFF_DEBUG;
- /* Always enable extensions for -ggdb,
+ /* Always enable extensions for -ggdb or -gxcoff+,
always disable for -gxcoff.
For plain -g, use system-specific default. */
if (write_symbols == XCOFF_DEBUG && !strncmp (str, "ggdb", len)
&& len >= 2)
- use_gdb_dbx_extensions = 1;
- else if (write_symbols == DBX_DEBUG
+ use_gnu_debug_info_extensions = 1;
+ else if (write_symbols == XCOFF_DEBUG && !strcmp (str, "gxcoff+"))
+ use_gnu_debug_info_extensions = 1;
+ else if (write_symbols == XCOFF_DEBUG
&& !strncmp (str, "gxcoff", len) && len >= 2)
- use_gdb_dbx_extensions = 0;
+ use_gnu_debug_info_extensions = 0;
else
- use_gdb_dbx_extensions = DEFAULT_GDB_EXTENSIONS;
+ use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
#endif
if (write_symbols == NO_DEBUG)
warning ("`-%s' option not supported on this version of GCC", str);
error ("Invalid option `%s'", argv[i]);
}
else if (argv[i][0] == '+')
- {
- if (lang_decode_option (argv[i]))
- ;
- else
- error ("Invalid option `%s'", argv[i]);
- }
+ error ("Invalid option `%s'", argv[i]);
else
filename = argv[i];
}
- /* Inlining does not work if not optimizing,
- so force it not to be done. */
if (optimize == 0)
{
+ /* Inlining does not work if not optimizing,
+ so force it not to be done. */
flag_no_inline = 1;
warn_inline = 0;
+
+ /* The c_decode_option and lang_decode_option functions set
+ this to `2' if -Wall is used, so we can avoid giving out
+ lots of errors for people who don't realize what -Wall does. */
+ if (warn_uninitialized == 1)
+ warning ("-Wuninitialized is not supported without -O");
+ }
+
+#if defined(DWARF_DEBUGGING_INFO)
+ if (write_symbols == DWARF_DEBUG
+ && strcmp (language_string, "GNU C++") == 0)
+ {
+ warning ("-g option not supported for C++ on SVR4 systems");
+ write_symbols = NO_DEBUG;
}
+#endif /* defined(DWARF_DEBUGGING_INFO) */
#ifdef OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of options. */
compile_file (filename);
+#ifndef OS2
#ifndef VMS
if (flag_print_mem)
{
char *lim = (char *) sbrk (0);
fprintf (stderr, "Data size %d.\n",
- (int) lim - (int) &environ);
+ lim - (char *) &environ);
fflush (stderr);
#ifdef USG
#endif /* not USG */
}
#endif /* not VMS */
+#endif /* not OS2 */
if (errorcount)
exit (FATAL_EXIT_CODE);