toplev.c revision 69460
119370Spst/* Top level of GNU C compiler
219370Spst   Copyright (C) 1987, 88, 89, 92-99, 2000 Free Software Foundation, Inc.
398944Sobrien
4130803SmarcelThis file is part of GNU CC.
5130803Smarcel
619370SpstGNU CC is free software; you can redistribute it and/or modify
798944Sobrienit under the terms of the GNU General Public License as published by
819370Spstthe Free Software Foundation; either version 2, or (at your option)
998944Sobrienany later version.
1098944Sobrien
1198944SobrienGNU CC is distributed in the hope that it will be useful,
1298944Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1319370SpstMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1498944SobrienGNU General Public License for more details.
1598944Sobrien
1698944SobrienYou should have received a copy of the GNU General Public License
1798944Sobrienalong with GNU CC; see the file COPYING.  If not, write to
1819370Spstthe Free Software Foundation, 59 Temple Place - Suite 330,
1998944SobrienBoston, MA 02111-1307, USA.  */
2098944Sobrien
2198944Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 69460 2000-12-01 10:20:17Z obrien $ */
2298944Sobrien
2398944Sobrien/* This is the top level of cc1/c++.
2446283Sdfr   It parses command args, opens files, invokes the various passes
2519370Spst   in the proper order, and counts the time used by each.
2619370Spst   Error messages and low-level interface to malloc also handled here.  */
2719370Spst
2819370Spst#include "config.h"
2919370Spst#undef FLOAT /* This is for hpux. They should change hpux.  */
3019370Spst#undef FFS  /* Some systems define this in param.h.  */
3119370Spst#include "system.h"
3219370Spst#include <signal.h>
3319370Spst#include <setjmp.h>
3419370Spst
3519370Spst#ifdef HAVE_SYS_RESOURCE_H
36130803Smarcel# include <sys/resource.h>
3719370Spst#endif
3819370Spst
3919370Spst#ifdef HAVE_SYS_TIMES_H
4019370Spst# include <sys/times.h>
4198944Sobrien#endif
42130803Smarcel
43130803Smarcel#include "input.h"
44130803Smarcel#include "tree.h"
45130803Smarcel#include "rtl.h"
46130803Smarcel#include "flags.h"
47130803Smarcel#include "insn-attr.h"
4819370Spst#include "insn-codes.h"
4946283Sdfr#include "insn-config.h"
5046283Sdfr#include "recog.h"
5198944Sobrien#include "defaults.h"
5246283Sdfr#include "output.h"
5398944Sobrien#include "except.h"
5446283Sdfr#include "toplev.h"
5598944Sobrien#include "expr.h"
5646283Sdfr#include "basic-block.h"
5798944Sobrien#include "intl.h"
5846283Sdfr
5946283Sdfr#ifdef DWARF_DEBUGGING_INFO
6046283Sdfr#include "dwarfout.h"
6198944Sobrien#endif
6219370Spst
6398944Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
6446283Sdfr#include "dwarf2out.h"
6598944Sobrien#endif
6619370Spst
6798944Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
6819370Spst#include "dbxout.h"
6998944Sobrien#endif
7046283Sdfr
7198944Sobrien#ifdef SDB_DEBUGGING_INFO
7219370Spst#include "sdbout.h"
7398944Sobrien#endif
7419370Spst
7598944Sobrien#ifdef XCOFF_DEBUGGING_INFO
7619370Spst#include "xcoffout.h"
7798944Sobrien#endif
7819370Spst
7998944Sobrien#ifdef VMS
8019370Spst/* The extra parameters substantially improve the I/O performance.  */
8198944Sobrienstatic FILE *
8219370Spstvms_fopen (fname, type)
8398944Sobrien     char * fname;
8498944Sobrien     char * type;
8519370Spst{
8698944Sobrien  /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
8798944Sobrien     fixed arguments, which matches ANSI's specification but not VAXCRTL's
8819370Spst     pre-ANSI implementation.  This hack circumvents the mismatch problem.  */
8998944Sobrien  FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
9098944Sobrien
9119370Spst  if (*type == 'w')
9298944Sobrien    return (*vmslib_fopen) (fname, type, "mbc=32",
9398944Sobrien			    "deq=64", "fop=tef", "shr=nil");
9498944Sobrien  else
9598944Sobrien    return (*vmslib_fopen) (fname, type, "mbc=32");
9646283Sdfr}
9798944Sobrien#define fopen vms_fopen
9898944Sobrien#endif	/* VMS */
9998944Sobrien
10098944Sobrien#ifndef DEFAULT_GDB_EXTENSIONS
10198944Sobrien#define DEFAULT_GDB_EXTENSIONS 1
10219370Spst#endif
10398944Sobrien
10498944Sobrien/* If more than one debugging type is supported, you must define
10598944Sobrien   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way.
10698944Sobrien
10798944Sobrien   This is one long line cause VAXC can't handle a \-newline.  */
10898944Sobrien#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
10919370Spst#ifndef PREFERRED_DEBUGGING_TYPE
11019370SpstYou Lose!  You must define PREFERRED_DEBUGGING_TYPE!
11119370Spst#endif /* no PREFERRED_DEBUGGING_TYPE */
11219370Spst#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
11319370Spst	 so the following code needn't care.  */
11419370Spst#ifdef DBX_DEBUGGING_INFO
11519370Spst#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
11619370Spst#endif
11719370Spst#ifdef SDB_DEBUGGING_INFO
11819370Spst#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
11919370Spst#endif
12098944Sobrien#ifdef DWARF_DEBUGGING_INFO
12198944Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
12298944Sobrien#endif
12398944Sobrien#ifdef DWARF2_DEBUGGING_INFO
12498944Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
12598944Sobrien#endif
12698944Sobrien#ifdef XCOFF_DEBUGGING_INFO
12719370Spst#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
12846283Sdfr#endif
12946283Sdfr#endif /* More than one debugger format enabled.  */
13098944Sobrien
13146283Sdfr/* If still not defined, must have been because no debugging formats
13298944Sobrien   are supported.  */
13346283Sdfr#ifndef PREFERRED_DEBUGGING_TYPE
13498944Sobrien#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
13546283Sdfr#endif
136130803Smarcel
13746283Sdfr#ifndef DIR_SEPARATOR
13846283Sdfr#define DIR_SEPARATOR '/'
13946283Sdfr#endif
140130803Smarcel
14119370Spstextern int rtx_equal_function_value_matters;
14219370Spst
14319370Spst#if ! (defined (VMS) || defined (OS2))
14419370Spstextern char **environ;
14519370Spst#endif
14619370Spstextern char *version_string, *language_string;
14719370Spst
14819370Spst/* Carry information from ASM_DECLARE_OBJECT_NAME
14919370Spst   to ASM_FINISH_DECLARE_OBJECT.  */
150130803Smarcel
151130803Smarcelextern int size_directive_output;
15246283Sdfrextern tree last_assemble_variable_decl;
15346283Sdfr
15446283Sdfrextern char *init_parse PVPROTO((char *));
15546283Sdfrextern void finish_parse ();
15646283Sdfrextern void init_decl_processing ();
15746283Sdfrextern void init_obstacks ();
15846283Sdfrextern void init_tree_codes ();
15946283Sdfrextern void init_rtl ();
160130803Smarcelextern void init_regs ();
161130803Smarcelextern void init_optabs ();
162130803Smarcelextern void init_stmt ();
163130803Smarcelextern void init_reg_sets ();
164130803Smarcelextern void dump_flow_info ();
165130803Smarcelextern void dump_sched_info ();
166130803Smarcelextern void dump_local_alloc ();
167130803Smarcelextern void regset_release_memory ();
168130803Smarcel
169130803Smarcelextern void print_rtl ();
170130803Smarcelextern void print_rtl_with_bb ();
171130803Smarcel
172130803Smarcelvoid rest_of_decl_compilation ();
173130803Smarcelvoid error_with_file_and_line PVPROTO((const char *file,
174130803Smarcel				       int line, const char *s, ...));
175130803Smarcelvoid error_with_decl PVPROTO((tree decl, const char *s, ...));
176130803Smarcelvoid error_for_asm PVPROTO((rtx insn, const char *s, ...));
177130803Smarcelvoid notice PVPROTO((const char *s, ...));
178130803Smarcelvoid error PVPROTO((const char *s, ...));
179130803Smarcelvoid fatal PVPROTO((const char *s, ...));
180130803Smarcelvoid warning_with_file_and_line PVPROTO((const char *file,
181130803Smarcel					 int line, const char *s, ...));
182130803Smarcelvoid warning_with_decl PVPROTO((tree decl, const char *s, ...));
183130803Smarcelvoid warning PVPROTO((const char *s, ...));
184130803Smarcelvoid pedwarn PVPROTO((const char *s, ...));
185130803Smarcelvoid pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
186130803Smarcelvoid pedwarn_with_file_and_line PVPROTO((const char *file,
187130803Smarcel					 int line, const char *s, ...));
188130803Smarcelvoid sorry PVPROTO((const char *s, ...));
189130803Smarcelstatic void set_target_switch PROTO((const char *));
190130803Smarcelstatic char *decl_name PROTO((tree, int));
191130803Smarcelstatic void vmessage PROTO((const char *, const char *, va_list));
192130803Smarcelstatic void v_message_with_file_and_line PROTO((const char *, int, int,
193130803Smarcel						const char *, va_list));
194130803Smarcelstatic void v_message_with_decl PROTO((tree, int, const char *, va_list));
195130803Smarcelstatic void file_and_line_for_asm PROTO((rtx, char **, int *));
196130803Smarcelstatic void v_error_with_file_and_line PROTO((const char *, int,
197130803Smarcel					      const char *, va_list));
198130803Smarcelstatic void v_error_with_decl PROTO((tree, const char *, va_list));
19946283Sdfrstatic void v_error_for_asm PROTO((rtx, const char *, va_list));
20046283Sdfrstatic void verror PROTO((const char *, va_list));
201130803Smarcelstatic void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
202130803Smarcelstatic void v_warning_with_file_and_line PROTO ((const char *, int,
203130803Smarcel						 const char *, va_list));
20446283Sdfrstatic void v_warning_with_decl PROTO((tree, const char *, va_list));
205130803Smarcelstatic void v_warning_for_asm PROTO((rtx, const char *, va_list));
206130803Smarcelstatic void vwarning PROTO((const char *, va_list));
207130803Smarcelstatic void vpedwarn PROTO((const char *, va_list));
20846283Sdfrstatic void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
209130803Smarcelstatic void v_pedwarn_with_file_and_line PROTO((const char *, int,
210130803Smarcel						const char *, va_list));
211130803Smarcelstatic void vsorry PROTO((const char *, va_list));
21246283Sdfrstatic void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
213130803Smarcelstatic void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
214130803Smarcel#ifdef ASM_IDENTIFY_LANGUAGE
215130803Smarcel/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
216130803Smarcelstatic void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
217130803Smarcel#endif
218130803Smarcelstatic void open_dump_file PROTO((const char *, const char *));
219130803Smarcelstatic void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
220130803Smarcelstatic void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
221130803Smarcelstatic void clean_dump_file PROTO((const char *));
222130803Smarcelstatic void compile_file PROTO((char *));
223130803Smarcelstatic void display_help PROTO ((void));
224130803Smarcel
225130803Smarcelstatic void print_version PROTO((FILE *, const char *));
226130803Smarcelstatic int print_single_switch PROTO((FILE *, int, int, const char *,
22746283Sdfr				      const char *, const char *,
228130803Smarcel				      const char *, const char *));
229130803Smarcelstatic void print_switch_values PROTO((FILE *, int, int, const char *,
23046283Sdfr				       const char *, const char *));
231130803Smarcel
232130803Smarcelvoid print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
233130803Smarcelvoid clean_graph_dump_file PROTO ((const char *, const char *));
23446283Sdfrvoid finish_graph_dump_file PROTO ((const char *, const char *));
235130803Smarcel/* Length of line when printing switch values.  */
236130803Smarcel#define MAX_LINE 75
237130803Smarcel
23846283Sdfr/* Name of program invoked, sans directories.  */
239130803Smarcel
240130803Smarcelchar *progname;
24146283Sdfr
242130803Smarcel/* Copy of arguments to main.  */
243130803Smarcelint save_argc;
244130803Smarcelchar **save_argv;
245130803Smarcel
246130803Smarcel/* Name of current original source file (what was input to cpp).
247130803Smarcel   This comes from each #-command in the actual input.  */
248130803Smarcel
24946283Sdfrchar *input_filename;
250130803Smarcel
251130803Smarcel/* Name of top-level original source file (what was input to cpp).
252130803Smarcel   This comes from the #-command at the beginning of the actual input.
253130803Smarcel   If there isn't any there, then this is the cc1 input file name.  */
254130803Smarcel
25519370Spstchar *main_input_filename;
256130803Smarcel
257130803Smarcel/* Current line number in real source file.  */
258130803Smarcel
259130803Smarcelint lineno;
26019370Spst
261130803Smarcel/* Nonzero if it is unsafe to create any new pseudo registers.  */
262130803Smarcelint no_new_pseudos;
263130803Smarcel
26419370Spst/* Stack of currently pending input files.  */
265130803Smarcel
266130803Smarcelstruct file_stack *input_file_stack;
267130803Smarcel
268130803Smarcel/* Incremented on each change to input_file_stack.  */
269130803Smarcelint input_file_stack_tick;
270130803Smarcel
271130803Smarcel/* FUNCTION_DECL for function now being parsed or compiled.  */
272130803Smarcel
27346283Sdfrextern tree current_function_decl;
274130803Smarcel
275130803Smarcel/* Name to use as base of names for dump output files.  */
276130803Smarcel
277130803Smarcelconst char *dump_base_name;
27846283Sdfr
279130803Smarcel/* Bit flags that specify the machine subtype we are compiling for.
280130803Smarcel   Bits are tested using macros TARGET_... defined in the tm.h file
281130803Smarcel   and set by `-m...' switches.  Must be defined in rtlanal.c.  */
282130803Smarcel
283130803Smarcelextern int target_flags;
284130803Smarcel
285130803Smarcel/* Flags saying which kinds of debugging dump have been requested.  */
286130803Smarcel
287130803Smarcelint rtl_dump = 0;
288130803Smarcelint rtl_dump_and_exit = 0;
289130803Smarcelint jump_opt_dump = 0;
290130803Smarcelint addressof_dump = 0;
29146283Sdfrint cse_dump = 0;
292130803Smarcelint gcse_dump = 0;
293130803Smarcelint loop_dump = 0;
294130803Smarcelint cse2_dump = 0;
295130803Smarcelint branch_prob_dump = 0;
296130803Smarcelint flow_dump = 0;
297130803Smarcelint combine_dump = 0;
298130803Smarcelint regmove_dump = 0;
299130803Smarcelint sched_dump = 0;
300130803Smarcelint local_reg_dump = 0;
301130803Smarcelint global_reg_dump = 0;
302130803Smarcelint flow2_dump = 0;
303130803Smarcelint sched2_dump = 0;
30446283Sdfrint jump2_opt_dump = 0;
305130803Smarcel#ifdef DELAY_SLOTS
306130803Smarcelint dbr_sched_dump = 0;
307130803Smarcel#endif
308130803Smarcelint flag_print_asm_name = 0;
309130803Smarcel#ifdef STACK_REGS
310130803Smarcelint stack_reg_dump = 0;
31146283Sdfr#endif
312130803Smarcel#ifdef MACHINE_DEPENDENT_REORG
313130803Smarcelint mach_dep_reorg_dump = 0;
314130803Smarcel#endif
315130803Smarcelenum graph_dump_types graph_dump_format;
316130803Smarcel
317130803Smarcel/* Name for output file of assembly code, specified with -o.  */
31819370Spst
319130803Smarcelchar *asm_file_name;
320130803Smarcel
321130803Smarcel/* Value of the -G xx switch, and whether it was passed or not.  */
322130803Smarcelint g_switch_value;
323130803Smarcelint g_switch_set;
32419370Spst
325130803Smarcel/* Type(s) of debugging information we are producing (if any).
326130803Smarcel   See flags.h for the definitions of the different possible
327130803Smarcel   types of debugging information.  */
328130803Smarcelenum debug_info_type write_symbols = NO_DEBUG;
329130803Smarcel
330130803Smarcel/* Level of debugging information we are producing.  See flags.h
331130803Smarcel   for the definitions of the different possible levels.  */
332130803Smarcelenum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
333130803Smarcel
334130803Smarcel/* Nonzero means use GNU-only extensions in the generated symbolic
335130803Smarcel   debugging information.  */
336130803Smarcel/* Currently, this only has an effect when write_symbols is set to
337130803Smarcel   DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
338130803Smarcelint use_gnu_debug_info_extensions = 0;
339130803Smarcel
340130803Smarcel/* Nonzero means do optimizations.  -O.
341130803Smarcel   Particular numeric values stand for particular amounts of optimization;
342130803Smarcel   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
343130803Smarcel   ones are not controlled directly by this variable.  Instead, they are
344130803Smarcel   controlled by individual `flag_...' variables that are defaulted
345130803Smarcel   based on this variable.  */
346130803Smarcel
347130803Smarcelint optimize = 0;
348130803Smarcel
349130803Smarcel/* Nonzero means optimize for size.  -Os.
350130803Smarcel   The only valid values are zero and non-zero. When optimize_size is
351130803Smarcel   non-zero, optimize defaults to 2, but certain individual code
352130803Smarcel   bloating optimizations are disabled.  */
353130803Smarcel
354130803Smarcelint optimize_size = 0;
355130803Smarcel
356130803Smarcel/* Number of error messages and warning messages so far.  */
357242936Semaste
358130803Smarcelint errorcount = 0;
359130803Smarcelint warningcount = 0;
360130803Smarcelint sorrycount = 0;
361130803Smarcel
362130803Smarcel/* Pointer to function to compute the name to use to print a declaration.
363130803Smarcel   DECL is the declaration in question.
364130803Smarcel   VERBOSITY determines what information will be printed:
365130803Smarcel     0: DECL_NAME, demangled as necessary.
366130803Smarcel     1: and scope information.
367130803Smarcel     2: and any other information that might be interesting, such as function
368130803Smarcel        parameter types in C++.  */
369130803Smarcel
370130803Smarcelchar *(*decl_printable_name)		PROTO ((tree, int));
371130803Smarcel
372130803Smarcel/* Pointer to function to compute rtl for a language-specific tree code.  */
373130803Smarcel
374130803Smarceltypedef rtx (*lang_expand_expr_t)
375130803Smarcel  PROTO ((union tree_node *, rtx, enum machine_mode,
376130803Smarcel	  enum expand_modifier modifier));
377130803Smarcel
378130803Smarcellang_expand_expr_t lang_expand_expr = 0;
379130803Smarcel
380130803Smarceltree (*lang_expand_constant) PROTO((tree)) = 0;
381130803Smarcel
382130803Smarcel/* Pointer to function to finish handling an incomplete decl at the
383130803Smarcel   end of compilation.  */
384130803Smarcel
385130803Smarcelvoid (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
386130803Smarcel
387130803Smarcel/* Nonzero if generating code to do profiling.  */
388130803Smarcel
38919370Spstint profile_flag = 0;
39019370Spst
39119370Spst/* Nonzero if generating code to do profiling on a line-by-line basis.  */
392130803Smarcel
39319370Spstint profile_block_flag;
39419370Spst
39598944Sobrien/* Nonzero if generating code to profile program flow graph arcs.  */
39619370Spst
397130803Smarcelint profile_arc_flag = 0;
398130803Smarcel
399130803Smarcel/* Nonzero if generating info for gcov to calculate line test coverage.  */
400130803Smarcel
401130803Smarcelint flag_test_coverage = 0;
402130803Smarcel
403130803Smarcel/* Nonzero indicates that branch taken probabilities should be calculated.  */
40498944Sobrien
40519370Spstint flag_branch_probabilities = 0;
40619370Spst
40719370Spst/* Nonzero for -pedantic switch: warn about anything
40846283Sdfr   that standard spec forbids.  */
40998944Sobrien
41098944Sobrienint pedantic = 0;
41198944Sobrien
41298944Sobrien/* Temporarily suppress certain warnings.
41398944Sobrien   This is set while reading code from a system header file.  */
41498944Sobrien
41598944Sobrienint in_system_header = 0;
41698944Sobrien
41719370Spst/* Nonzero means do stupid register allocation.
418130803Smarcel   Currently, this is 1 if `optimize' is 0.  */
419130803Smarcel
42019370Spstint obey_regdecls = 0;
42119370Spst
42298944Sobrien/* Don't print functions as they are compiled and don't print
42398944Sobrien   times taken by the various passes.  -quiet.  */
42419370Spst
425130803Smarcelint quiet_flag = 0;
426130803Smarcel
427130803Smarcel/* -f flags.  */
428130803Smarcel
429130803Smarcel/* Nonzero means `char' should be signed.  */
43019370Spst
431130803Smarcelint flag_signed_char;
43219370Spst
43319370Spst/* Nonzero means give an enum type only as many bytes as it needs.  */
43498944Sobrien
43519370Spstint flag_short_enums;
436130803Smarcel
437130803Smarcel/* Nonzero for -fcaller-saves: allocate values in regs that need to
438130803Smarcel   be saved across function calls, if that produces overall better code.
439130803Smarcel   Optional now, so people can test it.  */
440130803Smarcel
441130803Smarcel#ifdef DEFAULT_CALLER_SAVES
442130803Smarcelint flag_caller_saves = 1;
443130803Smarcel#else
444130803Smarcelint flag_caller_saves = 0;
445130803Smarcel#endif
446130803Smarcel
447130803Smarcel/* Nonzero if structures and unions should be returned in memory.
448130803Smarcel
449130803Smarcel   This should only be defined if compatibility with another compiler or
450130803Smarcel   with an ABI is needed, because it results in slower code.  */
451130803Smarcel
452130803Smarcel#ifndef DEFAULT_PCC_STRUCT_RETURN
453130803Smarcel#define DEFAULT_PCC_STRUCT_RETURN 1
454130803Smarcel#endif
455130803Smarcel
456130803Smarcel/* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */
457130803Smarcel
45819370Spstint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
45919370Spst
460130803Smarcel/* Nonzero for -fforce-mem: load memory value into a register
46119370Spst   before arithmetic on it.  This makes better cse but slower compilation.  */
46219370Spst
46319370Spstint flag_force_mem = 0;
46419370Spst
465130803Smarcel/* Nonzero for -fforce-addr: load memory address into a register before
466130803Smarcel   reference to memory.  This makes better cse but slower compilation.  */
467130803Smarcel
468130803Smarcelint flag_force_addr = 0;
469130803Smarcel
470130803Smarcel/* Nonzero for -fdefer-pop: don't pop args after each function call;
47119370Spst   instead save them up to pop many calls' args with one insns.  */
47298944Sobrien
47398944Sobrienint flag_defer_pop = 0;
47498944Sobrien
47598944Sobrien/* Nonzero for -ffloat-store: don't allocate floats and doubles
47698944Sobrien   in extended-precision registers.  */
47798944Sobrien
47898944Sobrienint flag_float_store = 0;
47998944Sobrien
48098944Sobrien/* Nonzero for -fcse-follow-jumps:
481130803Smarcel   have cse follow jumps to do a more extensive job.  */
482130803Smarcel
483130803Smarcelint flag_cse_follow_jumps;
48498944Sobrien
48598944Sobrien/* Nonzero for -fcse-skip-blocks:
486130803Smarcel   have cse follow a branch around a block.  */
48798944Sobrienint flag_cse_skip_blocks;
488130803Smarcel
48998944Sobrien/* Nonzero for -fexpensive-optimizations:
49098944Sobrien   perform miscellaneous relatively-expensive optimizations.  */
49198944Sobrienint flag_expensive_optimizations;
492130803Smarcel
49398944Sobrien/* Nonzero for -fthread-jumps:
49498944Sobrien   have jump optimize output of loop.  */
49598944Sobrien
496130803Smarcelint flag_thread_jumps;
49798944Sobrien
49898944Sobrien/* Nonzero enables strength-reduction in loop.c.  */
49998944Sobrien
50098944Sobrienint flag_strength_reduce = 0;
50198944Sobrien
50298944Sobrien/* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
50398944Sobrien   number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
50498944Sobrien   UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
50598944Sobrien   unrolled.  */
50698944Sobrien
50798944Sobrienint flag_unroll_loops;
50898944Sobrien
509130803Smarcel/* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
51098944Sobrien   This is generally not a win.  */
51198944Sobrien
51298944Sobrienint flag_unroll_all_loops;
51398944Sobrien
51498944Sobrien/* Nonzero forces all invariant computations in loops to be moved
51598944Sobrien   outside the loop. */
516130803Smarcel
517130803Smarcelint flag_move_all_movables = 0;
518130803Smarcel
519130803Smarcel/* Nonzero forces all general induction variables in loops to be
520130803Smarcel   strength reduced. */
52198944Sobrien
52298944Sobrienint flag_reduce_all_givs = 0;
52398944Sobrien
524130803Smarcel/* Nonzero to perform full register move optimization passes.  This is the
52598944Sobrien   default for -O2.  */
52698944Sobrien
52798944Sobrienint flag_regmove = 0;
52898944Sobrien
52998944Sobrien/* Nonzero for -fwritable-strings:
53098944Sobrien   store string constants in data segment and don't uniquize them.  */
53198944Sobrien
53298944Sobrienint flag_writable_strings = 0;
53398944Sobrien
53498944Sobrien/* Nonzero means don't put addresses of constant functions in registers.
53598944Sobrien   Used for compiling the Unix kernel, where strange substitutions are
53698944Sobrien   done on the assembly output.  */
53798944Sobrien
53898944Sobrienint flag_no_function_cse = 0;
539130803Smarcel
54098944Sobrien/* Nonzero for -fomit-frame-pointer:
54198944Sobrien   don't make a frame pointer in simple functions that don't require one.  */
54298944Sobrien
54398944Sobrienint flag_omit_frame_pointer = 0;
54498944Sobrien
54598944Sobrien/* Nonzero means place each function into its own section on those platforms
54698944Sobrien   which support arbitrary section names and unlimited numbers of sections.  */
54798944Sobrien
548130803Smarcelint flag_function_sections = 0;
54919370Spst
55019370Spst/* ... and similar for data.  */
55119370Spst
55298944Sobrienint flag_data_sections = 0;
55398944Sobrien
55498944Sobrien/* Nonzero to inhibit use of define_optimization peephole opts.  */
55598944Sobrien
55698944Sobrienint flag_no_peephole = 0;
55798944Sobrien
55898944Sobrien/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
55919370Spst   operations in the interest of optimization.  For example it allows
56098944Sobrien   GCC to assume arguments to sqrt are nonnegative numbers, allowing
56198944Sobrien   faster code for sqrt to be generated.  */
56298944Sobrien
56398944Sobrienint flag_fast_math = 0;
56498944Sobrien
56598944Sobrien/* Nonzero means the front end generally wants `errno' maintained by math
56619370Spst   operations, like built-in SQRT, unless overridden by flag_fast_math.  */
567130803Smarcel
56819370Spstint flag_errno_math = 1;
56998944Sobrien
57019370Spst/* 0 means straightforward implementation of complex divide acceptable.
57119370Spst   1 means wide ranges of inputs must work for complex divide.
57219370Spst   2 means C9X-like requirements for complex divide (not yet implemented).  */
57319370Spst
57419370Spstint flag_complex_divide_method = 0;
57519370Spst
57619370Spst/* Nonzero means all references through pointers are volatile.  */
57719370Spst
57819370Spstint flag_volatile;
57919370Spst
58019370Spst/* Nonzero means treat all global and extern variables as volatile.  */
58119370Spst
58219370Spstint flag_volatile_global;
583130803Smarcel
58419370Spst/* Nonzero means treat all static variables as volatile.  */
58519370Spst
58619370Spstint flag_volatile_static;
58719370Spst
588130803Smarcel/* Nonzero means just do syntax checking; don't output anything.  */
58998944Sobrien
59098944Sobrienint flag_syntax_only = 0;
59198944Sobrien
59298944Sobrien/* Nonzero means perform global cse.  */
59398944Sobrien
59498944Sobrienstatic int flag_gcse;
59598944Sobrien
59698944Sobrien/* Nonzero means to rerun cse after loop optimization.  This increases
59798944Sobrien   compilation time about 20% and picks up a few more common expressions.  */
59898944Sobrien
59998944Sobrienstatic int flag_rerun_cse_after_loop;
600130803Smarcel
60119370Spst/* Nonzero means to run loop optimizations twice.  */
60298944Sobrien
60398944Sobrienint flag_rerun_loop_opt;
60498944Sobrien
60598944Sobrien/* Nonzero for -finline-functions: ok to inline functions that look like
60698944Sobrien   good inline candidates.  */
60798944Sobrien
60898944Sobrienint flag_inline_functions;
609130803Smarcel
61098944Sobrien/* Nonzero for -fkeep-inline-functions: even if we make a function
61119370Spst   go inline everywhere, keep its definition around for debugging
61219370Spst   purposes.  */
61319370Spst
61419370Spstint flag_keep_inline_functions;
615130803Smarcel
61646283Sdfr/* Nonzero means that functions will not be inlined.  */
61719370Spst
618130803Smarcelint flag_no_inline;
61946283Sdfr
62019370Spst/* Nonzero means that we should emit static const variables
62119370Spst   regardless of whether or not optimization is turned on.  */
62219370Spst
623130803Smarcelint flag_keep_static_consts = 1;
62419370Spst
62598944Sobrien/* Nonzero means we should be saving declaration info into a .X file.  */
62619370Spst
62798944Sobrienint flag_gen_aux_info = 0;
62898944Sobrien
62998944Sobrien/* Specified name of aux-info file.  */
630130803Smarcel
63119370Spststatic char *aux_info_file_name;
63298944Sobrien
633130803Smarcel/* Nonzero means make the text shared if supported.  */
634130803Smarcel
635130803Smarcelint flag_shared_data;
63698944Sobrien
63798944Sobrien/* Nonzero means schedule into delayed branch slots if supported.  */
638130803Smarcel
63998944Sobrienint flag_delayed_branch;
64098944Sobrien
64198944Sobrien/* Nonzero if we are compiling pure (sharable) code.
64298944Sobrien   Value is 1 if we are doing reasonable (i.e. simple
64398944Sobrien   offset into offset table) pic.  Value is 2 if we can
64498944Sobrien   only perform register offsets.  */
64598944Sobrien
64698944Sobrienint flag_pic;
64798944Sobrien
64898944Sobrien/* Nonzero means generate extra code for exception handling and enable
64998944Sobrien   exception handling.  */
65098944Sobrien
65198944Sobrienint flag_exceptions;
65298944Sobrien
65398944Sobrien/* Nonzero means use the new model for exception handling. Replaces
65498944Sobrien   -DNEW_EH_MODEL as a compile option. */
65598944Sobrien
65698944Sobrienint flag_new_exceptions = 0;
65798944Sobrien
65898944Sobrien/* Nonzero means don't place uninitialized global data in common storage
65998944Sobrien   by default.  */
66098944Sobrien
66198944Sobrienint flag_no_common;
66298944Sobrien
66398944Sobrien/* Nonzero means pretend it is OK to examine bits of target floats,
66498944Sobrien   even if that isn't true.  The resulting code will have incorrect constants,
66598944Sobrien   but the same series of instructions that the native compiler would make.  */
66698944Sobrien
66798944Sobrienint flag_pretend_float;
66898944Sobrien
66998944Sobrien/* Nonzero means change certain warnings into errors.
67098944Sobrien   Usually these are warnings about failure to conform to some standard.  */
67198944Sobrien
67298944Sobrienint flag_pedantic_errors = 0;
67398944Sobrien
67498944Sobrien/* flag_schedule_insns means schedule insns within basic blocks (before
67598944Sobrien   local_alloc).
67698944Sobrien   flag_schedule_insns_after_reload means schedule insns after
67798944Sobrien   global_alloc.  */
67898944Sobrien
67919370Spstint flag_schedule_insns = 0;
68098944Sobrienint flag_schedule_insns_after_reload = 0;
68198944Sobrien
68219370Spst#ifdef HAIFA
683130803Smarcel/* The following flags have effect only for scheduling before register
68498944Sobrien   allocation:
68519370Spst
68698944Sobrien   flag_schedule_interblock means schedule insns accross basic blocks.
68798944Sobrien   flag_schedule_speculative means allow speculative motion of non-load insns.
68898944Sobrien   flag_schedule_speculative_load means allow speculative motion of some
68998944Sobrien   load insns.
69019370Spst   flag_schedule_speculative_load_dangerous allows speculative motion of more
69119370Spst   load insns.  */
69298944Sobrien
69319370Spstint flag_schedule_interblock = 1;
69498944Sobrienint flag_schedule_speculative = 1;
69598944Sobrienint flag_schedule_speculative_load = 0;
69698944Sobrienint flag_schedule_speculative_load_dangerous = 0;
69798944Sobrien#endif  /* HAIFA */
69819370Spst
69946283Sdfr/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
70046283Sdfr   by a cheaper branch, on a count register. */
70146283Sdfrint flag_branch_on_count_reg;
70246283Sdfr
70398944Sobrien/* -finhibit-size-directive inhibits output of .size for ELF.
70446283Sdfr   This is used only for compiling crtstuff.c,
70546283Sdfr   and it may be extended to other effects
70698944Sobrien   needed for crtstuff.c on other systems.  */
70746283Sdfrint flag_inhibit_size_directive = 0;
70819370Spst
70919370Spst/* -fverbose-asm causes extra commentary information to be produced in
71019370Spst   the generated assembly code (to make it more readable).  This option
71119370Spst   is generally only of use to those who actually need to read the
71246283Sdfr   generated assembly code (perhaps while debugging the compiler itself).
71398944Sobrien   -fno-verbose-asm, the default, causes the extra information
71419370Spst   to be omitted and is useful when comparing two assembler files.  */
71519370Spst
71619370Spstint flag_verbose_asm = 0;
71719370Spst
71898944Sobrien/* -dA causes debug commentary information to be produced in
71998944Sobrien   the generated assembly code (to make it more readable).  This option
72019370Spst   is generally only of use to those who actually need to read the
72119370Spst   generated assembly code (perhaps while debugging the compiler itself).
72219370Spst   Currently, this switch is only used by dwarfout.c; however, it is intended
72319370Spst   to be a catchall for printing debug information in the assembler file.  */
72419370Spst
72598944Sobrienint flag_debug_asm = 0;
72698944Sobrien
72719370Spst/* -fgnu-linker specifies use of the GNU linker for initializations.
72819370Spst   (Or, more generally, a linker that handles initializations.)
72919370Spst   -fno-gnu-linker says that collect2 will be used.  */
73019370Spst#ifdef USE_COLLECT2
73119370Spstint flag_gnu_linker = 0;
73219370Spst#else
73398944Sobrienint flag_gnu_linker = 1;
73419370Spst#endif
73598944Sobrien
73619370Spst/* Tag all structures with __attribute__(packed) */
73719370Spstint flag_pack_struct = 0;
73898944Sobrien
73998944Sobrien/* Nonzero means that -Wformat accepts certain system-dependent formats.  */
74098944Sobrienint flag_format_extensions = 0;
74198944Sobrien
74298944Sobrien/* Emit code to check for stack overflow; also may cause large objects
74398944Sobrien   to be allocated dynamically.  */
74498944Sobrienint flag_stack_check;
74598944Sobrien
74698944Sobrien/* -fcheck-memory-usage causes extra code to be generated in order to check
74798944Sobrien   memory accesses.  This is used by a detector of bad memory accesses such
74898944Sobrien   as Checker.  */
74998944Sobrienint flag_check_memory_usage = 0;
75098944Sobrien
75198944Sobrien/* -fprefix-function-name causes function name to be prefixed.  This
75219370Spst   can be used with -fcheck-memory-usage to isolate code compiled with
75319370Spst   -fcheck-memory-usage.  */
75419370Spstint flag_prefix_function_name = 0;
75519370Spst
75698944Sobrien/* 0 if pointer arguments may alias each other.  True in C.
75798944Sobrien   1 if pointer arguments may not alias each other but may alias
75819370Spst   global variables.
75919370Spst   2 if pointer arguments may not alias each other and may not
76019370Spst   alias global variables.  True in Fortran.
76119370Spst   This defaults to 0 for C.  */
76219370Spstint flag_argument_noalias = 0;
76319370Spst
76419370Spst/* Nonzero if we should do (language-dependent) alias analysis.
765130803Smarcel   Typically, this analysis will assume that expressions of certain
76619370Spst   types do not alias expressions of certain other types.  Only used
767130803Smarcel   if alias analysis (in general) is enabled.  */
76819370Spstint flag_strict_aliasing = 0;
76919370Spst
77019370Spst/* Instrument functions with calls at entry and exit, for profiling.  */
77119370Spstint flag_instrument_function_entry_exit = 0;
77298944Sobrien
77319370Spst/* Nonzero means ignore `#ident' directives.  0 means handle them.
77419370Spst   On SVR4 targets, it also controls whether or not to emit a
77519370Spst   string identifying the compiler.  */
77619370Spst
77719370Spstint flag_no_ident = 0;
77819370Spst
77919370Spst/* Table of supported debugging formats.  */
78019370Spststatic struct
78119370Spst{
78219370Spst  const char * arg;
78319370Spst  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
78419370Spst     constant expression, we use NO_DEBUG in its place.  */
78519370Spst  enum debug_info_type debug_type;
78619370Spst  int use_extensions_p;
78719370Spst  const char * description;
78819370Spst} *da,
78919370Spstdebug_args[] =
79019370Spst{
79119370Spst  { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
792130803Smarcel    "Generate default debug format output" },
79319370Spst  { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
79419370Spst#ifdef DBX_DEBUGGING_INFO
79519370Spst  { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
79619370Spst  { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
79719370Spst#endif
79819370Spst#ifdef DWARF_DEBUGGING_INFO
799130803Smarcel  { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
80019370Spst  { "gdwarf+", DWARF_DEBUG, 1,
80119370Spst    "Generated extended DWARF-1 format debug output" },
80219370Spst#endif
80319370Spst#ifdef DWARF2_DEBUGGING_INFO
80419370Spst  { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
805130803Smarcel#endif
80619370Spst#ifdef XCOFF_DEBUGGING_INFO
80798944Sobrien  { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
80819370Spst  { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
80919370Spst#endif
81019370Spst#ifdef SDB_DEBUGGING_INFO
81119370Spst  { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
81298944Sobrien#endif
81319370Spst  { 0, 0, 0, 0 }
81419370Spst};
81519370Spst
81619370Spsttypedef struct
81798944Sobrien{
81819370Spst  const char * string;
81919370Spst  int *  variable;
82019370Spst  int    on_value;
82119370Spst  const char * description;
82219370Spst}
82319370Spstlang_independent_options;
82419370Spst
82519370Spst/* Add or remove a leading underscore from user symbols.  */
82619370Spstint flag_leading_underscore = -1;
82719370Spst
82819370Spst/* The user symbol prefix after having resolved same.  */
82919370Spstconst char *user_label_prefix;
83019370Spst
83198944Sobrien/* A default for same.  */
83219370Spst#ifndef USER_LABEL_PREFIX
83319370Spst#define USER_LABEL_PREFIX ""
83419370Spst#endif
83519370Spst
83619370Spst/* Table of language-independent -f options.
83719370Spst   STRING is the option name.  VARIABLE is the address of the variable.
83819370Spst   ON_VALUE is the value to store in VARIABLE
83919370Spst    if `-fSTRING' is seen as an option.
84019370Spst   (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
841130803Smarcel
84219370Spstlang_independent_options f_options[] =
84319370Spst{
84419370Spst  {"float-store", &flag_float_store, 1,
84519370Spst   "Do not store floats in registers" },
846130803Smarcel  {"volatile", &flag_volatile, 1,
847130803Smarcel   "Consider all mem refs through pointers as volatile"},
848130803Smarcel  {"volatile-global", &flag_volatile_global, 1,
849130803Smarcel   "Consider all mem refs to global data to be volatile" },
850130803Smarcel  {"volatile-static", &flag_volatile_static, 1,
851130803Smarcel   "Consider all mem refs to static data to be volatile" },
852130803Smarcel  {"defer-pop", &flag_defer_pop, 1,
853130803Smarcel   "Defer popping functions args from stack until later" },
854130803Smarcel  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
855130803Smarcel   "When possible do not generate stack frames"},
856130803Smarcel  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
857130803Smarcel   "When running CSE, follow jumps to their targets" },
858130803Smarcel  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
859130803Smarcel   "When running CSE, follow conditional jumps" },
86019370Spst  {"expensive-optimizations", &flag_expensive_optimizations, 1,
86119370Spst   "Perform a number of minor, expensive optimisations" },
86219370Spst  {"thread-jumps", &flag_thread_jumps, 1,
86319370Spst   "Perform jump threading optimisations"},
864130803Smarcel  {"strength-reduce", &flag_strength_reduce, 1,
86519370Spst   "Perform strength reduction optimisations" },
866130803Smarcel  {"unroll-loops", &flag_unroll_loops, 1,
867130803Smarcel   "Perform loop unrolling when iteration count is known" },
868130803Smarcel  {"unroll-all-loops", &flag_unroll_all_loops, 1,
86919370Spst   "Perform loop unrolling for all loops" },
87019370Spst  {"move-all-movables", &flag_move_all_movables, 1,
871130803Smarcel   "Force all loop invariant computations out of loops" },
87246283Sdfr  {"reduce-all-givs", &flag_reduce_all_givs, 1,
87346283Sdfr   "Strength reduce all loop general induction variables" },
87446283Sdfr  {"writable-strings", &flag_writable_strings, 1,
87546283Sdfr   "Store strings in writable data section" },
87646283Sdfr  {"peephole", &flag_no_peephole, 0,
87746283Sdfr   "Enable machine specific peephole optimisations" },
87846283Sdfr  {"force-mem", &flag_force_mem, 1,
87946283Sdfr   "Copy memory operands into registers before using" },
88046283Sdfr  {"force-addr", &flag_force_addr, 1,
88146283Sdfr   "Copy memory address constants into regs before using" },
88246283Sdfr  {"function-cse", &flag_no_function_cse, 0,
88346283Sdfr   "Allow function addresses to be held in registers" },
88498944Sobrien  {"inline-functions", &flag_inline_functions, 1,
885130803Smarcel   "Integrate simple functions into their callers" },
88698944Sobrien  {"keep-inline-functions", &flag_keep_inline_functions, 1,
88798944Sobrien   "Generate code for funcs even if they are fully inlined" },
88898944Sobrien  {"inline", &flag_no_inline, 0,
88998944Sobrien   "Pay attention to the 'inline' keyword"},
89098944Sobrien  {"keep-static-consts", &flag_keep_static_consts, 1,
89198944Sobrien   "Emit static const variables even if they are not used" },
89298944Sobrien  {"syntax-only", &flag_syntax_only, 1,
89398944Sobrien   "Check for syntax errors, then stop" },
89498944Sobrien  {"shared-data", &flag_shared_data, 1,
895130803Smarcel   "Mark data as shared rather than private" },
89698944Sobrien  {"caller-saves", &flag_caller_saves, 1,
89719370Spst   "Enable saving registers around function calls" },
89819370Spst  {"pcc-struct-return", &flag_pcc_struct_return, 1,
89919370Spst   "Return 'short' aggregates in memory, not registers" },
900130803Smarcel  {"reg-struct-return", &flag_pcc_struct_return, 0,
90119370Spst   "Return 'short' aggregates in registers" },
90219370Spst  {"delayed-branch", &flag_delayed_branch, 1,
903130803Smarcel   "Attempt to fill delay slots of branch instructions" },
90419370Spst  {"gcse", &flag_gcse, 1,
90519370Spst   "Perform the global common subexpression elimination" },
90619370Spst  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
90719370Spst   "Run CSE pass after loop optimisations"},
90819370Spst  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
909130803Smarcel   "Run the loop optimiser twice"},
91019370Spst  {"pretend-float", &flag_pretend_float, 1,
911130803Smarcel   "Pretend that host and target use the same FP format"},
912130803Smarcel  {"schedule-insns", &flag_schedule_insns, 1,
913130803Smarcel   "Reschedule instructions to avoid pipeline stalls"},
91419370Spst  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
91519370Spst  "Run two passes of the instruction scheduler"},
91619370Spst#ifdef HAIFA
91719370Spst  {"sched-interblock",&flag_schedule_interblock, 1,
91819370Spst   "Enable scheduling across basic blocks" },
919130803Smarcel  {"sched-spec",&flag_schedule_speculative, 1,
92019370Spst   "Allow speculative motion of non-loads" },
92119370Spst  {"sched-spec-load",&flag_schedule_speculative_load, 1,
922130803Smarcel   "Allow speculative motion of some loads" },
923130803Smarcel  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
92419370Spst   "Allow speculative motion of more loads" },
92519370Spst#endif  /* HAIFA */
92619370Spst  {"branch-count-reg",&flag_branch_on_count_reg, 1,
92719370Spst   "Replace add,compare,branch with branch on count reg"},
92819370Spst  {"pic", &flag_pic, 1,
92919370Spst   "Generate position independent code, if possible"},
93019370Spst  {"PIC", &flag_pic, 2, ""},
93119370Spst  {"exceptions", &flag_exceptions, 1,
93219370Spst   "Enable exception handling" },
93319370Spst  {"new-exceptions", &flag_new_exceptions, 1,
93419370Spst   "Use the new model for exception handling" },
93519370Spst  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
93619370Spst   "Use setjmp/longjmp to handle exceptions" },
937130803Smarcel  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
938130803Smarcel   "Support asynchronous exceptions" },
93919370Spst  {"profile-arcs", &profile_arc_flag, 1,
94019370Spst   "Insert arc based program profiling code" },
94119370Spst  {"test-coverage", &flag_test_coverage, 1,
94298944Sobrien   "Create data files needed by gcov" },
943130803Smarcel  {"branch-probabilities", &flag_branch_probabilities, 1,
944130803Smarcel   "Use profiling information for branch probabilities" },
94519370Spst  {"fast-math", &flag_fast_math, 1,
94619370Spst   "Improve FP speed by violating ANSI & IEEE rules" },
94719370Spst  {"common", &flag_no_common, 0,
94819370Spst   "Do not put unitialised globals in the common section" },
94919370Spst  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
95019370Spst   "Do not generate .size directives" },
95119370Spst  {"function-sections", &flag_function_sections, 1,
952130803Smarcel   "place each function into its own section" },
953130803Smarcel  {"data-sections", &flag_data_sections, 1,
95419370Spst   "place data items into their own section" },
955130803Smarcel  {"verbose-asm", &flag_verbose_asm, 1,
95619370Spst   "Add extra commentry to assembler output"},
95719370Spst  {"gnu-linker", &flag_gnu_linker, 1,
958130803Smarcel   "Output GNU ld formatted global initialisers"},
95919370Spst  {"regmove", &flag_regmove, 1,
96019370Spst   "Enables a register move optimisation"},
961130803Smarcel  {"optimize-register-move", &flag_regmove, 1,
962130803Smarcel   "Do the full regmove optimization pass"},
96319370Spst  {"pack-struct", &flag_pack_struct, 1,
964130803Smarcel   "Pack structure members together without holes" },
96519370Spst  {"format-extensions", &flag_format_extensions, 1,
96619370Spst   "-Wformat accepts certain FreeBSD system-dependent formats" },
967130803Smarcel  {"stack-check", &flag_stack_check, 1,
968130803Smarcel   "Insert stack checking code into the program" },
96919370Spst  {"argument-alias", &flag_argument_noalias, 0,
97019370Spst   "Specify that arguments may alias each other & globals"},
97119370Spst  {"argument-noalias", &flag_argument_noalias, 1,
972130803Smarcel   "Assume arguments may alias globals but not each other"},
97319370Spst  {"argument-noalias-global", &flag_argument_noalias, 2,
97419370Spst   "Assume arguments do not alias each other or globals" },
97519370Spst  {"strict-aliasing", &flag_strict_aliasing, 1,
97619370Spst   "Assume strict aliasing rules apply" },
97719370Spst  {"check-memory-usage", &flag_check_memory_usage, 1,
97819370Spst   "Generate code to check every memory access" },
97919370Spst  {"prefix-function-name", &flag_prefix_function_name, 1,
98019370Spst   "Add a prefix to all function names" },
98119370Spst  {"dump-unnumbered", &flag_dump_unnumbered, 1,
98219370Spst   "Suppress output of instruction numbers and line number notes in debugging dumps"},
98319370Spst  {"instrument-functions", &flag_instrument_function_entry_exit, 1,
984130803Smarcel   "Instrument function entry/exit with profiling calls"},
985130803Smarcel  {"leading-underscore", &flag_leading_underscore, 1,
986130803Smarcel   "External symbols have a leading underscore" },
987130803Smarcel  {"ident", &flag_no_ident, 0,
988130803Smarcel   "Process #ident directives"}
98919370Spst};
990130803Smarcel
991130803Smarcel#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
992130803Smarcel
993130803Smarcel/* Table of language-specific options.  */
994130803Smarcel
995130803Smarcelstatic struct lang_opt
996130803Smarcel{
997130803Smarcel  const char * option;
998130803Smarcel  const char * description;
999130803Smarcel}
100019370Spstdocumented_lang_options[] =
100119370Spst{
100219370Spst  /* In order not to overload the --help output, the convention
100319370Spst     used here is to only describe those options which are not
100419370Spst     enabled by default.  */
100519370Spst
1006130803Smarcel  { "-ansi", "Compile just for ANSI C" },
100719370Spst  { "-fallow-single-precision",
100819370Spst    "Do not promote floats to double if using -traditional" },
100919370Spst  { "-std= ", "Determine language standard"},
101019370Spst
101119370Spst  { "-fsigned-bitfields", "" },
101219370Spst  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
101319370Spst  { "-fno-signed-bitfields", "" },
101419370Spst  { "-fno-unsigned-bitfields","" },
101519370Spst  { "-fsigned-char", "Make 'char' be signed by default"},
101619370Spst  { "-funsigned-char", "Make 'char' be unsigned by default"},
101719370Spst  { "-fno-signed-char", "" },
1018130803Smarcel  { "-fno-unsigned-char", "" },
1019130803Smarcel
1020130803Smarcel  { "-ftraditional", "" },
1021130803Smarcel  { "-traditional", "Attempt to support traditional K&R style C"},
1022130803Smarcel  { "-fnotraditional", "" },
1023130803Smarcel  { "-fno-traditional", "" },
1024130803Smarcel
1025130803Smarcel  { "-fasm", "" },
1026130803Smarcel  { "-fno-asm", "Do not recognise the 'asm' keyword" },
1027130803Smarcel  { "-fbuiltin", "" },
1028130803Smarcel  { "-fno-builtin", "Do not recognise any built in functions" },
1029130803Smarcel  { "-fhosted", "Assume normal C execution environment" },
1030130803Smarcel  { "-fno-hosted", "" },
1031130803Smarcel  { "-ffreestanding",
1032130803Smarcel    "Assume that standard libraries & main might not exist" },
1033130803Smarcel  { "-fno-freestanding", "" },
1034130803Smarcel  { "-fcond-mismatch", "Allow different types as args of ? operator"},
1035130803Smarcel  { "-fno-cond-mismatch", "" },
1036130803Smarcel  { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
1037130803Smarcel  { "-fno-dollars-in-identifiers", "" },
1038130803Smarcel  { "-fshort-double", "Use the same size for double as for float" },
1039130803Smarcel  { "-fno-short-double", "" },
1040130803Smarcel  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
1041130803Smarcel  { "-fno-short-enums", "" },
1042130803Smarcel
1043130803Smarcel  { "-Wall", "Enable most warning messages" },
104446283Sdfr  { "-Wbad-function-cast",
1045130803Smarcel    "Warn about casting functions to incompatible types" },
1046130803Smarcel  { "-Wno-bad-function-cast", "" },
1047130803Smarcel  { "-Wmissing-noreturn",
1048130803Smarcel    "Warn about functions which might be candidates for attribute noreturn" },
1049130803Smarcel  { "-Wno-missing-noreturn", "" },
1050130803Smarcel  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
1051130803Smarcel  { "-Wno-cast-qual", "" },
1052130803Smarcel  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
1053130803Smarcel  { "-Wno-char-subscripts", "" },
1054130803Smarcel  { "-Wcomment", "Warn if nested comments are detected" },
1055130803Smarcel  { "-Wno-comment", "" },
1056130803Smarcel  { "-Wcomments", "Warn if nested comments are detected" },
105746283Sdfr  { "-Wno-comments", "" },
1058130803Smarcel  { "-Wconversion", "Warn about possibly confusing type conversions" },
1059130803Smarcel  { "-Wno-conversion", "" },
1060130803Smarcel  { "-Wformat", "Warn about printf format anomalies" },
1061130803Smarcel  { "-Wno-format", "" },
1062130803Smarcel  { "-Wimplicit-function-declaration",
1063130803Smarcel    "Warn about implicit function declarations" },
1064130803Smarcel  { "-Wno-implicit-function-declaration", "" },
1065130803Smarcel  { "-Werror-implicit-function-declaration", "" },
1066130803Smarcel  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
1067130803Smarcel  { "-Wno-implicit-int", "" },
1068130803Smarcel  { "-Wimplicit", "" },
1069130803Smarcel  { "-Wno-implicit", "" },
1070130803Smarcel  { "-Wimport", "Warn about the use of the #import directive" },
1071130803Smarcel  { "-Wno-import", "" },
1072130803Smarcel  { "-Wlong-long","" },
1073130803Smarcel  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
1074130803Smarcel  { "-Wmain", "Warn about suspicious declarations of main" },
1075130803Smarcel  { "-Wno-main", "" },
1076130803Smarcel  { "-Wmissing-braces",
1077130803Smarcel    "Warn about possibly missing braces around initialisers" },
1078130803Smarcel  { "-Wno-missing-braces", "" },
1079130803Smarcel  { "-Wmissing-declarations",
1080130803Smarcel    "Warn about global funcs without previous declarations"},
1081130803Smarcel  { "-Wno-missing-declarations", "" },
1082130803Smarcel  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
1083130803Smarcel  { "-Wno-missing-prototypes", "" },
1084130803Smarcel  { "-Wmultichar", "Warn about use of multicharacter literals"},
1085130803Smarcel  { "-Wno-multichar", "" },
1086130803Smarcel  { "-Wnested-externs", "Warn about externs not at file scope level" },
1087130803Smarcel  { "-Wno-nested-externs", "" },
1088130803Smarcel  { "-Wparentheses", "Warn about possible missing parentheses" },
1089130803Smarcel  { "-Wno-parentheses", "" },
1090130803Smarcel  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
1091130803Smarcel  { "-Wno-pointer-arith", "" },
1092130803Smarcel  { "-Wredundant-decls",
1093130803Smarcel    "Warn about multiple declarations of the same object" },
1094130803Smarcel  { "-Wno-redundant-decls", "" },
1095130803Smarcel  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
1096130803Smarcel  { "-Wno-sign-compare", "" },
1097130803Smarcel  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
1098130803Smarcel  { "-Wno-unknown-pragmas", "" },
109946283Sdfr  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
1100130803Smarcel  { "-Wno-strict-prototypes", "" },
110119370Spst  { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
110219370Spst  { "-Wno-traditional", "" },
110319370Spst  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
110419370Spst  { "-Wno-trigraphs", "" },
110519370Spst  { "-Wundef", "" },
110619370Spst  { "-Wno-undef", "" },
110719370Spst  { "-Wwrite-strings", "Mark strings as 'const char *'"},
110819370Spst  { "-Wno-write-strings", "" },
110919370Spst
111098944Sobrien  /* These are for languages with USE_CPPLIB.  */
111119370Spst  /* These options are already documented in cpplib.c */
111298944Sobrien  { "--help", "" },
111319370Spst  { "-A", "" },
111419370Spst  { "-D", "" },
111519370Spst  { "-I", "" },
111619370Spst#if USE_CPPLIB
111719370Spst  { "-MD", "Print dependencies to FILE.d" },
111819370Spst  { "-MMD", "Print dependencies to FILE.d" },
111919370Spst  { "-M", "Print dependencies to stdout" },
112019370Spst  { "-MM", "Print dependencies to stdout" },
112198944Sobrien#endif /* USE_CPPLIB */
112219370Spst  { "-U", "" },
112319370Spst  { "-H", "" },
112419370Spst  { "-idirafter", "" },
112519370Spst  { "-imacros", "" },
112619370Spst  { "-include", "" },
112719370Spst  { "-iprefix", "" },
112819370Spst  { "-isystem", "" },
112919370Spst  { "-iwithprefix", "" },
113019370Spst  { "-iwithprefixbefore", "" },
113119370Spst  { "-lang-c", "" },
113298944Sobrien  { "-lang-c89", "" },
113398944Sobrien  { "-lang-c++", "" },
113419370Spst  { "-remap", "" },
113598944Sobrien  { "-nostdinc", "" },
113619370Spst  { "-nostdinc++", "" },
113719370Spst  { "-trigraphs", "" },
1138130803Smarcel  { "-undef", "" },
1139130803Smarcel
1140130803Smarcel#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
1141130803Smarcel
114219370Spst  /* These are for obj c.  */
114319370Spst  DEFINE_LANG_NAME ("Objective C")
114419370Spst
114519370Spst  { "-lang-objc", "" },
114619370Spst  { "-gen-decls", "Dump decls to a .decl file" },
114719370Spst  { "-fgnu-runtime", "Generate code for GNU runtime environment" },
114819370Spst  { "-fno-gnu-runtime", "" },
114919370Spst  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
115019370Spst  { "-fno-next-runtime", "" },
115198944Sobrien  { "-Wselector", "Warn if a selector has multiple methods" },
115298944Sobrien  { "-Wno-selector", "" },
115398944Sobrien  { "-Wprotocol", "" },
115498944Sobrien  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
115598944Sobrien  { "-print-objc-runtime-info",
115698944Sobrien    "Generate C header of platform specific features" },
115719370Spst
115819370Spst#include "options.h"
115919370Spst
116098944Sobrien};
116119370Spst
116219370Spst/* Here is a table, controlled by the tm.h file, listing each -m switch
116319370Spst   and which bits in `target_switches' it should set or clear.
116419370Spst   If VALUE is positive, it is bits to set.
116519370Spst   If VALUE is negative, -VALUE is bits to clear.
116619370Spst   (The sign bit is not used so there is no confusion.)  */
116719370Spst
116819370Spststruct
116919370Spst{
117019370Spst  const char * name;
117119370Spst  int    value;
117219370Spst  const char * description;
117398944Sobrien}
117419370Spsttarget_switches [] = TARGET_SWITCHES;
117519370Spst
117619370Spst/* This table is similar, but allows the switch to have a value.  */
117719370Spst
117819370Spst#ifdef TARGET_OPTIONS
117919370Spststruct
118019370Spst{
118119370Spst  const char *  prefix;
118219370Spst  const char ** variable;
118398944Sobrien  const char *  description;
118419370Spst}
118519370Spsttarget_options [] = TARGET_OPTIONS;
118619370Spst#endif
118719370Spst
118819370Spst/* Options controlling warnings */
118919370Spst
119019370Spst/* Don't print warning messages.  -w.  */
119119370Spst
119219370Spstint inhibit_warnings = 0;
119398944Sobrien
119419370Spst/* Print various extra warnings.  -W.  */
119598944Sobrien
119698944Sobrienint extra_warnings = 0;
119798944Sobrien
119898944Sobrien/* Treat warnings as errors.  -Werror.  */
119919370Spst
120019370Spstint warnings_are_errors = 0;
120119370Spst
120219370Spst/* Nonzero to warn about unused local variables.  */
120319370Spst
120419370Spstint warn_unused;
1205130803Smarcel
120619370Spst/* Nonzero to warn about variables used before they are initialized.  */
120719370Spst
120819370Spstint warn_uninitialized;
120919370Spst
121019370Spst/* Nonzero means warn about all declarations which shadow others.   */
121119370Spst
121219370Spstint warn_shadow;
121319370Spst
121419370Spst/* Warn if a switch on an enum fails to have a case for every enum value.  */
121519370Spst
121619370Spstint warn_switch;
121719370Spst
121898944Sobrien/* Nonzero means warn about function definitions that default the return type
121998944Sobrien   or that use a null return and have a return-type other than void.  */
122098944Sobrien
1221130803Smarcelint warn_return_type;
122246283Sdfr
122398944Sobrien/* Nonzero means warn about pointer casts that increase the required
122419370Spst   alignment of the target type (and might therefore lead to a crash
122519370Spst   due to a misaligned access).  */
122619370Spst
122719370Spstint warn_cast_align;
122819370Spst
122919370Spst/* Nonzero means warn about any identifiers that match in the first N
123046283Sdfr   characters.  The value N is in `id_clash_len'.  */
1231194061Savg
1232194061Savgint warn_id_clash;
1233194061Savgunsigned id_clash_len;
1234194061Savg
1235194061Savg/* Nonzero means warn about any objects definitions whose size is larger
1236194061Savg   than N bytes.  Also want about function definitions whose returned
1237194061Savg   values are larger than N bytes. The value N is in `larger_than_size'.  */
1238194061Savg
1239194061Savgint warn_larger_than;
1240194061Savgunsigned larger_than_size;
1241194061Savg
1242194061Savg/* Nonzero means warn if inline function is too large.  */
1243194061Savg
1244194061Savgint warn_inline;
1245194061Savg
1246194061Savg/* Warn if a function returns an aggregate,
124746283Sdfr   since there are often incompatible calling conventions for doing this.  */
124898944Sobrien
124946283Sdfrint warn_aggregate_return;
125098944Sobrien
125198944Sobrien/* Likewise for -W.  */
125298944Sobrien
125398944Sobrienlang_independent_options W_options[] =
1254194061Savg{
125546283Sdfr  {"unused", &warn_unused, 1, "Warn when a variable is unused" },
125698944Sobrien  {"error", &warnings_are_errors, 1, ""},
125746283Sdfr  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
125846283Sdfr  {"switch", &warn_switch, 1,
125946283Sdfr   "Warn about enumerated switches missing a specific case" },
126098944Sobrien  {"aggregate-return", &warn_aggregate_return, 1,
126198944Sobrien   "Warn about returning structures, unions or arrays" },
126246283Sdfr  {"cast-align", &warn_cast_align, 1,
126398944Sobrien   "Warn about pointer casts which increase alignment" },
126498944Sobrien  {"uninitialized", &warn_uninitialized, 1,
126598944Sobrien   "Warn about unitialized automatic variables"},
126646283Sdfr  {"inline", &warn_inline, 1,
126798944Sobrien   "Warn when an inlined function cannot be inlined"}
126898944Sobrien};
126946283Sdfr
127098944Sobrien/* Output files for assembler code (real compiler output)
127198944Sobrien   and debugging dumps.  */
127298944Sobrien
127398944SobrienFILE *asm_out_file;
127498944SobrienFILE *aux_info_file;
127598944SobrienFILE *rtl_dump_file = NULL;
127698944Sobrien
127798944Sobrien/* Decode the string P as an integral parameter.
127846283Sdfr   If the string is indeed an integer return its numeric value else
127946283Sdfr   issue an Invalid Option error for the option PNAME and return DEFVAL.
128098944Sobrien   If PNAME is zero just return DEFVAL, do not call error.               */
128198944Sobrien
128298944Sobrienint
128398944Sobrienread_integral_parameter (p, pname, defval)
128498944Sobrien     const char *p;
128598944Sobrien     const char *pname;
128698944Sobrien     const int  defval;
128798944Sobrien{
128898944Sobrien  const char *endp = p;
128998944Sobrien
129098944Sobrien  while (*endp)
129198944Sobrien    {
129298944Sobrien      if (*endp >= '0' && *endp <= '9')
129398944Sobrien	endp++;
129498944Sobrien      else
129598944Sobrien	break;
129698944Sobrien    }
129798944Sobrien
129898944Sobrien  if (*endp != 0)
129998944Sobrien    {
130098944Sobrien      if (pname != 0)
130198944Sobrien	error ("Invalid option `%s'", pname);
130246283Sdfr      return defval;
130346283Sdfr    }
1304194061Savg
1305194061Savg  return atoi (p);
1306194061Savg}
1307194061Savg
130846283Sdfr
130946283Sdfr/* Time accumulators, to count the total time spent in various passes.  */
131098944Sobrien
131146283Sdfrint parse_time;
131246283Sdfrint varconst_time;
131398944Sobrienint integration_time;
131446283Sdfrint jump_time;
131546283Sdfrint cse_time;
131698944Sobrienint gcse_time;
131746283Sdfrint loop_time;
131898944Sobrienint cse2_time;
131946283Sdfrint branch_prob_time;
1320194061Savgint flow_time;
1321194061Savgint combine_time;
1322194061Savgint regmove_time;
1323194061Savgint sched_time;
1324194061Savgint local_alloc_time;
132546283Sdfrint global_alloc_time;
132698944Sobrienint flow2_time;
132746283Sdfrint sched2_time;
132819370Spst#ifdef DELAY_SLOTS
132919370Spstint dbr_sched_time;
133019370Spst#endif
133119370Spstint shorten_branch_time;
1332130803Smarcelint stack_reg_time;
1333130803Smarcelint final_time;
133419370Spstint symout_time;
1335130803Smarcelint dump_time;
1336130803Smarcel
1337130803Smarcel/* Return time used so far, in microseconds.  */
1338130803Smarcel
133919370Spstlong
1340130803Smarcelget_run_time ()
134119370Spst{
134219370Spst  if (quiet_flag)
134319370Spst    return 0;
134419370Spst
134519370Spst#ifdef __BEOS__
134619370Spst  return 0;
134719370Spst#else /* not BeOS */
1348130803Smarcel#if defined (_WIN32) && !defined (__CYGWIN__)
134919370Spst  if (clock() < 0)
135046283Sdfr    return 0;
135198944Sobrien  else
1352130803Smarcel    return (clock() * 1000);
135319370Spst#else /* not _WIN32 */
135419370Spst#ifdef _SC_CLK_TCK
135519370Spst  {
135619370Spst    static int tick;
135719370Spst    struct tms tms;
135819370Spst    if (tick == 0)
135919370Spst      tick = 1000000 / sysconf(_SC_CLK_TCK);
136019370Spst    times (&tms);
136119370Spst    return (tms.tms_utime + tms.tms_stime) * tick;
136219370Spst  }
136319370Spst#else
136419370Spst#ifdef USG
136519370Spst  {
136619370Spst    struct tms tms;
136719370Spst#   if HAVE_SYSCONF && defined _SC_CLK_TCK
136819370Spst#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
136998944Sobrien#   else
1370130803Smarcel#    ifdef CLK_TCK
137119370Spst#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
1372130803Smarcel#    else
1373130803Smarcel#     define TICKS_PER_SECOND HZ /* traditional UNIX */
1374130803Smarcel#    endif
137519370Spst#   endif
1376130803Smarcel    times (&tms);
137719370Spst    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
1378130803Smarcel  }
137919370Spst#else
138019370Spst#ifndef VMS
138119370Spst  {
138219370Spst    struct rusage rusage;
138319370Spst    getrusage (0, &rusage);
138419370Spst    return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
138519370Spst	    + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
138619370Spst  }
138719370Spst#else /* VMS */
138819370Spst  {
1389130803Smarcel    struct
139019370Spst      {
139119370Spst        int proc_user_time;
139219370Spst        int proc_system_time;
139319370Spst        int child_user_time;
139419370Spst        int child_system_time;
139519370Spst      } vms_times;
139619370Spst    times ((void *) &vms_times);
139719370Spst    return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
139819370Spst  }
139919370Spst#endif	/* VMS */
140019370Spst#endif	/* USG */
140119370Spst#endif  /* _SC_CLK_TCK */
140219370Spst#endif	/* _WIN32 */
140319370Spst#endif	/* __BEOS__ */
140419370Spst}
140519370Spst
140619370Spst#define TIMEVAR(VAR, BODY)    \
140719370Spstdo { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
140819370Spst
140919370Spstvoid
141019370Spstprint_time (str, total)
1411130803Smarcel     const char *str;
1412130803Smarcel     int total;
141319370Spst{
1414130803Smarcel  fprintf (stderr,
1415130803Smarcel	   "time in %s: %d.%06d\n",
141619370Spst	   str, total / 1000000, total % 1000000);
141719370Spst}
141819370Spst
141919370Spst/* Count an error or warning.  Return 1 if the message should be printed.  */
142019370Spst
142119370Spstint
142298944Sobriencount_error (warningp)
142319370Spst     int warningp;
142419370Spst{
142546283Sdfr  if (warningp && inhibit_warnings)
142619370Spst    return 0;
142719370Spst
142898944Sobrien  if (warningp && !warnings_are_errors)
142998944Sobrien    warningcount++;
143019370Spst  else
143119370Spst    {
143219370Spst      static int warning_message = 0;
143319370Spst
143419370Spst      if (warningp && !warning_message)
143519370Spst	{
143619370Spst	  notice ("%s: warnings being treated as errors\n", progname);
143719370Spst	  warning_message = 1;
143819370Spst	}
143919370Spst      errorcount++;
144019370Spst    }
144119370Spst
144219370Spst  return 1;
144319370Spst}
1444130803Smarcel
1445130803Smarcel/* Print a fatal error message.  NAME is the text.
144619370Spst   Also include a system error message based on `errno'.  */
1447130803Smarcel
1448130803Smarcelvoid
1449130803Smarcelpfatal_with_name (name)
145019370Spst  const char *name;
145119370Spst{
1452130803Smarcel  fprintf (stderr, "%s: ", progname);
145319370Spst  perror (name);
145419370Spst  exit (FATAL_EXIT_CODE);
145519370Spst}
145619370Spst
145719370Spstvoid
145819370Spstfatal_io_error (name)
145919370Spst  const char *name;
146019370Spst{
146119370Spst  notice ("%s: %s: I/O error\n", progname, name);
146219370Spst  exit (FATAL_EXIT_CODE);
146319370Spst}
146419370Spst
146519370Spst/* Called to give a better error message for a bad insn rather than
146619370Spst   just calling abort().  */
146719370Spst
146819370Spstvoid
146919370Spstfatal_insn VPROTO((const char *msgid, rtx insn, ...))
147019370Spst{
147119370Spst#ifndef ANSI_PROTOTYPES
147219370Spst  const char *msgid;
147319370Spst  rtx insn;
147419370Spst#endif
147519370Spst  va_list ap;
147619370Spst
147719370Spst  VA_START (ap, insn);
147819370Spst
147919370Spst#ifndef ANSI_PROTOTYPES
148019370Spst  msgid = va_arg (ap, const char *);
148119370Spst  insn = va_arg (ap, rtx);
148219370Spst#endif
148319370Spst
148419370Spst  verror (msgid, ap);
148519370Spst  debug_rtx (insn);
148619370Spst  exit (FATAL_EXIT_CODE);
148719370Spst}
148819370Spst
148919370Spst/* Called to give a better error message when we don't have an insn to match
149019370Spst   what we are looking for or if the insn's constraints aren't satisfied,
149119370Spst   rather than just calling abort().  */
149219370Spst
149319370Spstvoid
149419370Spstfatal_insn_not_found (insn)
149519370Spst     rtx insn;
149619370Spst{
149719370Spst  if (INSN_CODE (insn) < 0)
149898944Sobrien    fatal_insn ("internal error--unrecognizable insn:", insn);
149998944Sobrien  else
150019370Spst    fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
150119370Spst}
150219370Spst
150319370Spst/* This is the default decl_printable_name function.  */
150419370Spst
150519370Spststatic char *
150619370Spstdecl_name (decl, verbosity)
150719370Spst     tree decl;
150819370Spst     int verbosity ATTRIBUTE_UNUSED;
150919370Spst{
151019370Spst  return IDENTIFIER_POINTER (DECL_NAME (decl));
151146283Sdfr}
151298944Sobrien
151319370Spststatic int need_error_newline;
1514130803Smarcel
151519370Spst/* Function of last error message;
1516130803Smarcel   more generally, function such that if next error message is in it
151719370Spst   then we don't have to mention the function name.  */
151819370Spststatic tree last_error_function = NULL;
151919370Spst
152098944Sobrien/* Used to detect when input_file_stack has changed since last described.  */
152119370Spststatic int last_error_tick;
152298944Sobrien
152346283Sdfr/* Called when the start of a function definition is parsed,
152498944Sobrien   this function prints on stderr the name of the function.  */
152546283Sdfr
152646283Sdfrvoid
152746283Sdfrannounce_function (decl)
152846283Sdfr     tree decl;
152946283Sdfr{
153046283Sdfr  if (! quiet_flag)
153146283Sdfr    {
153246283Sdfr      if (rtl_dump_and_exit)
1533130803Smarcel	fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
153498944Sobrien      else
153546283Sdfr	fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
153646283Sdfr      fflush (stderr);
153746283Sdfr      need_error_newline = 1;
153846283Sdfr      last_error_function = current_function_decl;
153998944Sobrien    }
1540130803Smarcel}
154198944Sobrien
154298944Sobrien/* The default function to print out name of current function that caused
1543130803Smarcel   an error.  */
154446283Sdfr
154519370Spstvoid
154619370Spstdefault_print_error_function (file)
154719370Spst  const char *file;
1548130803Smarcel{
1549130803Smarcel  if (last_error_function != current_function_decl)
155019370Spst    {
155119370Spst      if (file)
1552130803Smarcel	fprintf (stderr, "%s: ", file);
1553130803Smarcel
1554130803Smarcel      if (current_function_decl == NULL)
1555130803Smarcel	notice ("At top level:\n");
155619370Spst      else
155719370Spst	notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
155819370Spst		 ? "In method `%s':\n"
155919370Spst		 : "In function `%s':\n"),
156019370Spst		(*decl_printable_name) (current_function_decl, 2));
156119370Spst
156219370Spst      last_error_function = current_function_decl;
156319370Spst    }
1564130803Smarcel}
156519370Spst
156619370Spst/* Called by report_error_function to print out function name.
156719370Spst * Default may be overridden by language front-ends.  */
156819370Spst
156919370Spstvoid (*print_error_function) PROTO((const char *)) =
157019370Spst  default_print_error_function;
157119370Spst
157219370Spst/* Prints out, if necessary, the name of the current function
157319370Spst  that caused an error.  Called from all error and warning functions.
1574130803Smarcel  We ignore the FILE parameter, as it cannot be relied upon.  */
157519370Spst
1576130803Smarcelvoid
157719370Spstreport_error_function (file)
157819370Spst  const char *file ATTRIBUTE_UNUSED;
157919370Spst{
158019370Spst  struct file_stack *p;
158119370Spst
158219370Spst  if (need_error_newline)
158319370Spst    {
158419370Spst      fprintf (stderr, "\n");
158519370Spst      need_error_newline = 0;
158619370Spst    }
158719370Spst
158819370Spst  if (input_file_stack && input_file_stack->next != 0
158919370Spst      && input_file_stack_tick != last_error_tick)
1590130803Smarcel    {
1591130803Smarcel      for (p = input_file_stack->next; p; p = p->next)
159219370Spst	notice ((p == input_file_stack->next
159319370Spst		 ?    "In file included from %s:%d"
159419370Spst		 : ",\n                 from %s:%d"),
159519370Spst		p->name, p->line);
159619370Spst      fprintf (stderr, ":\n");
159719370Spst      last_error_tick = input_file_stack_tick;
159819370Spst    }
159919370Spst
160019370Spst  (*print_error_function) (input_filename);
160119370Spst}
160219370Spst
160319370Spst/* Print a message.  */
160419370Spst
160519370Spststatic void
160619370Spstvnotice (file, msgid, ap)
160746283Sdfr     FILE *file;
160898944Sobrien     char *msgid;
160919370Spst     va_list ap;
1610130803Smarcel{
161119370Spst  vfprintf (file, _(msgid), ap);
1612130803Smarcel}
161319370Spst
161446283Sdfrvoid
161546283Sdfrnotice VPROTO((const char *msgid, ...))
161646283Sdfr{
161798944Sobrien#ifndef ANSI_PROTOTYPES
161846283Sdfr  char *msgid;
161998944Sobrien#endif
162098944Sobrien  va_list ap;
162146283Sdfr
162298944Sobrien  VA_START (ap, msgid);
162346283Sdfr
1624130803Smarcel#ifndef ANSI_PROTOTYPES
1625130803Smarcel  msgid = va_arg (ap, char *);
1626130803Smarcel#endif
1627130803Smarcel
162819370Spst  vnotice (stderr, msgid, ap);
1629130803Smarcel  va_end (ap);
163019370Spst}
163198944Sobrien
1632130803Smarcelvoid
163319370Spstfnotice VPROTO((FILE *file, const char *msgid, ...))
163419370Spst{
163598944Sobrien#ifndef ANSI_PROTOTYPES
1636130803Smarcel  FILE *file;
1637130803Smarcel  const char *msgid;
163819370Spst#endif
1639130803Smarcel  va_list ap;
1640130803Smarcel
1641130803Smarcel  VA_START (ap, msgid);
164246283Sdfr
164319370Spst#ifndef ANSI_PROTOTYPES
1644130803Smarcel  file = va_arg (ap, FILE *);
164519370Spst  msgid = va_arg (ap, const char *);
164619370Spst#endif
164719370Spst
164819370Spst  vnotice (file, msgid, ap);
1649130803Smarcel  va_end (ap);
1650130803Smarcel}
1651130803Smarcel
1652130803Smarcel/* Report FILE and LINE (or program name), and optionally just WARN.  */
1653130803Smarcel
1654130803Smarcelstatic void
1655130803Smarcelreport_file_and_line (file, line, warn)
1656130803Smarcel     char *file;
1657130803Smarcel     int line;
1658130803Smarcel     int warn;
1659130803Smarcel{
1660130803Smarcel  if (file)
1661130803Smarcel    fprintf (stderr, "%s:%d: ", file, line);
1662130803Smarcel  else
1663130803Smarcel    fprintf (stderr, "%s: ", progname);
1664130803Smarcel
1665130803Smarcel  if (warn)
1666130803Smarcel    notice ("warning: ");
166719370Spst}
166819370Spst
166919370Spst/* Print a message.  */
167019370Spst
167119370Spststatic void
167219370Spstvmessage (prefix, msgid, ap)
167319370Spst     const char *prefix;
167419370Spst     const char *msgid;
167519370Spst     va_list ap;
167619370Spst{
167719370Spst  if (prefix)
167819370Spst    fprintf (stderr, "%s: ", prefix);
1679130803Smarcel
1680130803Smarcel  vfprintf (stderr, msgid, ap);
168119370Spst}
1682130803Smarcel
1683130803Smarcel/* Print a message relevant to line LINE of file FILE.  */
168419370Spst
168519370Spststatic void
168619370Spstv_message_with_file_and_line (file, line, warn, msgid, ap)
168719370Spst     const char *file;
168819370Spst     int line;
168919370Spst     int warn;
169019370Spst     const char *msgid;
169119370Spst     va_list ap;
169219370Spst{
169319370Spst  report_file_and_line (file, line, warn);
169419370Spst  vnotice (stderr, msgid, ap);
169519370Spst  fputc ('\n', stderr);
169619370Spst}
169719370Spst
169898944Sobrien/* Print a message relevant to the given DECL.  */
169998944Sobrien
170098944Sobrienstatic void
170198944Sobrienv_message_with_decl (decl, warn, msgid, ap)
170298944Sobrien     tree decl;
170398944Sobrien     int warn;
170498944Sobrien     const char *msgid;
170598944Sobrien     va_list ap;
170619370Spst{
170719370Spst  const char *p;
170819370Spst
170919370Spst  report_file_and_line (DECL_SOURCE_FILE (decl),
171019370Spst			DECL_SOURCE_LINE (decl), warn);
171119370Spst
171219370Spst  /* Do magic to get around lack of varargs support for insertion
171319370Spst     of arguments into existing list.  We know that the decl is first;
171419370Spst     we ass_u_me that it will be printed with "%s".  */
171519370Spst
171698944Sobrien  for (p = _(msgid); *p; ++p)
171798944Sobrien    {
171819370Spst      if (*p == '%')
1719130803Smarcel	{
1720130803Smarcel	  if (*(p + 1) == '%')
172119370Spst	    ++p;
172219370Spst	  else if (*(p + 1) != 's')
172319370Spst	    abort ();
172419370Spst	  else
172519370Spst	    break;
172619370Spst	}
1727130803Smarcel    }
1728130803Smarcel
1729130803Smarcel  if (p > _(msgid))			/* Print the left-hand substring.  */
173019370Spst    {
173119370Spst      char fmt[sizeof "%.255s"];
173219370Spst      long width = p - _(msgid);
173319370Spst
173419370Spst      if (width > 255L) width = 255L;	/* arbitrary */
173519370Spst      sprintf (fmt, "%%.%lds", width);
173646283Sdfr      fprintf (stderr, fmt, _(msgid));
173798944Sobrien    }
173819370Spst
173919370Spst  if (*p == '%')		/* Print the name.  */
1740130803Smarcel    {
1741130803Smarcel      const char *n = (DECL_NAME (decl)
174219370Spst		 ? (*decl_printable_name) (decl, 2)
174319370Spst		 : "((anonymous))");
174446283Sdfr      fputs (n, stderr);
174546283Sdfr      while (*p)
174698944Sobrien	{
174798944Sobrien	  ++p;
174846283Sdfr	  if (ISALPHA (*(p - 1) & 0xFF))
1749130803Smarcel	    break;
175098944Sobrien	}
1751130803Smarcel    }
1752130803Smarcel
175398944Sobrien  if (*p)			/* Print the rest of the message.  */
175446283Sdfr    vmessage ((char *)NULL, p, ap);
175519370Spst
175619370Spst  fputc ('\n', stderr);
175719370Spst}
175819370Spst
175998944Sobrien/* Figure file and line of the given INSN.  */
176019370Spst
1761130803Smarcelstatic void
176219370Spstfile_and_line_for_asm (insn, pfile, pline)
176319370Spst     rtx insn;
176498944Sobrien     char **pfile;
176519370Spst     int *pline;
176698944Sobrien{
1767130803Smarcel  rtx body = PATTERN (insn);
176819370Spst  rtx asmop;
176919370Spst
1770130803Smarcel  /* Find the (or one of the) ASM_OPERANDS in the insn.  */
177119370Spst  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
177219370Spst    asmop = SET_SRC (body);
1773130803Smarcel  else if (GET_CODE (body) == ASM_OPERANDS)
1774130803Smarcel    asmop = body;
177519370Spst  else if (GET_CODE (body) == PARALLEL
177619370Spst	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
177719370Spst    asmop = SET_SRC (XVECEXP (body, 0, 0));
177898944Sobrien  else if (GET_CODE (body) == PARALLEL
177946283Sdfr	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
178098944Sobrien    asmop = XVECEXP (body, 0, 0);
178146283Sdfr  else
178246283Sdfr    asmop = NULL;
178346283Sdfr
178498944Sobrien  if (asmop)
178519370Spst    {
178646283Sdfr      *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
1787130803Smarcel      *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
1788130803Smarcel    }
178919370Spst  else
179019370Spst    {
179119370Spst      *pfile = input_filename;
179219370Spst      *pline = lineno;
179319370Spst    }
179419370Spst}
179598944Sobrien
179619370Spst/* Report an error at line LINE of file FILE.  */
1797130803Smarcel
179819370Spststatic void
179919370Spstv_error_with_file_and_line (file, line, msgid, ap)
180098944Sobrien     const char *file;
180119370Spst     int line;
180298944Sobrien     const char *msgid;
1803130803Smarcel     va_list ap;
180419370Spst{
180519370Spst  count_error (0);
1806130803Smarcel  report_error_function (file);
180719370Spst  v_message_with_file_and_line (file, line, 0, msgid, ap);
180819370Spst}
180919370Spst
181019370Spstvoid
181198944Sobrienerror_with_file_and_line VPROTO((const char *file, int line,
181298944Sobrien				 const char *msgid, ...))
181398944Sobrien{
181419370Spst#ifndef ANSI_PROTOTYPES
181519370Spst  const char *file;
181619370Spst  int line;
181719370Spst  const char *msgid;
1818130803Smarcel#endif
1819130803Smarcel  va_list ap;
182019370Spst
182119370Spst  VA_START (ap, msgid);
182246283Sdfr
182398944Sobrien#ifndef ANSI_PROTOTYPES
182446283Sdfr  file = va_arg (ap, const char *);
182546283Sdfr  line = va_arg (ap, int);
182646283Sdfr  msgid = va_arg (ap, const char *);
182719370Spst#endif
182819370Spst
182998944Sobrien  v_error_with_file_and_line (file, line, msgid, ap);
183019370Spst  va_end (ap);
183146283Sdfr}
1832130803Smarcel
1833130803Smarcel/* Report an error at the declaration DECL.
183419370Spst   MSGID is a format string which uses %s to substitute the declaration
183519370Spst   name; subsequent substitutions are a la printf.  */
183698944Sobrien
183798944Sobrienstatic void
183819370Spstv_error_with_decl (decl, msgid, ap)
183919370Spst     tree decl;
184098944Sobrien     const char *msgid;
1841130803Smarcel     va_list ap;
184219370Spst{
1843130803Smarcel  count_error (0);
1844130803Smarcel  report_error_function (DECL_SOURCE_FILE (decl));
1845130803Smarcel  v_message_with_decl (decl, 0, msgid, ap);
1846130803Smarcel}
1847130803Smarcel
184819370Spstvoid
1849130803Smarcelerror_with_decl VPROTO((tree decl, const char *msgid, ...))
185019370Spst{
1851130803Smarcel#ifndef ANSI_PROTOTYPES
1852130803Smarcel  tree decl;
1853130803Smarcel  const char *msgid;
1854130803Smarcel#endif
185519370Spst  va_list ap;
185619370Spst
185719370Spst  VA_START (ap, msgid);
185819370Spst
1859130803Smarcel#ifndef ANSI_PROTOTYPES
1860130803Smarcel  decl = va_arg (ap, tree);
186119370Spst  msgid = va_arg (ap, const char *);
186219370Spst#endif
1863130803Smarcel
1864130803Smarcel  v_error_with_decl (decl, msgid, ap);
186519370Spst  va_end (ap);
186619370Spst}
186719370Spst
186819370Spst/* Report an error at the line number of the insn INSN.
186919370Spst   This is used only when INSN is an `asm' with operands,
187019370Spst   and each ASM_OPERANDS records its own source file and line.  */
1871130803Smarcel
1872130803Smarcelstatic void
187319370Spstv_error_for_asm (insn, msgid, ap)
187419370Spst     rtx insn;
1875130803Smarcel     const char *msgid;
1876130803Smarcel     va_list ap;
1877130803Smarcel{
1878130803Smarcel  char *file;
1879130803Smarcel  int line;
1880130803Smarcel
1881130803Smarcel  count_error (0);
1882130803Smarcel  file_and_line_for_asm (insn, &file, &line);
1883130803Smarcel  report_error_function (file);
1884130803Smarcel  v_message_with_file_and_line (file, line, 0, msgid, ap);
1885130803Smarcel}
1886130803Smarcel
1887130803Smarcelvoid
1888130803Smarcelerror_for_asm VPROTO((rtx insn, const char *msgid, ...))
1889130803Smarcel{
1890130803Smarcel#ifndef ANSI_PROTOTYPES
1891130803Smarcel  rtx insn;
1892130803Smarcel  const char *msgid;
1893130803Smarcel#endif
1894130803Smarcel  va_list ap;
1895130803Smarcel
1896130803Smarcel  VA_START (ap, msgid);
1897130803Smarcel
1898130803Smarcel#ifndef ANSI_PROTOTYPES
1899130803Smarcel  insn = va_arg (ap, rtx);
1900130803Smarcel  msgid = va_arg (ap, const char *);
1901130803Smarcel#endif
1902130803Smarcel
1903130803Smarcel  v_error_for_asm (insn, msgid, ap);
1904130803Smarcel  va_end (ap);
1905130803Smarcel}
190619370Spst
190719370Spst/* Report an error at the current line number.  */
1908130803Smarcel
1909130803Smarcelstatic void
1910130803Smarcelverror (msgid, ap)
191119370Spst     const char *msgid;
191219370Spst     va_list ap;
1913130803Smarcel{
1914130803Smarcel  v_error_with_file_and_line (input_filename, lineno, msgid, ap);
1915130803Smarcel}
1916130803Smarcel
1917130803Smarcelvoid
1918130803Smarcelerror VPROTO((const char *msgid, ...))
1919130803Smarcel{
1920130803Smarcel#ifndef ANSI_PROTOTYPES
1921130803Smarcel  const char *msgid;
192219370Spst#endif
192319370Spst  va_list ap;
1924130803Smarcel
1925130803Smarcel  VA_START (ap, msgid);
1926130803Smarcel
192719370Spst#ifndef ANSI_PROTOTYPES
1928130803Smarcel  msgid = va_arg (ap, const char *);
1929130803Smarcel#endif
1930130803Smarcel
1931130803Smarcel  verror (msgid, ap);
1932130803Smarcel  va_end (ap);
1933130803Smarcel}
1934130803Smarcel
1935130803Smarcel/* Report a fatal error at the current line number.  */
1936130803Smarcel
1937130803Smarcelstatic void
1938130803Smarcelvfatal (msgid, ap)
1939130803Smarcel     const char *msgid;
1940130803Smarcel     va_list ap;
194119370Spst{
1942130803Smarcel  verror (msgid, ap);
1943130803Smarcel  exit (FATAL_EXIT_CODE);
1944130803Smarcel}
194519370Spst
1946130803Smarcelvoid
1947130803Smarcelfatal VPROTO((const char *msgid, ...))
1948130803Smarcel{
1949130803Smarcel#ifndef ANSI_PROTOTYPES
1950130803Smarcel  const char *msgid;
1951130803Smarcel#endif
1952130803Smarcel  va_list ap;
1953130803Smarcel
1954130803Smarcel  VA_START (ap, msgid);
1955130803Smarcel
1956130803Smarcel#ifndef ANSI_PROTOTYPES
1957130803Smarcel  msgid = va_arg (ap, const char *);
1958130803Smarcel#endif
1959130803Smarcel
1960130803Smarcel  vfatal (msgid, ap);
1961130803Smarcel  va_end (ap);
1962130803Smarcel}
1963130803Smarcel
1964130803Smarcel/* Report a warning at line LINE of file FILE.  */
1965130803Smarcel
1966130803Smarcelstatic void
1967130803Smarcelv_warning_with_file_and_line (file, line, msgid, ap)
1968130803Smarcel     const char *file;
196919370Spst     int line;
1970130803Smarcel     const char *msgid;
1971130803Smarcel     va_list ap;
1972130803Smarcel{
1973130803Smarcel  if (count_error (1))
1974130803Smarcel    {
1975130803Smarcel      report_error_function (file);
1976130803Smarcel      v_message_with_file_and_line (file, line, 1, msgid, ap);
1977130803Smarcel    }
1978130803Smarcel}
1979130803Smarcel
1980130803Smarcelvoid
1981130803Smarcelwarning_with_file_and_line VPROTO((const char *file, int line,
1982130803Smarcel				   const char *msgid, ...))
1983130803Smarcel{
1984130803Smarcel#ifndef ANSI_PROTOTYPES
1985130803Smarcel  const char *file;
198619370Spst  int line;
198719370Spst  const char *msgid;
198819370Spst#endif
198919370Spst  va_list ap;
199019370Spst
199119370Spst  VA_START (ap, msgid);
199219370Spst
199319370Spst#ifndef ANSI_PROTOTYPES
199446283Sdfr  file = va_arg (ap, const char *);
199546283Sdfr  line = va_arg (ap, int);
199646283Sdfr  msgid = va_arg (ap, const char *);
199746283Sdfr#endif
199846283Sdfr
199946283Sdfr  v_warning_with_file_and_line (file, line, msgid, ap);
200046283Sdfr  va_end (ap);
200146283Sdfr}
200298944Sobrien
200346283Sdfr/* Report a warning at the declaration DECL.
200498944Sobrien   MSGID is a format string which uses %s to substitute the declaration
200546283Sdfr   name; subsequent substitutions are a la printf.  */
200646283Sdfr
200746283Sdfrstatic void
200846283Sdfrv_warning_with_decl (decl, msgid, ap)
200946283Sdfr     tree decl;
201046283Sdfr     const char *msgid;
201146283Sdfr     va_list ap;
201246283Sdfr{
201346283Sdfr  if (count_error (1))
201446283Sdfr    {
201546283Sdfr      report_error_function (DECL_SOURCE_FILE (decl));
201646283Sdfr      v_message_with_decl (decl, 1, msgid, ap);
201746283Sdfr    }
201846283Sdfr}
201946283Sdfr
202046283Sdfrvoid
202146283Sdfrwarning_with_decl VPROTO((tree decl, const char *msgid, ...))
202246283Sdfr{
202346283Sdfr#ifndef ANSI_PROTOTYPES
202446283Sdfr  tree decl;
202546283Sdfr  const char *msgid;
202646283Sdfr#endif
202746283Sdfr  va_list ap;
202846283Sdfr
202946283Sdfr  VA_START (ap, msgid);
203046283Sdfr
203146283Sdfr#ifndef ANSI_PROTOTYPES
203246283Sdfr  decl = va_arg (ap, tree);
203346283Sdfr  msgid = va_arg (ap, const char *);
203446283Sdfr#endif
203546283Sdfr
2036130803Smarcel  v_warning_with_decl (decl, msgid, ap);
2037130803Smarcel  va_end (ap);
203846283Sdfr}
203946283Sdfr
204046283Sdfr/* Report a warning at the line number of the insn INSN.
204146283Sdfr   This is used only when INSN is an `asm' with operands,
204246283Sdfr   and each ASM_OPERANDS records its own source file and line.  */
204346283Sdfr
204446283Sdfrstatic void
204546283Sdfrv_warning_for_asm (insn, msgid, ap)
204646283Sdfr     rtx insn;
204798944Sobrien     const char *msgid;
204846283Sdfr     va_list ap;
204946283Sdfr{
205046283Sdfr  if (count_error (1))
2051130803Smarcel    {
2052130803Smarcel      char *file;
205346283Sdfr      int line;
205446283Sdfr
205519370Spst      file_and_line_for_asm (insn, &file, &line);
205619370Spst      report_error_function (file);
205719370Spst      v_message_with_file_and_line (file, line, 1, msgid, ap);
205898944Sobrien    }
205919370Spst}
2060130803Smarcel
206119370Spstvoid
206298944Sobrienwarning_for_asm VPROTO((rtx insn, const char *msgid, ...))
2063130803Smarcel{
206419370Spst#ifndef ANSI_PROTOTYPES
2065130803Smarcel  rtx insn;
2066130803Smarcel  const char *msgid;
2067130803Smarcel#endif
2068130803Smarcel  va_list ap;
2069130803Smarcel
2070130803Smarcel  VA_START (ap, msgid);
2071130803Smarcel
2072130803Smarcel#ifndef ANSI_PROTOTYPES
207319370Spst  insn = va_arg (ap, rtx);
207419370Spst  msgid = va_arg (ap, const char *);
207519370Spst#endif
207619370Spst
207719370Spst  v_warning_for_asm (insn, msgid, ap);
207819370Spst  va_end (ap);
207919370Spst}
208019370Spst
208119370Spst/* Report a warning at the current line number.  */
208219370Spst
208319370Spststatic void
208419370Spstvwarning (msgid, ap)
208598944Sobrien     const char *msgid;
208619370Spst     va_list ap;
208798944Sobrien{
208819370Spst  v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
208919370Spst}
209019370Spst
209119370Spstvoid
209219370Spstwarning VPROTO((const char *msgid, ...))
209319370Spst{
209419370Spst#ifndef ANSI_PROTOTYPES
209519370Spst  const char *msgid;
209619370Spst#endif
209719370Spst  va_list ap;
209819370Spst
209919370Spst  VA_START (ap, msgid);
210019370Spst
210119370Spst#ifndef ANSI_PROTOTYPES
210219370Spst  msgid = va_arg (ap, const char *);
210319370Spst#endif
210419370Spst
210519370Spst  vwarning (msgid, ap);
210619370Spst  va_end (ap);
210719370Spst}
210819370Spst
210919370Spst/* These functions issue either warnings or errors depending on
211019370Spst   -pedantic-errors.  */
211119370Spst
211219370Spststatic void
211319370Spstvpedwarn (msgid, ap)
211419370Spst     const char *msgid;
211519370Spst     va_list ap;
211619370Spst{
211719370Spst  if (flag_pedantic_errors)
211819370Spst    verror (msgid, ap);
211919370Spst  else
212019370Spst    vwarning (msgid, ap);
212119370Spst}
212219370Spst
212346283Sdfrvoid
212446283Sdfrpedwarn VPROTO((const char *msgid, ...))
212598944Sobrien{
212698944Sobrien#ifndef ANSI_PROTOTYPES
212746283Sdfr  const char *msgid;
212846283Sdfr#endif
212919370Spst  va_list ap;
213019370Spst
213119370Spst  VA_START (ap, msgid);
213219370Spst
213319370Spst#ifndef ANSI_PROTOTYPES
213419370Spst  msgid = va_arg (ap, const char *);
213519370Spst#endif
213646283Sdfr
213746283Sdfr  vpedwarn (msgid, ap);
213819370Spst  va_end (ap);
213946283Sdfr}
214046283Sdfr
214146283Sdfrstatic void
214246283Sdfrv_pedwarn_with_decl (decl, msgid, ap)
214398944Sobrien     tree decl;
214446283Sdfr     const char *msgid;
214546283Sdfr     va_list ap;
214646283Sdfr{
214746283Sdfr  /* We don't want -pedantic-errors to cause the compilation to fail from
214846283Sdfr     "errors" in system header files.  Sometimes fixincludes can't fix what's
214919370Spst     broken (eg: unsigned char bitfields - fixing it may change the alignment
215019370Spst     which will cause programs to mysteriously fail because the C library
215119370Spst     or kernel uses the original layout).  There's no point in issuing a
215219370Spst     warning either, it's just unnecessary noise.  */
215319370Spst
215419370Spst  if (! DECL_IN_SYSTEM_HEADER (decl))
215519370Spst    {
215619370Spst      if (flag_pedantic_errors)
215719370Spst	v_error_with_decl (decl, msgid, ap);
215819370Spst      else
215919370Spst	v_warning_with_decl (decl, msgid, ap);
216046283Sdfr    }
216198944Sobrien}
216298944Sobrien
216346283Sdfrvoid
216446283Sdfrpedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
216598944Sobrien{
216698944Sobrien#ifndef ANSI_PROTOTYPES
216746283Sdfr  tree decl;
216819370Spst  const char *msgid;
216919370Spst#endif
217019370Spst  va_list ap;
217119370Spst
217298944Sobrien  VA_START (ap, msgid);
217398944Sobrien
217419370Spst#ifndef ANSI_PROTOTYPES
217519370Spst  decl = va_arg (ap, tree);
217698944Sobrien  msgid = va_arg (ap, const char *);
217719370Spst#endif
217819370Spst
2179  v_pedwarn_with_decl (decl, msgid, ap);
2180  va_end (ap);
2181}
2182
2183static void
2184v_pedwarn_with_file_and_line (file, line, msgid, ap)
2185     const char *file;
2186     int line;
2187     const char *msgid;
2188     va_list ap;
2189{
2190  if (flag_pedantic_errors)
2191    v_error_with_file_and_line (file, line, msgid, ap);
2192  else
2193    v_warning_with_file_and_line (file, line, msgid, ap);
2194}
2195
2196void
2197pedwarn_with_file_and_line VPROTO((const char *file, int line,
2198				   const char *msgid, ...))
2199{
2200#ifndef ANSI_PROTOTYPES
2201  const char *file;
2202  int line;
2203  const char *msgid;
2204#endif
2205  va_list ap;
2206
2207  VA_START (ap, msgid);
2208
2209#ifndef ANSI_PROTOTYPES
2210  file = va_arg (ap, const char *);
2211  line = va_arg (ap, int);
2212  msgid = va_arg (ap, const char *);
2213#endif
2214
2215  v_pedwarn_with_file_and_line (file, line, msgid, ap);
2216  va_end (ap);
2217}
2218
2219/* Apologize for not implementing some feature.  */
2220
2221static void
2222vsorry (msgid, ap)
2223     const char *msgid;
2224     va_list ap;
2225{
2226  sorrycount++;
2227  if (input_filename)
2228    fprintf (stderr, "%s:%d: ", input_filename, lineno);
2229  else
2230    fprintf (stderr, "%s: ", progname);
2231  notice ("sorry, not implemented: ");
2232  vnotice (stderr, msgid, ap);
2233  fputc ('\n', stderr);
2234}
2235
2236void
2237sorry VPROTO((const char *msgid, ...))
2238{
2239#ifndef ANSI_PROTOTYPES
2240  const char *msgid;
2241#endif
2242  va_list ap;
2243
2244  VA_START (ap, msgid);
2245
2246#ifndef ANSI_PROTOTYPES
2247  msgid = va_arg (ap, const char *);
2248#endif
2249
2250  vsorry (msgid, ap);
2251  va_end (ap);
2252}
2253
2254/* Given a partial pathname as input, return another pathname that shares
2255   no elements with the pathname of __FILE__.  This is used by abort() to
2256   print `Internal compiler error in expr.c' instead of `Internal compiler
2257   error in ../../egcs/gcc/expr.c'.  */
2258const char *
2259trim_filename (name)
2260     const char *name;
2261{
2262  static const char *this_file = __FILE__;
2263  const char *p = name, *q = this_file;
2264
2265  while (*p == *q && *p != 0 && *q != 0) p++, q++;
2266  while (p > name && p[-1] != DIR_SEPARATOR
2267#ifdef DIR_SEPARATOR_2
2268	 && p[-1] != DIR_SEPARATOR_2
2269#endif
2270	 )
2271    p--;
2272
2273  return p;
2274}
2275
2276/* More 'friendly' abort that prints the line and file.
2277   config.h can #define abort fancy_abort if you like that sort of thing.
2278
2279   I don't think this is actually a good idea.
2280   Other sorts of crashes will look a certain way.
2281   It is a good thing if crashes from calling abort look the same way.
2282     -- RMS  */
2283
2284void
2285fancy_abort ()
2286{
2287  fatal ("internal gcc abort");
2288}
2289
2290/* This calls abort and is used to avoid problems when abort if a macro.
2291   It is used when we need to pass the address of abort.  */
2292
2293void
2294do_abort ()
2295{
2296  abort ();
2297}
2298
2299/* When `malloc.c' is compiled with `rcheck' defined,
2300   it calls this function to report clobberage.  */
2301
2302void
2303botch (s)
2304  const char * s ATTRIBUTE_UNUSED;
2305{
2306  abort ();
2307}
2308
2309/* Same as `malloc' but report error if no memory available.  */
2310
2311PTR
2312xmalloc (size)
2313  size_t size;
2314{
2315  register PTR value;
2316
2317  if (size == 0)
2318    size = 1;
2319
2320  value = (PTR) malloc (size);
2321  if (value == 0)
2322    fatal ("virtual memory exhausted");
2323  return value;
2324}
2325
2326/* Same as `calloc' but report error if no memory available.  */
2327
2328PTR
2329xcalloc (size1, size2)
2330  size_t size1, size2;
2331{
2332  register PTR value;
2333
2334  if (size1 == 0 || size2 == 0)
2335    size1 = size2 = 1;
2336
2337  value = (PTR) calloc (size1, size2);
2338  if (value == 0)
2339    fatal ("virtual memory exhausted");
2340  return value;
2341}
2342
2343
2344/* Same as `realloc' but report error if no memory available.
2345   Also handle null PTR even if the vendor realloc gets it wrong.  */
2346
2347PTR
2348xrealloc (ptr, size)
2349  PTR ptr;
2350  size_t size;
2351{
2352  register PTR result;
2353
2354  if (size == 0)
2355    size = 1;
2356
2357  result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
2358
2359  if (!result)
2360    fatal ("virtual memory exhausted");
2361
2362  return result;
2363}
2364
2365/* Same as `strdup' but report error if no memory available.  */
2366
2367char *
2368xstrdup (s)
2369  register const char *s;
2370{
2371  register char *result = (char *) malloc (strlen (s) + 1);
2372
2373  if (! result)
2374    fatal ("virtual memory exhausted");
2375  strcpy (result, s);
2376  return result;
2377}
2378
2379/* Return the logarithm of X, base 2, considering X unsigned,
2380   if X is a power of 2.  Otherwise, returns -1.
2381
2382   This should be used via the `exact_log2' macro.  */
2383
2384int
2385exact_log2_wide (x)
2386     register unsigned HOST_WIDE_INT x;
2387{
2388  register int log = 0;
2389  /* Test for 0 or a power of 2.  */
2390  if (x == 0 || x != (x & -x))
2391    return -1;
2392  while ((x >>= 1) != 0)
2393    log++;
2394  return log;
2395}
2396
2397/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
2398   If X is 0, return -1.
2399
2400   This should be used via the floor_log2 macro.  */
2401
2402int
2403floor_log2_wide (x)
2404     register unsigned HOST_WIDE_INT x;
2405{
2406  register int log = -1;
2407  while (x != 0)
2408    log++,
2409    x >>= 1;
2410  return log;
2411}
2412
2413static int float_handler_set;
2414int float_handled;
2415jmp_buf float_handler;
2416
2417/* Signals actually come here.  */
2418
2419static void
2420float_signal (signo)
2421     /* If this is missing, some compilers complain.  */
2422     int signo ATTRIBUTE_UNUSED;
2423{
2424  if (float_handled == 0)
2425    abort ();
2426#if defined (USG) || defined (hpux)
2427  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
2428#endif
2429  float_handled = 0;
2430  signal (SIGFPE, float_signal);
2431  longjmp (float_handler, 1);
2432}
2433
2434/* Specify where to longjmp to when a floating arithmetic error happens.
2435   If HANDLER is 0, it means don't handle the errors any more.  */
2436
2437void
2438set_float_handler (handler)
2439     jmp_buf handler;
2440{
2441  float_handled = (handler != 0);
2442  if (handler)
2443    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
2444
2445  if (float_handled && ! float_handler_set)
2446    {
2447      signal (SIGFPE, float_signal);
2448      float_handler_set = 1;
2449    }
2450}
2451
2452/* This is a wrapper function for code which might elicit an
2453   arithmetic exception.  That code should be passed in as a function
2454   pointer FN, and one argument DATA.  DATA is usually a struct which
2455   contains the real input and output for function FN.  This function
2456   returns 0 (failure) if longjmp was called (i.e. an exception
2457   occured.)  It returns 1 (success) otherwise. */
2458
2459int
2460do_float_handler (fn, data)
2461  void (*fn) PROTO ((PTR));
2462  PTR data;
2463{
2464  jmp_buf buf;
2465
2466  if (setjmp (buf))
2467    {
2468      /* We got here via longjmp() caused by an exception in function fn() */
2469      set_float_handler (NULL);
2470      return 0;
2471    }
2472
2473  set_float_handler (buf);
2474  (*fn)(data);
2475  set_float_handler (NULL);
2476  return 1;
2477}
2478
2479/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
2480   error happens, pushing the previous specification into OLD_HANDLER.
2481   Return an indication of whether there was a previous handler in effect.  */
2482
2483int
2484push_float_handler (handler, old_handler)
2485     jmp_buf handler, old_handler;
2486{
2487  int was_handled = float_handled;
2488
2489  float_handled = 1;
2490  if (was_handled)
2491    memcpy ((char *) old_handler, (char *) float_handler,
2492	   sizeof (float_handler));
2493
2494  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
2495  return was_handled;
2496}
2497
2498/* Restore the previous specification of whether and where to longjmp to
2499   when a floating arithmetic error happens.  */
2500
2501void
2502pop_float_handler (handled, handler)
2503     int handled;
2504     jmp_buf handler;
2505{
2506  float_handled = handled;
2507  if (handled)
2508    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
2509}
2510
2511/* Handler for SIGPIPE.  */
2512
2513static void
2514pipe_closed (signo)
2515     /* If this is missing, some compilers complain.  */
2516     int signo ATTRIBUTE_UNUSED;
2517{
2518  fatal ("output pipe has been closed");
2519}
2520
2521/* Strip off a legitimate source ending from the input string NAME of
2522   length LEN.  Rather than having to know the names used by all of
2523   our front ends, we strip off an ending of a period followed by
2524   up to five characters.  (Java uses ".class".) */
2525
2526void
2527strip_off_ending (name, len)
2528     char *name;
2529     int len;
2530{
2531  int i;
2532  for (i = 2;  i < 6 && len > i;  i++)
2533    {
2534      if (name[len - i] == '.')
2535	{
2536	  name[len - i] = '\0';
2537	  break;
2538	}
2539    }
2540}
2541
2542/* Output a quoted string.  */
2543
2544void
2545output_quoted_string (asm_file, string)
2546     FILE *asm_file;
2547     const char *string;
2548{
2549#ifdef OUTPUT_QUOTED_STRING
2550  OUTPUT_QUOTED_STRING (asm_file, string);
2551#else
2552  char c;
2553
2554  putc ('\"', asm_file);
2555  while ((c = *string++) != 0)
2556    {
2557      if (c == '\"' || c == '\\')
2558	putc ('\\', asm_file);
2559      putc (c, asm_file);
2560    }
2561  putc ('\"', asm_file);
2562#endif
2563}
2564
2565/* Output a file name in the form wanted by System V.  */
2566
2567void
2568output_file_directive (asm_file, input_name)
2569     FILE *asm_file;
2570     const char *input_name;
2571{
2572  int len = strlen (input_name);
2573  const char *na = input_name + len;
2574
2575  /* NA gets INPUT_NAME sans directory names.  */
2576  while (na > input_name)
2577    {
2578      if (na[-1] == '/')
2579	break;
2580#ifdef DIR_SEPARATOR
2581      if (na[-1] == DIR_SEPARATOR)
2582	break;
2583#endif
2584      na--;
2585    }
2586
2587#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
2588  ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
2589#else
2590#ifdef ASM_OUTPUT_SOURCE_FILENAME
2591  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
2592#else
2593  fprintf (asm_file, "\t.file\t");
2594  output_quoted_string (asm_file, na);
2595  fputc ('\n', asm_file);
2596#endif
2597#endif
2598}
2599
2600#ifdef ASM_IDENTIFY_LANGUAGE
2601/* Routine to build language identifier for object file.  */
2602static void
2603output_lang_identify (asm_out_file)
2604     FILE *asm_out_file;
2605{
2606  int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
2607  char *s = (char *) alloca (len);
2608  sprintf (s, "__gnu_compiled_%s", lang_identify ());
2609  ASM_OUTPUT_LABEL (asm_out_file, s);
2610}
2611#endif
2612
2613/* Routine to open a dump file.  */
2614static void
2615open_dump_file (suffix, function_name)
2616     const char *suffix;
2617     const char *function_name;
2618{
2619  char *dumpname;
2620
2621  TIMEVAR
2622    (dump_time,
2623     {
2624       dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
2625
2626       if (rtl_dump_file != NULL)
2627	 fclose (rtl_dump_file);
2628
2629       strcpy (dumpname, dump_base_name);
2630       strcat (dumpname, suffix);
2631
2632       rtl_dump_file = fopen (dumpname, "a");
2633
2634       if (rtl_dump_file == NULL)
2635	 pfatal_with_name (dumpname);
2636
2637       free (dumpname);
2638
2639       if (function_name)
2640	 fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
2641     });
2642
2643  return;
2644}
2645
2646/* Routine to close a dump file.  */
2647static void
2648close_dump_file (func, insns)
2649     void (*func) PROTO ((FILE *, rtx));
2650     rtx    insns;
2651{
2652  TIMEVAR
2653    (dump_time,
2654     {
2655       if (func)
2656	 func (rtl_dump_file, insns);
2657
2658       fflush (rtl_dump_file);
2659       fclose (rtl_dump_file);
2660
2661       rtl_dump_file = NULL;
2662     });
2663
2664  return;
2665}
2666
2667/* Routine to dump rtl into a file.  */
2668static void
2669dump_rtl (suffix, decl, func, insns)
2670     const char *suffix;
2671     tree   decl;
2672     void (*func) PROTO ((FILE *, rtx));
2673     rtx    insns;
2674{
2675  open_dump_file (suffix, decl_printable_name (decl, 2));
2676  close_dump_file (func, insns);
2677}
2678
2679/* Routine to empty a dump file.  */
2680static void
2681clean_dump_file (suffix)
2682  const char *suffix;
2683{
2684  char *dumpname;
2685
2686  dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
2687
2688  strcpy (dumpname, dump_base_name);
2689  strcat (dumpname, suffix);
2690
2691  rtl_dump_file = fopen (dumpname, "w");
2692
2693  if (rtl_dump_file == NULL)
2694    pfatal_with_name (dumpname);
2695
2696  free (dumpname);
2697
2698  fclose (rtl_dump_file);
2699  rtl_dump_file = NULL;
2700
2701  return;
2702}
2703
2704/* Do any final processing required for the declarations in VEC, of
2705   which there are LEN.  We write out inline functions and variables
2706   that have been deferred until this point, but which are required.
2707   Returns non-zero if anything was put out.  */
2708int
2709wrapup_global_declarations (vec, len)
2710     tree *vec;
2711     int len;
2712{
2713  tree decl;
2714  int i;
2715  int reconsider;
2716  int output_something = 0;
2717
2718  for (i = 0; i < len; i++)
2719    {
2720      decl = vec[i];
2721
2722      /* We're not deferring this any longer.  */
2723      DECL_DEFER_OUTPUT (decl) = 0;
2724
2725      if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
2726	  && incomplete_decl_finalize_hook != 0)
2727	(*incomplete_decl_finalize_hook) (decl);
2728    }
2729
2730  /* Now emit any global variables or functions that we have been
2731     putting off.  We need to loop in case one of the things emitted
2732     here references another one which comes earlier in the list.  */
2733  do
2734    {
2735      reconsider = 0;
2736      for (i = 0; i < len; i++)
2737	{
2738	  decl = vec[i];
2739
2740	  if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
2741	    continue;
2742
2743	  /* Don't write out static consts, unless we still need them.
2744
2745	     We also keep static consts if not optimizing (for debugging),
2746	     unless the user specified -fno-keep-static-consts.
2747	     ??? They might be better written into the debug information.
2748	     This is possible when using DWARF.
2749
2750	     A language processor that wants static constants to be always
2751	     written out (even if it is not used) is responsible for
2752	     calling rest_of_decl_compilation itself.  E.g. the C front-end
2753	     calls rest_of_decl_compilation from finish_decl.
2754	     One motivation for this is that is conventional in some
2755	     environments to write things like:
2756	     static const char rcsid[] = "... version string ...";
2757	     intending to force the string to be in the executable.
2758
2759	     A language processor that would prefer to have unneeded
2760	     static constants "optimized away" would just defer writing
2761	     them out until here.  E.g. C++ does this, because static
2762	     constants are often defined in header files.
2763
2764	     ??? A tempting alternative (for both C and C++) would be
2765	     to force a constant to be written if and only if it is
2766	     defined in a main file, as opposed to an include file.  */
2767
2768	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
2769	      && (! TREE_READONLY (decl)
2770		  || TREE_PUBLIC (decl)
2771		  || (!optimize && flag_keep_static_consts)
2772		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
2773	    {
2774	      reconsider = 1;
2775	      rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
2776	    }
2777
2778	  if (TREE_CODE (decl) == FUNCTION_DECL
2779	      && DECL_INITIAL (decl) != 0
2780	      && DECL_SAVED_INSNS (decl) != 0
2781	      && (flag_keep_inline_functions
2782		  || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
2783		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
2784	    {
2785	      reconsider = 1;
2786	      temporary_allocation ();
2787	      output_inline_function (decl);
2788	      permanent_allocation (1);
2789	    }
2790	}
2791
2792      if (reconsider)
2793	output_something = 1;
2794    }
2795  while (reconsider);
2796
2797  return output_something;
2798}
2799
2800/* Issue appropriate warnings for the global declarations in VEC (of
2801   which there are LEN).  Output debugging information for them.  */
2802void
2803check_global_declarations (vec, len)
2804     tree *vec;
2805     int len;
2806{
2807  tree decl;
2808  int i;
2809
2810  for (i = 0; i < len; i++)
2811    {
2812      decl = vec[i];
2813
2814      if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
2815	  && ! TREE_ASM_WRITTEN (decl))
2816	/* Cancel the RTL for this decl so that, if debugging info
2817	   output for global variables is still to come,
2818	   this one will be omitted.  */
2819	DECL_RTL (decl) = NULL;
2820
2821      /* Warn about any function
2822	 declared static but not defined.
2823	 We don't warn about variables,
2824	 because many programs have static variables
2825	 that exist only to get some text into the object file.  */
2826      if (TREE_CODE (decl) == FUNCTION_DECL
2827	  && (warn_unused
2828	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
2829	  && DECL_INITIAL (decl) == 0
2830	  && DECL_EXTERNAL (decl)
2831	  && ! DECL_ARTIFICIAL (decl)
2832	  && ! TREE_PUBLIC (decl))
2833	{
2834	  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
2835	    pedwarn_with_decl (decl,
2836			       "`%s' used but never defined");
2837	  else
2838	    warning_with_decl (decl,
2839			       "`%s' declared `static' but never defined");
2840	  /* This symbol is effectively an "extern" declaration now.  */
2841	  TREE_PUBLIC (decl) = 1;
2842	  assemble_external (decl);
2843	}
2844
2845      /* Warn about static fns or vars defined but not used,
2846	 but not about inline functions or static consts
2847	 since defining those in header files is normal practice.  */
2848      if (warn_unused
2849	  && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
2850	      || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
2851	  && ! DECL_IN_SYSTEM_HEADER (decl)
2852	  && ! DECL_EXTERNAL (decl)
2853	  && ! TREE_PUBLIC (decl)
2854	  && ! TREE_USED (decl)
2855	  && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl))
2856	  /* The TREE_USED bit for file-scope decls
2857	     is kept in the identifier, to handle multiple
2858	     external decls in different scopes.  */
2859	  && ! TREE_USED (DECL_NAME (decl)))
2860	warning_with_decl (decl, "`%s' defined but not used");
2861
2862#ifdef SDB_DEBUGGING_INFO
2863      /* The COFF linker can move initialized global vars to the end.
2864	 And that can screw up the symbol ordering.
2865	 By putting the symbols in that order to begin with,
2866	 we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
2867      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
2868	  && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
2869	  && ! DECL_EXTERNAL (decl)
2870	  && DECL_RTL (decl) != 0)
2871	TIMEVAR (symout_time, sdbout_symbol (decl, 0));
2872
2873      /* Output COFF information for non-global
2874	 file-scope initialized variables.  */
2875      if (write_symbols == SDB_DEBUG
2876	  && TREE_CODE (decl) == VAR_DECL
2877	  && DECL_INITIAL (decl)
2878	  && ! DECL_EXTERNAL (decl)
2879	  && DECL_RTL (decl) != 0
2880	  && GET_CODE (DECL_RTL (decl)) == MEM)
2881	TIMEVAR (symout_time, sdbout_toplevel_data (decl));
2882#endif /* SDB_DEBUGGING_INFO */
2883#ifdef DWARF_DEBUGGING_INFO
2884      /* Output DWARF information for file-scope tentative data object
2885	 declarations, file-scope (extern) function declarations (which
2886	 had no corresponding body) and file-scope tagged type declarations
2887	 and definitions which have not yet been forced out.  */
2888
2889      if (write_symbols == DWARF_DEBUG
2890	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
2891	TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
2892#endif
2893#ifdef DWARF2_DEBUGGING_INFO
2894      /* Output DWARF2 information for file-scope tentative data object
2895	 declarations, file-scope (extern) function declarations (which
2896	 had no corresponding body) and file-scope tagged type declarations
2897	 and definitions which have not yet been forced out.  */
2898
2899      if (write_symbols == DWARF2_DEBUG
2900	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
2901	TIMEVAR (symout_time, dwarf2out_decl (decl));
2902#endif
2903    }
2904}
2905
2906/* Compile an entire file of output from cpp, named NAME.
2907   Write a file of assembly output and various debugging dumps.  */
2908
2909static void
2910compile_file (name)
2911     char *name;
2912{
2913  tree globals;
2914  int start_time;
2915
2916  int name_specified = name != 0;
2917
2918  if (dump_base_name == 0)
2919    dump_base_name = name ? name : "gccdump";
2920
2921  parse_time = 0;
2922  varconst_time = 0;
2923  integration_time = 0;
2924  jump_time = 0;
2925  cse_time = 0;
2926  gcse_time = 0;
2927  loop_time = 0;
2928  cse2_time = 0;
2929  branch_prob_time = 0;
2930  flow_time = 0;
2931  combine_time = 0;
2932  regmove_time = 0;
2933  sched_time = 0;
2934  local_alloc_time = 0;
2935  global_alloc_time = 0;
2936  flow2_time = 0;
2937  sched2_time = 0;
2938#ifdef DELAY_SLOTS
2939  dbr_sched_time = 0;
2940#endif
2941  shorten_branch_time = 0;
2942  stack_reg_time = 0;
2943  final_time = 0;
2944  symout_time = 0;
2945  dump_time = 0;
2946
2947  /* Initialize data in various passes.  */
2948
2949  init_obstacks ();
2950  init_tree_codes ();
2951  name = init_parse (name);
2952  init_rtl ();
2953  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
2954		  || debug_info_level == DINFO_LEVEL_VERBOSE
2955		  || flag_test_coverage);
2956  init_regs ();
2957  init_decl_processing ();
2958  init_optabs ();
2959  init_stmt ();
2960  init_expmed ();
2961  init_expr_once ();
2962  init_loop ();
2963  init_reload ();
2964  init_alias_once ();
2965
2966  if (flag_caller_saves)
2967    init_caller_save ();
2968
2969  /* If auxiliary info generation is desired, open the output file.
2970     This goes in the same directory as the source file--unlike
2971     all the other output files.  */
2972  if (flag_gen_aux_info)
2973    {
2974      aux_info_file = fopen (aux_info_file_name, "w");
2975      if (aux_info_file == 0)
2976	pfatal_with_name (aux_info_file_name);
2977    }
2978
2979  /* Clear the dump files.  */
2980  if (rtl_dump)
2981    clean_dump_file (".rtl");
2982  if (jump_opt_dump)
2983    {
2984      clean_dump_file (".jump");
2985      if (graph_dump_format != no_graph)
2986	clean_graph_dump_file (dump_base_name, ".jump");
2987    }
2988  if (addressof_dump)
2989    {
2990      clean_dump_file (".addressof");
2991      if (graph_dump_format != no_graph)
2992	clean_graph_dump_file (dump_base_name, ".addressof");
2993    }
2994  if (cse_dump)
2995    {
2996      clean_dump_file (".cse");
2997      if (graph_dump_format != no_graph)
2998	clean_graph_dump_file (dump_base_name, ".cse");
2999    }
3000  if (loop_dump)
3001    {
3002      clean_dump_file (".loop");
3003      if (graph_dump_format != no_graph)
3004	clean_graph_dump_file (dump_base_name, ".loop");
3005    }
3006  if (cse2_dump)
3007    {
3008      clean_dump_file (".cse2");
3009      if (graph_dump_format != no_graph)
3010	clean_graph_dump_file (dump_base_name, ".cse2");
3011    }
3012  if (branch_prob_dump)
3013    {
3014      clean_dump_file (".bp");
3015      if (graph_dump_format != no_graph)
3016	clean_graph_dump_file (dump_base_name, ".bp");
3017    }
3018  if (flow_dump)
3019    {
3020      clean_dump_file (".flow");
3021      if (graph_dump_format != no_graph)
3022	clean_graph_dump_file (dump_base_name, ".flow");
3023    }
3024  if (combine_dump)
3025    {
3026      clean_dump_file (".combine");
3027      if (graph_dump_format != no_graph)
3028	clean_graph_dump_file (dump_base_name, ".combine");
3029    }
3030  if (regmove_dump)
3031    {
3032      clean_dump_file (".regmove");
3033      if (graph_dump_format != no_graph)
3034	clean_graph_dump_file (dump_base_name, ".regmove");
3035    }
3036  if (sched_dump)
3037    {
3038      clean_dump_file (".sched");
3039      if (graph_dump_format != no_graph)
3040	clean_graph_dump_file (dump_base_name, ".sched");
3041    }
3042  if (local_reg_dump)
3043    {
3044      clean_dump_file (".lreg");
3045      if (graph_dump_format != no_graph)
3046	clean_graph_dump_file (dump_base_name, ".lreg");
3047    }
3048  if (global_reg_dump)
3049    {
3050      clean_dump_file (".greg");
3051      if (graph_dump_format != no_graph)
3052	clean_graph_dump_file (dump_base_name, ".greg");
3053    }
3054  if (flow2_dump)
3055    {
3056      clean_dump_file (".flow2");
3057      if (graph_dump_format != no_graph)
3058	clean_graph_dump_file (dump_base_name, ".flow2");
3059    }
3060  if (sched2_dump)
3061    {
3062      clean_dump_file (".sched2");
3063      if (graph_dump_format != no_graph)
3064	clean_graph_dump_file (dump_base_name, ".sched2");
3065    }
3066  if (jump2_opt_dump)
3067    {
3068      clean_dump_file (".jump2");
3069      if (graph_dump_format != no_graph)
3070	clean_graph_dump_file (dump_base_name, ".jump2");
3071    }
3072#ifdef DELAY_SLOTS
3073  if (dbr_sched_dump)
3074    {
3075      clean_dump_file (".dbr");
3076      if (graph_dump_format != no_graph)
3077	clean_graph_dump_file (dump_base_name, ".dbr");
3078    }
3079#endif
3080  if (gcse_dump)
3081    {
3082      clean_dump_file (".gcse");
3083      if (graph_dump_format != no_graph)
3084	clean_graph_dump_file (dump_base_name, ".gcse");
3085    }
3086#ifdef STACK_REGS
3087  if (stack_reg_dump)
3088    {
3089      clean_dump_file (".stack");
3090      if (graph_dump_format != no_graph)
3091	clean_graph_dump_file (dump_base_name, ".stack");
3092    }
3093#endif
3094#ifdef MACHINE_DEPENDENT_REORG
3095  if (mach_dep_reorg_dump)
3096    {
3097      clean_dump_file (".mach");
3098      if (graph_dump_format != no_graph)
3099	clean_graph_dump_file (dump_base_name, ".mach");
3100    }
3101#endif
3102
3103  /* Open assembler code output file.  */
3104
3105  if (flag_syntax_only)
3106    asm_out_file = NULL;
3107  else
3108    {
3109      if (! name_specified && asm_file_name == 0)
3110	asm_out_file = stdout;
3111      else
3112	{
3113	  int len = strlen (dump_base_name);
3114	  register char *dumpname = (char *) xmalloc (len + 6);
3115	  strcpy (dumpname, dump_base_name);
3116	  strip_off_ending (dumpname, len);
3117	  strcat (dumpname, ".s");
3118	  if (asm_file_name == 0)
3119	    {
3120	      asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
3121	      strcpy (asm_file_name, dumpname);
3122	    }
3123	  if (!strcmp (asm_file_name, "-"))
3124	    asm_out_file = stdout;
3125	  else
3126	    asm_out_file = fopen (asm_file_name, "w");
3127	  if (asm_out_file == 0)
3128	    pfatal_with_name (asm_file_name);
3129	}
3130
3131#ifdef IO_BUFFER_SIZE
3132      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
3133	       _IOFBF, IO_BUFFER_SIZE);
3134#endif
3135    }
3136
3137  input_filename = name;
3138
3139  /* Put an entry on the input file stack for the main input file.  */
3140  input_file_stack
3141    = (struct file_stack *) xmalloc (sizeof (struct file_stack));
3142  input_file_stack->next = 0;
3143  input_file_stack->name = input_filename;
3144
3145  /* Perform language-specific initialization.
3146     This may set main_input_filename.  */
3147  lang_init ();
3148
3149  /* If the input doesn't start with a #line, use the input name
3150     as the official input file name.  */
3151  if (main_input_filename == 0)
3152    main_input_filename = name;
3153
3154  if (flag_syntax_only)
3155    {
3156      write_symbols = NO_DEBUG;
3157      profile_flag = 0;
3158      profile_block_flag = 0;
3159    }
3160  else
3161    {
3162      ASM_FILE_START (asm_out_file);
3163
3164#ifdef ASM_COMMENT_START
3165      if (flag_verbose_asm)
3166	{
3167	  /* Print the list of options in effect.  */
3168	  print_version (asm_out_file, ASM_COMMENT_START);
3169	  print_switch_values (asm_out_file, 0, MAX_LINE,
3170			       ASM_COMMENT_START, " ", "\n");
3171	  /* Add a blank line here so it appears in assembler output but not
3172	     screen output.  */
3173	  fprintf (asm_out_file, "\n");
3174	}
3175#endif
3176
3177      /* Output something to inform GDB that this compilation was by GCC.  */
3178#ifndef ASM_IDENTIFY_GCC
3179      fprintf (asm_out_file, "gcc2_compiled.:\n");
3180#else
3181      ASM_IDENTIFY_GCC (asm_out_file);
3182#endif
3183
3184  /* Output something to identify which front-end produced this file.  */
3185#ifdef ASM_IDENTIFY_LANGUAGE
3186      ASM_IDENTIFY_LANGUAGE (asm_out_file);
3187#endif
3188    } /* ! flag_syntax_only */
3189
3190#ifndef ASM_OUTPUT_SECTION_NAME
3191  if (flag_function_sections)
3192    {
3193      warning ("-ffunction-sections not supported for this target.");
3194      flag_function_sections = 0;
3195    }
3196  if (flag_data_sections)
3197    {
3198      warning ("-fdata-sections not supported for this target.");
3199      flag_data_sections = 0;
3200    }
3201#endif
3202
3203  if (flag_function_sections
3204      && (profile_flag || profile_block_flag))
3205    {
3206      warning ("-ffunction-sections disabled; it makes profiling impossible.");
3207      flag_function_sections = 0;
3208    }
3209
3210#ifndef OBJECT_FORMAT_ELF
3211  if (flag_function_sections && write_symbols != NO_DEBUG)
3212    warning ("-ffunction-sections may affect debugging on some targets.");
3213#endif
3214
3215  /* ??? Note: There used to be a conditional here
3216      to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
3217      This was to guarantee separation between gcc_compiled. and
3218      the first function, for the sake of dbx on Suns.
3219      However, having the extra zero here confused the Emacs
3220      code for unexec, and might confuse other programs too.
3221      Therefore, I took out that change.
3222      In future versions we should find another way to solve
3223      that dbx problem.  -- rms, 23 May 93.  */
3224
3225  /* Don't let the first function fall at the same address
3226     as gcc_compiled., if profiling.  */
3227  if (profile_flag || profile_block_flag)
3228    {
3229      /* It's best if we can write a nop here since some
3230	 assemblers don't tolerate zeros in the text section.  */
3231      if (insn_template[CODE_FOR_nop] != 0)
3232	output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
3233      else
3234	assemble_zeros (UNITS_PER_WORD);
3235    }
3236
3237  /* If dbx symbol table desired, initialize writing it
3238     and output the predefined types.  */
3239#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
3240  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
3241    TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
3242				       getdecls ()));
3243#endif
3244#ifdef SDB_DEBUGGING_INFO
3245  if (write_symbols == SDB_DEBUG)
3246    TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
3247				       getdecls ()));
3248#endif
3249#ifdef DWARF_DEBUGGING_INFO
3250  if (write_symbols == DWARF_DEBUG)
3251    TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
3252#endif
3253#ifdef DWARF2_UNWIND_INFO
3254  if (dwarf2out_do_frame ())
3255    dwarf2out_frame_init ();
3256#endif
3257#ifdef DWARF2_DEBUGGING_INFO
3258  if (write_symbols == DWARF2_DEBUG)
3259    TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
3260#endif
3261
3262  /* Initialize yet another pass.  */
3263
3264  init_final (main_input_filename);
3265  init_branch_prob (dump_base_name);
3266
3267  start_time = get_run_time ();
3268
3269  /* Call the parser, which parses the entire file
3270     (calling rest_of_compilation for each function).  */
3271
3272  if (yyparse () != 0)
3273    {
3274      if (errorcount == 0)
3275	notice ("Errors detected in input file (your bison.simple is out of date)\n");
3276
3277      /* In case there were missing closebraces,
3278	 get us back to the global binding level.  */
3279      while (! global_bindings_p ())
3280	poplevel (0, 0, 0);
3281    }
3282
3283  /* Compilation is now finished except for writing
3284     what's left of the symbol table output.  */
3285
3286  parse_time += get_run_time () - start_time;
3287
3288  parse_time -= integration_time;
3289  parse_time -= varconst_time;
3290
3291  if (flag_syntax_only)
3292    goto finish_syntax;
3293
3294  globals = getdecls ();
3295
3296  /* Really define vars that have had only a tentative definition.
3297     Really output inline functions that must actually be callable
3298     and have not been output so far.  */
3299
3300  {
3301    int len = list_length (globals);
3302    tree *vec = (tree *) alloca (sizeof (tree) * len);
3303    int i;
3304    tree decl;
3305
3306    /* Process the decls in reverse order--earliest first.
3307       Put them into VEC from back to front, then take out from front.  */
3308
3309    for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
3310      vec[len - i - 1] = decl;
3311
3312    wrapup_global_declarations (vec, len);
3313
3314    /* This must occur after the loop to output deferred functions.  Else
3315       the profiler initializer would not be emitted if all the functions
3316       in this compilation unit were deferred.
3317
3318       output_func_start_profiler can not cause any additional functions or
3319       data to need to be output, so it need not be in the deferred function
3320       loop above.  */
3321    output_func_start_profiler ();
3322
3323    /* Now that all possible functions have been output, we can dump
3324       the exception table.  */
3325
3326    output_exception_table ();
3327
3328    check_global_declarations (vec, len);
3329  }
3330
3331  /* Write out any pending weak symbol declarations.  */
3332
3333  weak_finish ();
3334
3335  /* Do dbx symbols */
3336#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
3337  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
3338    TIMEVAR (symout_time,
3339	     {
3340	       dbxout_finish (asm_out_file, main_input_filename);
3341	     });
3342#endif
3343
3344#ifdef DWARF_DEBUGGING_INFO
3345  if (write_symbols == DWARF_DEBUG)
3346    TIMEVAR (symout_time,
3347	     {
3348	       dwarfout_finish ();
3349	     });
3350#endif
3351
3352#ifdef DWARF2_UNWIND_INFO
3353  if (dwarf2out_do_frame ())
3354    dwarf2out_frame_finish ();
3355#endif
3356
3357#ifdef DWARF2_DEBUGGING_INFO
3358  if (write_symbols == DWARF2_DEBUG)
3359    TIMEVAR (symout_time,
3360	     {
3361	       dwarf2out_finish ();
3362	     });
3363#endif
3364
3365  /* Output some stuff at end of file if nec.  */
3366
3367  end_final (dump_base_name);
3368
3369  if (branch_prob_dump)
3370    open_dump_file (".bp", NULL);
3371
3372  TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
3373
3374  if (branch_prob_dump)
3375    close_dump_file (NULL, NULL_RTX);
3376
3377#ifdef ASM_FILE_END
3378  ASM_FILE_END (asm_out_file);
3379#endif
3380
3381
3382  /* Language-specific end of compilation actions.  */
3383 finish_syntax:
3384  lang_finish ();
3385
3386  /* Close the dump files.  */
3387
3388  if (flag_gen_aux_info)
3389    {
3390      fclose (aux_info_file);
3391      if (errorcount)
3392	unlink (aux_info_file_name);
3393    }
3394
3395  if (combine_dump)
3396    {
3397      open_dump_file (".combine", NULL);
3398      TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
3399      close_dump_file (NULL, NULL_RTX);
3400    }
3401
3402  /* Close non-debugging input and output files.  Take special care to note
3403     whether fclose returns an error, since the pages might still be on the
3404     buffer chain while the file is open.  */
3405
3406  finish_parse ();
3407
3408  if (! flag_syntax_only
3409      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
3410    fatal_io_error (asm_file_name);
3411
3412  /* Do whatever is necessary to finish printing the graphs.  */
3413  if (graph_dump_format != no_graph)
3414    {
3415      if (jump_opt_dump)
3416	finish_graph_dump_file (dump_base_name, ".jump");
3417      if (addressof_dump)
3418	finish_graph_dump_file (dump_base_name, ".addressof");
3419      if (cse_dump)
3420	finish_graph_dump_file (dump_base_name, ".cse");
3421      if (loop_dump)
3422	finish_graph_dump_file (dump_base_name, ".loop");
3423      if (cse2_dump)
3424	finish_graph_dump_file (dump_base_name, ".cse2");
3425      if (branch_prob_dump)
3426	finish_graph_dump_file (dump_base_name, ".bp");
3427      if (flow_dump)
3428	finish_graph_dump_file (dump_base_name, ".flow");
3429      if (combine_dump)
3430	finish_graph_dump_file (dump_base_name, ".combine");
3431      if (regmove_dump)
3432	finish_graph_dump_file (dump_base_name, ".regmove");
3433      if (sched_dump)
3434	finish_graph_dump_file (dump_base_name, ".sched");
3435      if (local_reg_dump)
3436	finish_graph_dump_file (dump_base_name, ".lreg");
3437      if (global_reg_dump)
3438	finish_graph_dump_file (dump_base_name, ".greg");
3439      if (flow2_dump)
3440	finish_graph_dump_file (dump_base_name, ".flow2");
3441      if (sched2_dump)
3442	finish_graph_dump_file (dump_base_name, ".sched2");
3443      if (jump2_opt_dump)
3444	finish_graph_dump_file (dump_base_name, ".jump2");
3445#ifdef DELAY_SLOTS
3446      if (dbr_sched_dump)
3447	finish_graph_dump_file (dump_base_name, ".dbr");
3448#endif
3449      if (gcse_dump)
3450	finish_graph_dump_file (dump_base_name, ".gcse");
3451#ifdef STACK_REGS
3452      if (stack_reg_dump)
3453	finish_graph_dump_file (dump_base_name, ".stack");
3454#endif
3455#ifdef MACHINE_DEPENDENT_REORG
3456      if (mach_dep_reorg_dump)
3457	finish_graph_dump_file (dump_base_name, ".mach");
3458#endif
3459    }
3460
3461  /* Free up memory for the benefit of leak detectors.  */
3462  free_reg_info ();
3463
3464  /* Print the times.  */
3465
3466  if (! quiet_flag)
3467    {
3468      fprintf (stderr,"\n");
3469      print_time ("parse", parse_time);
3470
3471      print_time ("integration", integration_time);
3472      print_time ("jump", jump_time);
3473      print_time ("cse", cse_time);
3474      print_time ("gcse", gcse_time);
3475      print_time ("loop", loop_time);
3476      print_time ("cse2", cse2_time);
3477      print_time ("branch-prob", branch_prob_time);
3478      print_time ("flow", flow_time);
3479      print_time ("combine", combine_time);
3480      print_time ("regmove", regmove_time);
3481      print_time ("sched", sched_time);
3482      print_time ("local-alloc", local_alloc_time);
3483      print_time ("global-alloc", global_alloc_time);
3484      print_time ("flow2", flow2_time);
3485      print_time ("sched2", sched2_time);
3486#ifdef DELAY_SLOTS
3487      print_time ("dbranch", dbr_sched_time);
3488#endif
3489      print_time ("shorten-branch", shorten_branch_time);
3490      print_time ("stack-reg", stack_reg_time);
3491      print_time ("final", final_time);
3492      print_time ("varconst", varconst_time);
3493      print_time ("symout", symout_time);
3494      print_time ("dump", dump_time);
3495    }
3496}
3497
3498/* This is called from various places for FUNCTION_DECL, VAR_DECL,
3499   and TYPE_DECL nodes.
3500
3501   This does nothing for local (non-static) variables.
3502   Otherwise, it sets up the RTL and outputs any assembler code
3503   (label definition, storage allocation and initialization).
3504
3505   DECL is the declaration.  If ASMSPEC is nonzero, it specifies
3506   the assembler symbol name to be used.  TOP_LEVEL is nonzero
3507   if this declaration is not within a function.  */
3508
3509void
3510rest_of_decl_compilation (decl, asmspec, top_level, at_end)
3511     tree decl;
3512     const char *asmspec;
3513     int top_level;
3514     int at_end;
3515{
3516  /* Declarations of variables, and of functions defined elsewhere.  */
3517
3518/* The most obvious approach, to put an #ifndef around where
3519   this macro is used, doesn't work since it's inside a macro call.  */
3520#ifndef ASM_FINISH_DECLARE_OBJECT
3521#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
3522#endif
3523
3524  /* Forward declarations for nested functions are not "external",
3525     but we need to treat them as if they were.  */
3526  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
3527      || TREE_CODE (decl) == FUNCTION_DECL)
3528    TIMEVAR (varconst_time,
3529	     {
3530	       make_decl_rtl (decl, asmspec, top_level);
3531	       /* Initialized extern variable exists to be replaced
3532		  with its value, or represents something that will be
3533		  output in another file.  */
3534	       if (! (TREE_CODE (decl) == VAR_DECL
3535		      && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
3536		      && DECL_INITIAL (decl) != 0
3537		      && DECL_INITIAL (decl) != error_mark_node))
3538		 /* Don't output anything
3539		    when a tentative file-scope definition is seen.
3540		    But at end of compilation, do output code for them.  */
3541		 if (! (! at_end && top_level
3542			&& (DECL_INITIAL (decl) == 0
3543			    || DECL_INITIAL (decl) == error_mark_node)))
3544		   assemble_variable (decl, top_level, at_end, 0);
3545	       if (decl == last_assemble_variable_decl)
3546		 {
3547		   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
3548					      top_level, at_end);
3549		 }
3550	     });
3551  else if (DECL_REGISTER (decl) && asmspec != 0)
3552    {
3553      if (decode_reg_name (asmspec) >= 0)
3554	{
3555	  DECL_RTL (decl) = 0;
3556	  make_decl_rtl (decl, asmspec, top_level);
3557	}
3558      else
3559	error ("invalid register name `%s' for register variable", asmspec);
3560    }
3561#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
3562  else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
3563	   && TREE_CODE (decl) == TYPE_DECL)
3564    TIMEVAR (symout_time, dbxout_symbol (decl, 0));
3565#endif
3566#ifdef SDB_DEBUGGING_INFO
3567  else if (write_symbols == SDB_DEBUG && top_level
3568	   && TREE_CODE (decl) == TYPE_DECL)
3569    TIMEVAR (symout_time, sdbout_symbol (decl, 0));
3570#endif
3571}
3572
3573/* Called after finishing a record, union or enumeral type.  */
3574
3575void
3576rest_of_type_compilation (type, toplev)
3577#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
3578     tree type;
3579     int toplev;
3580#else
3581     tree type ATTRIBUTE_UNUSED;
3582     int toplev ATTRIBUTE_UNUSED;
3583#endif
3584{
3585#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
3586  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
3587    TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
3588#endif
3589#ifdef SDB_DEBUGGING_INFO
3590  if (write_symbols == SDB_DEBUG)
3591    TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
3592#endif
3593}
3594
3595/* This is called from finish_function (within yyparse)
3596   after each top-level definition is parsed.
3597   It is supposed to compile that function or variable
3598   and output the assembler code for it.
3599   After we return, the tree storage is freed.  */
3600
3601void
3602rest_of_compilation (decl)
3603     tree decl;
3604{
3605  register rtx insns;
3606  int start_time = get_run_time ();
3607  int tem;
3608  /* Nonzero if we have saved the original DECL_INITIAL of the function,
3609     to be restored after we finish compiling the function
3610     (for use when compiling inline calls to this function).  */
3611  tree saved_block_tree = 0;
3612  /* Likewise, for DECL_ARGUMENTS.  */
3613  tree saved_arguments = 0;
3614  int failure = 0;
3615  int rebuild_label_notes_after_reload;
3616
3617  /* If we are reconsidering an inline function
3618     at the end of compilation, skip the stuff for making it inline.  */
3619
3620  if (DECL_SAVED_INSNS (decl) == 0)
3621    {
3622      int inlinable = 0;
3623      const char *lose;
3624
3625      /* If requested, consider whether to make this function inline.  */
3626      if (DECL_INLINE (decl) || flag_inline_functions)
3627	TIMEVAR (integration_time,
3628		 {
3629		   lose = function_cannot_inline_p (decl);
3630		   if (lose || ! optimize)
3631		     {
3632		       if (warn_inline && DECL_INLINE (decl))
3633			 warning_with_decl (decl, lose);
3634		       DECL_ABSTRACT_ORIGIN (decl) = 0;
3635		       /* Don't really compile an extern inline function.
3636			  If we can't make it inline, pretend
3637			  it was only declared.  */
3638		       if (DECL_EXTERNAL (decl))
3639			 {
3640			   DECL_INITIAL (decl) = 0;
3641			   goto exit_rest_of_compilation;
3642			 }
3643		     }
3644		   else
3645		     /* ??? Note that this has the effect of making it look
3646			like "inline" was specified for a function if we choose
3647			to inline it.  This isn't quite right, but it's
3648			probably not worth the trouble to fix.  */
3649		     inlinable = DECL_INLINE (decl) = 1;
3650		 });
3651
3652      insns = get_insns ();
3653
3654      /* Dump the rtl code if we are dumping rtl.  */
3655
3656      if (rtl_dump)
3657	{
3658	  open_dump_file (".rtl", decl_printable_name (decl, 2));
3659
3660	  if (DECL_SAVED_INSNS (decl))
3661	    fprintf (rtl_dump_file, ";; (integrable)\n\n");
3662
3663	  close_dump_file (print_rtl, insns);
3664	}
3665
3666      /* If we can, defer compiling inlines until EOF.
3667	 save_for_inline_copying can be extremely expensive.  */
3668      if (inlinable && ! decl_function_context (decl))
3669	DECL_DEFER_OUTPUT (decl) = 1;
3670
3671      /* If function is inline, and we don't yet know whether to
3672	 compile it by itself, defer decision till end of compilation.
3673	 finish_compilation will call rest_of_compilation again
3674	 for those functions that need to be output.  Also defer those
3675	 functions that we are supposed to defer.  We cannot defer
3676	 functions containing nested functions since the nested function
3677	 data is in our non-saved obstack.  We cannot defer nested
3678	 functions for the same reason.  */
3679
3680      /* If this is a nested inline, remove ADDRESSOF now so we can
3681	 finish compiling ourselves.  Otherwise, wait until EOF.
3682	 We have to do this because the purge_addressof transformation
3683	 changes the DECL_RTL for many variables, which confuses integrate.  */
3684      if (inlinable)
3685	{
3686	  if (decl_function_context (decl))
3687	    purge_addressof (insns);
3688	  else
3689	    DECL_DEFER_OUTPUT (decl) = 1;
3690	}
3691
3692      if (! current_function_contains_functions
3693	  && (DECL_DEFER_OUTPUT (decl)
3694	      || (DECL_INLINE (decl)
3695		  && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
3696		       && ! flag_keep_inline_functions)
3697		      || DECL_EXTERNAL (decl)))))
3698	{
3699	  DECL_DEFER_OUTPUT (decl) = 1;
3700
3701	  /* If -Wreturn-type, we have to do a bit of compilation.
3702	     However, if we just fall through we will call
3703	     save_for_inline_copying() which results in excessive
3704	     memory use.  Instead, we just want to call
3705	     jump_optimize() to figure out whether or not we can fall
3706	     off the end of the function; we do the minimum amount of
3707	     work necessary to make that safe.  And, we set optimize
3708	     to zero to keep jump_optimize from working too hard.  */
3709	  if (warn_return_type)
3710	    {
3711	      int saved_optimize = optimize;
3712	      optimize = 0;
3713	      find_exception_handler_labels ();
3714	      jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
3715			     !JUMP_AFTER_REGSCAN);
3716	      optimize = saved_optimize;
3717	    }
3718
3719#ifdef DWARF_DEBUGGING_INFO
3720	  /* Generate the DWARF info for the "abstract" instance
3721	     of a function which we may later generate inlined and/or
3722	     out-of-line instances of.  */
3723	  if (write_symbols == DWARF_DEBUG)
3724	    {
3725	      set_decl_abstract_flags (decl, 1);
3726	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
3727	      set_decl_abstract_flags (decl, 0);
3728	    }
3729#endif
3730#ifdef DWARF2_DEBUGGING_INFO
3731	  /* Generate the DWARF2 info for the "abstract" instance
3732	     of a function which we may later generate inlined and/or
3733	     out-of-line instances of.  */
3734	  if (write_symbols == DWARF2_DEBUG)
3735	    {
3736	      set_decl_abstract_flags (decl, 1);
3737	      TIMEVAR (symout_time, dwarf2out_decl (decl));
3738	      set_decl_abstract_flags (decl, 0);
3739	    }
3740#endif
3741	  TIMEVAR (integration_time, save_for_inline_nocopy (decl));
3742	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
3743	  goto exit_rest_of_compilation;
3744	}
3745
3746      /* If we have to compile the function now, save its rtl and subdecls
3747	 so that its compilation will not affect what others get.  */
3748      if (inlinable || DECL_DEFER_OUTPUT (decl))
3749	{
3750#ifdef DWARF_DEBUGGING_INFO
3751	  /* Generate the DWARF info for the "abstract" instance of
3752	     a function which we will generate an out-of-line instance
3753	     of almost immediately (and which we may also later generate
3754	     various inlined instances of).  */
3755	  if (write_symbols == DWARF_DEBUG)
3756	    {
3757	      set_decl_abstract_flags (decl, 1);
3758	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
3759	      set_decl_abstract_flags (decl, 0);
3760	    }
3761#endif
3762#ifdef DWARF2_DEBUGGING_INFO
3763	  /* Generate the DWARF2 info for the "abstract" instance of
3764	     a function which we will generate an out-of-line instance
3765	     of almost immediately (and which we may also later generate
3766	     various inlined instances of).  */
3767	  if (write_symbols == DWARF2_DEBUG)
3768	    {
3769	      set_decl_abstract_flags (decl, 1);
3770	      TIMEVAR (symout_time, dwarf2out_decl (decl));
3771	      set_decl_abstract_flags (decl, 0);
3772	    }
3773#endif
3774	  saved_block_tree = DECL_INITIAL (decl);
3775	  saved_arguments = DECL_ARGUMENTS (decl);
3776	  TIMEVAR (integration_time, save_for_inline_copying (decl));
3777	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
3778	}
3779
3780      /* If specified extern inline but we aren't inlining it, we are
3781	 done.  This goes for anything that gets here with DECL_EXTERNAL
3782	 set, not just things with DECL_INLINE.  */
3783      if (DECL_EXTERNAL (decl))
3784	goto exit_rest_of_compilation;
3785    }
3786
3787  if (! DECL_DEFER_OUTPUT (decl))
3788    TREE_ASM_WRITTEN (decl) = 1;
3789
3790  /* Now that integrate will no longer see our rtl, we need not distinguish
3791     between the return value of this function and the return value of called
3792     functions.  */
3793  rtx_equal_function_value_matters = 0;
3794
3795  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
3796  if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
3797    {
3798      goto exit_rest_of_compilation;
3799    }
3800
3801  /* Emit code to get eh context, if needed. */
3802  emit_eh_context ();
3803
3804#ifdef FINALIZE_PIC
3805  /* If we are doing position-independent code generation, now
3806     is the time to output special prologues and epilogues.
3807     We do not want to do this earlier, because it just clutters
3808     up inline functions with meaningless insns.  */
3809  if (flag_pic)
3810    FINALIZE_PIC;
3811#endif
3812
3813  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
3814     Note that that may have been done above, in save_for_inline_copying.
3815     The call to resume_temporary_allocation near the end of this function
3816     goes back to the usual state of affairs.  This must be done after
3817     we've built up any unwinders for exception handling, and done
3818     the FINALIZE_PIC work, if necessary.  */
3819
3820  rtl_in_current_obstack ();
3821
3822  insns = get_insns ();
3823
3824  /* Copy any shared structure that should not be shared.  */
3825
3826  unshare_all_rtl (insns);
3827
3828#ifdef SETJMP_VIA_SAVE_AREA
3829  /* This must be performed before virutal register instantiation.  */
3830  if (current_function_calls_alloca)
3831    optimize_save_area_alloca (insns);
3832#endif
3833
3834  /* Instantiate all virtual registers.  */
3835
3836  instantiate_virtual_regs (current_function_decl, get_insns ());
3837
3838  /* See if we have allocated stack slots that are not directly addressable.
3839     If so, scan all the insns and create explicit address computation
3840     for all references to such slots.  */
3841/*   fixup_stack_slots (); */
3842
3843  /* Find all the EH handlers.  */
3844  find_exception_handler_labels ();
3845
3846  /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
3847     are initialized and to compute whether control can drop off the end
3848     of the function.  */
3849  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
3850  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
3851				     JUMP_AFTER_REGSCAN));
3852
3853  /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
3854  if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
3855    goto exit_rest_of_compilation;
3856
3857  /* Dump rtl code after jump, if we are doing that.  */
3858
3859    if (jump_opt_dump)
3860      dump_rtl (".jump", decl, print_rtl, insns);
3861
3862  /* Perform common subexpression elimination.
3863     Nonzero value from `cse_main' means that jumps were simplified
3864     and some code may now be unreachable, so do
3865     jump optimization again.  */
3866
3867  if (optimize > 0)
3868    {
3869      if (cse_dump)
3870	open_dump_file (".cse", decl_printable_name (decl, 2));
3871
3872      TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
3873
3874      if (flag_thread_jumps)
3875	/* Hacks by tiemann & kenner.  */
3876	TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
3877
3878      TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
3879					 0, rtl_dump_file));
3880      if (tem || optimize > 1)
3881	TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
3882					   !JUMP_NOOP_MOVES,
3883					   !JUMP_AFTER_REGSCAN));
3884
3885      /* Run this after jump optmizations remove all the unreachable code
3886	 so that unreachable code will not keep values live.  */
3887      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
3888
3889      /* Dump rtl code after cse, if we are doing that.  */
3890
3891      if (cse_dump)
3892	{
3893	  close_dump_file (print_rtl, insns);
3894	  if (graph_dump_format != no_graph)
3895	    print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
3896	}
3897    }
3898
3899  purge_addressof (insns);
3900  reg_scan (insns, max_reg_num (), 1);
3901
3902  if (addressof_dump)
3903    {
3904      dump_rtl (".addressof", decl, print_rtl, insns);
3905      if (graph_dump_format != no_graph)
3906	print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
3907    }
3908
3909  /* Perform global cse.  */
3910
3911  if (optimize > 0 && flag_gcse)
3912    {
3913      if (gcse_dump)
3914	open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
3915
3916      TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
3917
3918      /* If gcse altered any jumps, rerun jump optimizations to clean
3919	 things up.  */
3920      if (tem)
3921	{
3922	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
3923					     !JUMP_NOOP_MOVES,
3924					     !JUMP_AFTER_REGSCAN));
3925        }
3926
3927      if (gcse_dump)
3928	{
3929	  close_dump_file (print_rtl, insns);
3930	  if (graph_dump_format != no_graph)
3931	    print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
3932	}
3933    }
3934  /* Move constant computations out of loops.  */
3935
3936  if (optimize > 0)
3937    {
3938      if (loop_dump)
3939	open_dump_file (".loop", decl_printable_name (decl, 2));
3940
3941      TIMEVAR
3942	(loop_time,
3943	 {
3944	   if (flag_rerun_loop_opt)
3945	     {
3946	       /* We only want to perform unrolling once.  */
3947
3948	       loop_optimize (insns, rtl_dump_file, 0, 0);
3949
3950
3951	       /* The first call to loop_optimize makes some instructions
3952		  trivially dead.  We delete those instructions now in the
3953		  hope that doing so will make the heuristics in loop work
3954		  better and possibly speed up compilation.  */
3955	       delete_trivially_dead_insns (insns, max_reg_num ());
3956
3957	       /* The regscan pass is currently necessary as the alias
3958		  analysis code depends on this information.  */
3959	       reg_scan (insns, max_reg_num (), 1);
3960	     }
3961	   loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
3962	 });
3963
3964      /* Dump rtl code after loop opt, if we are doing that.  */
3965
3966      if (loop_dump)
3967	{
3968	  close_dump_file (print_rtl, insns);
3969	  if (graph_dump_format != no_graph)
3970	    print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
3971	}
3972    }
3973
3974  if (optimize > 0)
3975    {
3976      if (cse2_dump)
3977	open_dump_file (".cse2", decl_printable_name (decl, 2));
3978
3979      if (flag_rerun_cse_after_loop)
3980	{
3981	  /* Running another jump optimization pass before the second
3982	     cse pass sometimes simplifies the RTL enough to allow
3983	     the second CSE pass to do a better job.  Jump_optimize can change
3984	     max_reg_num so we must rerun reg_scan afterwards.
3985	     ??? Rework to not call reg_scan so often.  */
3986	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
3987	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
3988					     !JUMP_NOOP_MOVES,
3989					     JUMP_AFTER_REGSCAN));
3990
3991	  TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
3992	  TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
3993					      1, rtl_dump_file));
3994	  if (tem)
3995	    TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
3996					       !JUMP_NOOP_MOVES,
3997					       !JUMP_AFTER_REGSCAN));
3998	}
3999
4000      if (flag_thread_jumps)
4001	{
4002	  /* This pass of jump threading straightens out code
4003	     that was kinked by loop optimization.  */
4004	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
4005	  TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
4006	}
4007
4008      /* Dump rtl code after cse, if we are doing that.  */
4009
4010      if (cse2_dump)
4011	{
4012	  close_dump_file (print_rtl, insns);
4013	  if (graph_dump_format != no_graph)
4014	    print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
4015	}
4016    }
4017
4018  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
4019    {
4020      if (branch_prob_dump)
4021	open_dump_file (".bp", decl_printable_name (decl, 2));
4022
4023      TIMEVAR
4024	(branch_prob_time,
4025	 {
4026	   branch_prob (insns, rtl_dump_file);
4027	 });
4028
4029      if (branch_prob_dump)
4030	{
4031	  close_dump_file (print_rtl, insns);
4032	  if (graph_dump_format != no_graph)
4033	    print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
4034	}
4035    }
4036
4037  /* We are no longer anticipating cse in this function, at least.  */
4038
4039  cse_not_expected = 1;
4040
4041  /* Now we choose between stupid (pcc-like) register allocation
4042     (if we got the -noreg switch and not -opt)
4043     and smart register allocation.  */
4044
4045  if (optimize > 0)		/* Stupid allocation probably won't work */
4046    obey_regdecls = 0;		/* if optimizations being done.  */
4047
4048  regclass_init ();
4049
4050  /* Print function header into flow dump now
4051     because doing the flow analysis makes some of the dump.  */
4052
4053  if (flow_dump)
4054    open_dump_file (".flow", decl_printable_name (decl, 2));
4055
4056  if (obey_regdecls)
4057    {
4058      TIMEVAR (flow_time,
4059	       {
4060		 regclass (insns, max_reg_num ());
4061		 stupid_life_analysis (insns, max_reg_num (),
4062				       rtl_dump_file);
4063	       });
4064    }
4065  else
4066    {
4067      /* Do control and data flow analysis,
4068	 and write some of the results to dump file.  */
4069
4070      TIMEVAR
4071	(flow_time,
4072	 {
4073	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
4074	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
4075	 });
4076
4077      if (warn_uninitialized)
4078	{
4079	  uninitialized_vars_warning (DECL_INITIAL (decl));
4080	  setjmp_args_warning ();
4081	}
4082    }
4083
4084  /* Dump rtl after flow analysis.  */
4085
4086  if (flow_dump)
4087    {
4088      close_dump_file (print_rtl_with_bb, insns);
4089      if (graph_dump_format != no_graph)
4090	print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
4091    }
4092
4093  /* The first life analysis pass has finished.  From now on we can not
4094     generate any new pseudos.  */
4095  no_new_pseudos = 1;
4096
4097  /* If -opt, try combining insns through substitution.  */
4098
4099  if (optimize > 0)
4100    {
4101      TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
4102
4103      /* Dump rtl code after insn combination.  */
4104
4105      if (combine_dump)
4106	{
4107	  dump_rtl (".combine", decl, print_rtl_with_bb, insns);
4108	  if (graph_dump_format != no_graph)
4109	    print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
4110	}
4111    }
4112
4113  /* Register allocation pre-pass, to reduce number of moves
4114     necessary for two-address machines.  */
4115  if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
4116    {
4117      if (regmove_dump)
4118	open_dump_file (".regmove", decl_printable_name (decl, 2));
4119
4120      TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
4121					       rtl_dump_file));
4122
4123      if (regmove_dump)
4124	{
4125	  close_dump_file (print_rtl_with_bb, insns);
4126	  if (graph_dump_format != no_graph)
4127	    print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
4128	}
4129    }
4130
4131  /* Print function header into sched dump now
4132     because doing the sched analysis makes some of the dump.  */
4133
4134  if (optimize > 0 && flag_schedule_insns)
4135    {
4136      if (sched_dump)
4137	open_dump_file (".sched", decl_printable_name (decl, 2));
4138
4139      /* Do control and data sched analysis,
4140	 and write some of the results to dump file.  */
4141
4142      TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
4143
4144      /* Dump rtl after instruction scheduling.  */
4145
4146      if (sched_dump)
4147	{
4148	  close_dump_file (print_rtl_with_bb, insns);
4149	  if (graph_dump_format != no_graph)
4150	    print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
4151	}
4152    }
4153
4154  /* Determine if the current function is a leaf before running reload
4155     since this can impact optimizations done by the prologue and
4156     epilogue thus changing register elimination offsets.  */
4157  current_function_is_leaf = leaf_function_p ();
4158
4159  /* Unless we did stupid register allocation,
4160     allocate pseudo-regs that are used only within 1 basic block.
4161
4162     RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
4163     jump optimizer after register allocation and reloading are finished.  */
4164
4165  if (!obey_regdecls)
4166    TIMEVAR (local_alloc_time,
4167	     {
4168	       recompute_reg_usage (insns, ! optimize_size);
4169	       regclass (insns, max_reg_num ());
4170	       rebuild_label_notes_after_reload = local_alloc ();
4171	     });
4172  else
4173    rebuild_label_notes_after_reload = 0;
4174
4175  /* Dump rtl code after allocating regs within basic blocks.  */
4176
4177  if (local_reg_dump)
4178    {
4179      open_dump_file (".lreg", decl_printable_name (decl, 2));
4180
4181      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
4182      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
4183
4184      close_dump_file (print_rtl_with_bb, insns);
4185      if (graph_dump_format != no_graph)
4186	print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
4187    }
4188
4189  if (global_reg_dump)
4190    open_dump_file (".greg", decl_printable_name (decl, 2));
4191
4192  /* Unless we did stupid register allocation,
4193     allocate remaining pseudo-regs, then do the reload pass
4194     fixing up any insns that are invalid.  */
4195
4196  TIMEVAR (global_alloc_time,
4197	   {
4198	     if (!obey_regdecls)
4199	       failure = global_alloc (rtl_dump_file);
4200	     else
4201	       failure = reload (insns, 0, rtl_dump_file);
4202	   });
4203
4204
4205  if (failure)
4206    goto exit_rest_of_compilation;
4207
4208  /* Do a very simple CSE pass over just the hard registers.  */
4209  if (optimize > 0)
4210    reload_cse_regs (insns);
4211
4212  /* Register allocation and reloading may have turned an indirect jump into
4213     a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
4214     jumping instructions.  */
4215  if (rebuild_label_notes_after_reload)
4216    TIMEVAR (jump_time, rebuild_jump_labels (insns));
4217
4218  /* If optimizing and we are performing instruction scheduling after
4219     reload, then go ahead and split insns now since we are about to
4220     recompute flow information anyway.
4221
4222     reload_cse_regs may expose more splitting opportunities, expecially
4223     for double-word operations.  */
4224  if (optimize > 0 && flag_schedule_insns_after_reload)
4225    {
4226      rtx insn;
4227
4228      for (insn = insns; insn; insn = NEXT_INSN (insn))
4229	{
4230	  rtx last;
4231
4232	  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4233	    continue;
4234
4235	  last = try_split (PATTERN (insn), insn, 1);
4236
4237	  if (last != insn)
4238	    {
4239	      PUT_CODE (insn, NOTE);
4240	      NOTE_SOURCE_FILE (insn) = 0;
4241	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
4242	    }
4243	}
4244    }
4245
4246  if (global_reg_dump)
4247    {
4248      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
4249      close_dump_file (print_rtl_with_bb, insns);
4250      if (graph_dump_format != no_graph)
4251	print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
4252    }
4253
4254  /* Re-create the death notes which were deleted during reload.  */
4255  if (flow2_dump)
4256    open_dump_file (".flow2", decl_printable_name (decl, 2));
4257
4258  if (optimize)
4259    {
4260      TIMEVAR
4261	(flow2_time,
4262	 {
4263	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
4264	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
4265	 });
4266    }
4267
4268  flow2_completed = 1;
4269
4270  /* On some machines, the prologue and epilogue code, or parts thereof,
4271     can be represented as RTL.  Doing so lets us schedule insns between
4272     it and the rest of the code and also allows delayed branch
4273     scheduling to operate in the epilogue.  */
4274
4275  thread_prologue_and_epilogue_insns (insns);
4276
4277  if (flow2_dump)
4278    {
4279      close_dump_file (print_rtl_with_bb, insns);
4280      if (graph_dump_format != no_graph)
4281	print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
4282    }
4283
4284  if (optimize > 0 && flag_schedule_insns_after_reload)
4285    {
4286      if (sched2_dump)
4287	open_dump_file (".sched2", decl_printable_name (decl, 2));
4288
4289      /* Do control and data sched analysis again,
4290	 and write some more of the results to dump file.  */
4291
4292      TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
4293
4294      /* Dump rtl after post-reorder instruction scheduling.  */
4295
4296      if (sched2_dump)
4297	{
4298	  close_dump_file (print_rtl_with_bb, insns);
4299	  if (graph_dump_format != no_graph)
4300	    print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
4301	}
4302    }
4303
4304#ifdef LEAF_REGISTERS
4305  current_function_uses_only_leaf_regs
4306    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
4307#endif
4308
4309  /* One more attempt to remove jumps to .+1
4310     left by dead-store-elimination.
4311     Also do cross-jumping this time
4312     and delete no-op move insns.  */
4313
4314  if (optimize > 0)
4315    {
4316      TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
4317					 JUMP_NOOP_MOVES,
4318					 !JUMP_AFTER_REGSCAN));
4319
4320      /* Dump rtl code after jump, if we are doing that.  */
4321
4322      if (jump2_opt_dump)
4323	{
4324	  dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
4325	  if (graph_dump_format != no_graph)
4326	    print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
4327	}
4328    }
4329
4330  /* If a machine dependent reorganization is needed, call it.  */
4331#ifdef MACHINE_DEPENDENT_REORG
4332   MACHINE_DEPENDENT_REORG (insns);
4333
4334   if (mach_dep_reorg_dump)
4335     {
4336       dump_rtl (".mach", decl, print_rtl_with_bb, insns);
4337       if (graph_dump_format != no_graph)
4338	 print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
4339     }
4340#endif
4341
4342  /* If a scheduling pass for delayed branches is to be done,
4343     call the scheduling code.  */
4344
4345#ifdef DELAY_SLOTS
4346  if (optimize > 0 && flag_delayed_branch)
4347    {
4348      if (dbr_sched_dump)
4349	open_dump_file (".dbr", decl_printable_name (decl, 2));
4350
4351      TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
4352
4353      if (dbr_sched_dump)
4354	{
4355	  close_dump_file (print_rtl_with_bb, insns);
4356	  if (graph_dump_format != no_graph)
4357	    print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
4358	}
4359    }
4360#endif
4361
4362  /* Shorten branches.  */
4363  TIMEVAR (shorten_branch_time,
4364	   {
4365	     shorten_branches (get_insns ());
4366	   });
4367
4368#ifdef STACK_REGS
4369  if (stack_reg_dump)
4370    open_dump_file (".stack", decl_printable_name (decl, 2));
4371
4372  TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
4373
4374  if (stack_reg_dump)
4375    {
4376      dump_rtl (".stack", decl, print_rtl_with_bb, insns);
4377      if (graph_dump_format != no_graph)
4378	print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
4379    }
4380#endif
4381
4382  /* Now turn the rtl into assembler code.  */
4383
4384  TIMEVAR (final_time,
4385	   {
4386	     rtx x;
4387	     char *fnname;
4388
4389	     /* Get the function's name, as described by its RTL.
4390		This may be different from the DECL_NAME name used
4391		in the source file.  */
4392
4393	     x = DECL_RTL (decl);
4394	     if (GET_CODE (x) != MEM)
4395	       abort ();
4396	     x = XEXP (x, 0);
4397	     if (GET_CODE (x) != SYMBOL_REF)
4398	       abort ();
4399	     fnname = XSTR (x, 0);
4400
4401	     assemble_start_function (decl, fnname);
4402	     final_start_function (insns, asm_out_file, optimize);
4403	     final (insns, asm_out_file, optimize, 0);
4404	     final_end_function (insns, asm_out_file, optimize);
4405	     assemble_end_function (decl, fnname);
4406	     if (! quiet_flag)
4407	       fflush (asm_out_file);
4408
4409	     /* Release all memory allocated by flow.  */
4410	     free_basic_block_vars (0);
4411
4412	     /* Release all memory held by regsets now */
4413	     regset_release_memory ();
4414	   });
4415
4416  /* Write DBX symbols if requested */
4417
4418  /* Note that for those inline functions where we don't initially
4419     know for certain that we will be generating an out-of-line copy,
4420     the first invocation of this routine (rest_of_compilation) will
4421     skip over this code by doing a `goto exit_rest_of_compilation;'.
4422     Later on, finish_compilation will call rest_of_compilation again
4423     for those inline functions that need to have out-of-line copies
4424     generated.  During that call, we *will* be routed past here.  */
4425
4426#ifdef DBX_DEBUGGING_INFO
4427  if (write_symbols == DBX_DEBUG)
4428    TIMEVAR (symout_time, dbxout_function (decl));
4429#endif
4430
4431#ifdef DWARF_DEBUGGING_INFO
4432  if (write_symbols == DWARF_DEBUG)
4433    TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
4434#endif
4435
4436#ifdef DWARF2_DEBUGGING_INFO
4437  if (write_symbols == DWARF2_DEBUG)
4438    TIMEVAR (symout_time, dwarf2out_decl (decl));
4439#endif
4440
4441 exit_rest_of_compilation:
4442
4443  free_bb_mem ();
4444
4445  /* In case the function was not output,
4446     don't leave any temporary anonymous types
4447     queued up for sdb output.  */
4448#ifdef SDB_DEBUGGING_INFO
4449  if (write_symbols == SDB_DEBUG)
4450    sdbout_types (NULL_TREE);
4451#endif
4452
4453  /* Put back the tree of subblocks and list of arguments
4454     from before we copied them.
4455     Code generation and the output of debugging info may have modified
4456     the copy, but the original is unchanged.  */
4457
4458  if (saved_block_tree != 0)
4459    {
4460      DECL_INITIAL (decl) = saved_block_tree;
4461      DECL_ARGUMENTS (decl) = saved_arguments;
4462      DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
4463    }
4464
4465  reload_completed = 0;
4466  flow2_completed = 0;
4467  no_new_pseudos = 0;
4468
4469  TIMEVAR (final_time,
4470	   {
4471	      /* Clear out the insn_length contents now that they are no
4472		 longer valid.  */
4473	      init_insn_lengths ();
4474
4475	      /* Clear out the real_constant_chain before some of the rtx's
4476		 it runs through become garbage.  */
4477	      clear_const_double_mem ();
4478
4479	      /* Cancel the effect of rtl_in_current_obstack.  */
4480	      resume_temporary_allocation ();
4481
4482	      /* Show no temporary slots allocated.  */
4483	      init_temp_slots ();
4484	   });
4485
4486  /* Make sure volatile mem refs aren't considered valid operands for
4487     arithmetic insns.  We must call this here if this is a nested inline
4488     function, since the above code leaves us in the init_recog state
4489     (from final.c), and the function context push/pop code does not
4490     save/restore volatile_ok.
4491
4492     ??? Maybe it isn't necessary for expand_start_function to call this
4493     anymore if we do it here?  */
4494
4495  init_recog_no_volatile ();
4496
4497  /* The parsing time is all the time spent in yyparse
4498     *except* what is spent in this function.  */
4499
4500  parse_time -= get_run_time () - start_time;
4501
4502  /* Reset global variables.  */
4503  free_basic_block_vars (0);
4504}
4505
4506static void
4507display_help ()
4508{
4509  int    undoc;
4510  unsigned long	 i;
4511  const char * lang;
4512
4513#ifndef USE_CPPLIB
4514  printf ("Usage: %s input [switches]\n", progname);
4515  printf ("Switches:\n");
4516#endif
4517  printf ("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n");
4518  printf ("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n");
4519  printf ("  -fcall-saved-<register> Mark <register> as being preserved across functions\n");
4520  printf ("  -finline-limit-<number> Limits the size of inlined functions to <number>\n");
4521
4522  for (i = NUM_ELEM (f_options); i--;)
4523    {
4524      const char * description = f_options[i].description;
4525
4526      if (description != NULL && * description != 0)
4527	printf ("  -f%-21s %s\n",
4528		f_options[i].string, description);
4529    }
4530
4531  printf ("  -O[number]              Set optimisation level to [number]\n");
4532  printf ("  -Os                     Optimise for space rather than speed\n");
4533  printf ("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n");
4534  printf ("  -pedantic-errors        Like -pedantic except that errors are produced\n");
4535  printf ("  -w                      Suppress warnings\n");
4536  printf ("  -W                      Enable extra warnings\n");
4537
4538  for (i = NUM_ELEM (W_options); i--;)
4539    {
4540      const char * description = W_options[i].description;
4541
4542      if (description != NULL && * description != 0)
4543	printf ("  -W%-21s %s\n",
4544		W_options[i].string, description);
4545    }
4546
4547  printf ("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n");
4548  printf ("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n");
4549  printf ("  -p                      Enable function profiling\n");
4550#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
4551  printf ("  -a                      Enable block profiling \n");
4552#endif
4553#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
4554  printf ("  -ax                     Enable jump profiling \n");
4555#endif
4556  printf ("  -o <file>               Place output into <file> \n");
4557  printf ("  -G <number>             Put global and static data smaller than <number>\n");
4558  printf ("                           bytes into a special section (on some targets)\n");
4559
4560  for (i = NUM_ELEM (debug_args); i--;)
4561    {
4562      if (debug_args[i].description != NULL)
4563	printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
4564    }
4565
4566  printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
4567  printf ("  -quiet                  Do not display functions compiled or elapsed time\n");
4568  printf ("  -version                Display the compiler's version\n");
4569  printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
4570  printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
4571#if defined HAIFA || defined INSN_SCHEDULING
4572  printf ("  -sched-verbose-<number> Set the verbosity level of the scheduler\n");
4573#endif
4574  printf ("  --help                  Display this information\n");
4575
4576  undoc = 0;
4577  lang  = "language";
4578
4579  /* Display descriptions of language specific options.
4580     If there is no description, note that there is an undocumented option.
4581     If the description is empty, do not display anything.  (This allows
4582     options to be deliberately undocumented, for whatever reason).
4583     If the option string is missing, then this is a marker, indicating
4584     that the description string is in fact the name of a language, whose
4585     language specific options are to follow.  */
4586
4587  if (NUM_ELEM (documented_lang_options) > 1)
4588    {
4589      printf ("\nLanguage specific options:\n");
4590
4591      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
4592	{
4593	  const char * description = documented_lang_options[i].description;
4594	  const char * option      = documented_lang_options[i].option;
4595
4596	  if (description == NULL)
4597	    {
4598	      undoc = 1;
4599
4600	      if (extra_warnings)
4601		printf ("  %-23.23s [undocumented]\n", option);
4602	    }
4603	  else if (* description == 0)
4604	    continue;
4605	  else if (option == NULL)
4606	    {
4607	      if (undoc)
4608		printf
4609		  ("\nThere are undocumented %s specific options as well.\n",
4610			lang);
4611	      undoc = 0;
4612
4613	      printf ("\n Options for %s:\n", description);
4614
4615	      lang = description;
4616	    }
4617	  else
4618	    printf ("  %-23.23s %s\n", option, description);
4619	}
4620    }
4621
4622  if (undoc)
4623    printf ("\nThere are undocumented %s specific options as well.\n", lang);
4624
4625  if (NUM_ELEM (target_switches) > 1
4626#ifdef TARGET_OPTIONS
4627      || NUM_ELEM (target_options) > 1
4628#endif
4629      )
4630    {
4631      int doc = 0;
4632
4633      undoc = 0;
4634
4635      printf ("\nTarget specific options:\n");
4636
4637      for (i = NUM_ELEM (target_switches); i--;)
4638	{
4639	  const char * option      = target_switches[i].name;
4640	  const char * description = target_switches[i].description;
4641
4642	  if (option == NULL || * option == 0)
4643	    continue;
4644	  else if (description == NULL)
4645	    {
4646	      undoc = 1;
4647
4648	      if (extra_warnings)
4649		printf ("  -m%-21.21s [undocumented]\n", option);
4650	    }
4651	  else if (* description != 0)
4652	    doc += printf ("  -m%-21.21s %s\n", option, description);
4653	}
4654
4655#ifdef TARGET_OPTIONS
4656      for (i = NUM_ELEM (target_options); i--;)
4657	{
4658	  const char * option      = target_options[i].prefix;
4659	  const char * description = target_options[i].description;
4660
4661	  if (option == NULL || * option == 0)
4662	    continue;
4663	  else if (description == NULL)
4664	    {
4665	      undoc = 1;
4666
4667	      if (extra_warnings)
4668		printf ("  -m%-21.21s [undocumented]\n", option);
4669	    }
4670	  else if (* description != 0)
4671	    doc += printf ("  -m%-21.21s %s\n", option, description);
4672	}
4673#endif
4674      if (undoc)
4675	{
4676	  if (doc)
4677	    printf ("\nThere are undocumented target specific options as well.\n");
4678	  else
4679	    printf ("  They exist, but they are not documented.\n");
4680	}
4681    }
4682}
4683
4684/* Compare the user specified 'option' with the language
4685   specific 'lang_option'.  Return true if they match, or
4686   if 'option' is a viable prefix of 'lang_option'.  */
4687
4688static int
4689check_lang_option (option, lang_option)
4690     char * option;
4691     char * lang_option;
4692{
4693  lang_independent_options * indep_options;
4694  int    len;
4695  long    k;
4696  char * space;
4697
4698  /* Ignore NULL entries.  */
4699  if (option == NULL || lang_option == NULL)
4700    return 0;
4701
4702  if ((space = strchr (lang_option, ' ')) != NULL)
4703    len = space - lang_option;
4704  else
4705    len = strlen (lang_option);
4706
4707  /* If they do not match to the first n characters then fail.  */
4708  if (strncmp (option, lang_option, len) != 0)
4709    return 0;
4710
4711  /* Do not accept a lang option, if it matches a normal -f or -W
4712     option.  Chill defines a -fpack, but we want to support
4713     -fpack-struct.  */
4714
4715  /* An exact match is OK  */
4716  if ((int) strlen (option) == len)
4717    return 1;
4718
4719  /* If it is not an -f or -W option allow the match */
4720  if (option[0] != '-')
4721    return 1;
4722
4723  switch (option[1])
4724    {
4725    case 'f': indep_options = f_options; break;
4726    case 'W': indep_options = W_options; break;
4727    default:  return 1;
4728    }
4729
4730  /* The option is a -f or -W option.
4731     Skip past the prefix and search for the remainder in the
4732     appropriate table of options.  */
4733  option += 2;
4734
4735  if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
4736    option += 3;
4737
4738  for (k = NUM_ELEM (indep_options); k--;)
4739    {
4740      if (!strcmp (option, indep_options[k].string))
4741	{
4742	  /* The option matched a language independent option,
4743	     do not allow the language specific match.  */
4744
4745	  return 0;
4746	}
4747    }
4748
4749  /* The option matches the start of the langauge specific option
4750     and it is not an exact match for a language independent option.  */
4751  return 1;
4752}
4753
4754/* Entry point of cc1/c++.  Decode command args, then call compile_file.
4755   Exit code is 35 if can't open files, 34 if fatal error,
4756   33 if had nonfatal errors, else success.  */
4757
4758int
4759main (argc, argv)
4760     int argc;
4761     char **argv;
4762{
4763  register int i;
4764  char *filename = 0;
4765  int flag_print_mem = 0;
4766  int version_flag = 0;
4767  char *p;
4768
4769  /* save in case md file wants to emit args as a comment.  */
4770  save_argc = argc;
4771  save_argv = argv;
4772
4773  p = argv[0] + strlen (argv[0]);
4774  while (p != argv[0] && p[-1] != '/'
4775#ifdef DIR_SEPARATOR
4776	 && p[-1] != DIR_SEPARATOR
4777#endif
4778	 )
4779    --p;
4780  progname = p;
4781
4782#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
4783  /* Get rid of any avoidable limit on stack size.  */
4784  {
4785    struct rlimit rlim;
4786
4787    /* Set the stack limit huge so that alloca does not fail.  */
4788    getrlimit (RLIMIT_STACK, &rlim);
4789    rlim.rlim_cur = rlim.rlim_max;
4790    setrlimit (RLIMIT_STACK, &rlim);
4791  }
4792#endif
4793
4794#ifdef HAVE_LC_MESSAGES
4795  setlocale (LC_MESSAGES, "");
4796#endif
4797  (void) bindtextdomain (PACKAGE, localedir);
4798  (void) textdomain (PACKAGE);
4799
4800  signal (SIGFPE, float_signal);
4801
4802#ifdef SIGPIPE
4803  signal (SIGPIPE, pipe_closed);
4804#endif
4805
4806  decl_printable_name = decl_name;
4807  lang_expand_expr = (lang_expand_expr_t) do_abort;
4808
4809  /* Initialize whether `char' is signed.  */
4810  flag_signed_char = DEFAULT_SIGNED_CHAR;
4811#ifdef DEFAULT_SHORT_ENUMS
4812  /* Initialize how much space enums occupy, by default.  */
4813  flag_short_enums = DEFAULT_SHORT_ENUMS;
4814#endif
4815
4816  /* Perform language-specific options intialization.  */
4817  lang_init_options ();
4818
4819  /* Scan to see what optimization level has been specified.  That will
4820     determine the default value of many flags.  */
4821  for (i = 1; i < argc; i++)
4822    {
4823      if (!strcmp (argv[i], "-O"))
4824	{
4825	  optimize = 1;
4826	  optimize_size = 0;
4827	}
4828      else if (argv[i][0] == '-' && argv[i][1] == 'O')
4829	{
4830	  /* Handle -Os, -O2, -O3, -O69, ...  */
4831	  char *p = &argv[i][2];
4832
4833	  if ((p[0] == 's') && (p[1] == 0))
4834	    {
4835	      optimize_size = 1;
4836
4837	      /* Optimizing for size forces optimize to be 2. */
4838	      optimize = 2;
4839	    }
4840	  else
4841	    {
4842	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
4843	      if (optimize_val != -1)
4844		{
4845		  optimize = optimize_val;
4846#ifdef __alpha__
4847		  if (optimize > 1)
4848		    {
4849		      #ifdef FORCE_OPTIMIZATION_DOWNGRADE
4850		      optimize = 1;
4851		      warning ("\n***\n***\t-O%d converted to \"-O1\" due to optimizer bugs on this platform\n***\n",
4852			      optimize_val);
4853		      #else
4854		      warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n",
4855			      optimize_val);
4856		      #endif
4857		    }
4858#endif /*__alpha__*/
4859		  optimize_size = 0;
4860		}
4861	    }
4862	}
4863    }
4864
4865  obey_regdecls = (optimize == 0);
4866
4867  if (optimize >= 1)
4868    {
4869      flag_defer_pop = 1;
4870      flag_thread_jumps = 1;
4871#ifdef DELAY_SLOTS
4872      flag_delayed_branch = 1;
4873#endif
4874#ifdef CAN_DEBUG_WITHOUT_FP
4875      flag_omit_frame_pointer = 1;
4876#endif
4877    }
4878
4879  if (optimize >= 2)
4880    {
4881      flag_cse_follow_jumps = 1;
4882      flag_cse_skip_blocks = 1;
4883      flag_gcse = 1;
4884      flag_expensive_optimizations = 1;
4885      flag_strength_reduce = 1;
4886      flag_rerun_cse_after_loop = 1;
4887      flag_rerun_loop_opt = 1;
4888      flag_caller_saves = 1;
4889      flag_force_mem = 1;
4890#ifdef INSN_SCHEDULING
4891      flag_schedule_insns = 1;
4892      flag_schedule_insns_after_reload = 1;
4893#endif
4894      flag_regmove = 1;
4895    }
4896
4897  if (optimize >= 3)
4898    {
4899      flag_inline_functions = 1;
4900    }
4901
4902  /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
4903     modify it.  */
4904  target_flags = 0;
4905  set_target_switch ("");
4906
4907#ifdef OPTIMIZATION_OPTIONS
4908  /* Allow default optimizations to be specified on a per-machine basis.  */
4909  OPTIMIZATION_OPTIONS (optimize, optimize_size);
4910#endif
4911
4912  /* Initialize register usage now so switches may override.  */
4913  init_reg_sets ();
4914
4915  for (i = 1; i < argc; i++)
4916    {
4917      size_t j;
4918
4919      /* If this is a language-specific option,
4920	 decode it in a language-specific way.  */
4921      for (j = NUM_ELEM (documented_lang_options); j--;)
4922	if (check_lang_option (argv[i], documented_lang_options[j].option))
4923	  break;
4924
4925      if (j != (size_t)-1)
4926	{
4927	  /* If the option is valid for *some* language,
4928	     treat it as valid even if this language doesn't understand it.  */
4929	  int strings_processed = lang_decode_option (argc - i, argv + i);
4930
4931	  if (!strcmp (argv[i], "--help"))
4932	    {
4933	      display_help ();
4934	      exit (0);
4935	    }
4936
4937	  if (strings_processed != 0)
4938	    i += strings_processed - 1;
4939	}
4940      else if (argv[i][0] == '-' && argv[i][1] != 0)
4941	{
4942	  register char *str = argv[i] + 1;
4943	  if (str[0] == 'Y')
4944	    str++;
4945
4946	  if (str[0] == 'm')
4947	    set_target_switch (&str[1]);
4948	  else if (!strcmp (str, "dumpbase"))
4949	    {
4950	      dump_base_name = argv[++i];
4951	    }
4952	  else if (str[0] == 'd')
4953	    {
4954	      register char *p = &str[1];
4955	      while (*p)
4956		switch (*p++)
4957		  {
4958 		  case 'a':
4959		    branch_prob_dump = 1;
4960 		    combine_dump = 1;
4961#ifdef DELAY_SLOTS
4962 		    dbr_sched_dump = 1;
4963#endif
4964 		    flow_dump = 1;
4965 		    flow2_dump = 1;
4966 		    global_reg_dump = 1;
4967 		    jump_opt_dump = 1;
4968 		    addressof_dump = 1;
4969 		    jump2_opt_dump = 1;
4970 		    local_reg_dump = 1;
4971 		    loop_dump = 1;
4972		    regmove_dump = 1;
4973 		    rtl_dump = 1;
4974 		    cse_dump = 1, cse2_dump = 1;
4975		    gcse_dump = 1;
4976 		    sched_dump = 1;
4977 		    sched2_dump = 1;
4978#ifdef STACK_REGS
4979		    stack_reg_dump = 1;
4980#endif
4981#ifdef MACHINE_DEPENDENT_REORG
4982		    mach_dep_reorg_dump = 1;
4983#endif
4984		    break;
4985		  case 'A':
4986		    flag_debug_asm = 1;
4987		    break;
4988		  case 'b':
4989		    branch_prob_dump = 1;
4990		    break;
4991		  case 'c':
4992		    combine_dump = 1;
4993		    break;
4994#ifdef DELAY_SLOTS
4995		  case 'd':
4996		    dbr_sched_dump = 1;
4997		    break;
4998#endif
4999		  case 'f':
5000		    flow_dump = 1;
5001		    break;
5002		  case 'F':
5003		    addressof_dump = 1;
5004		    break;
5005		  case 'g':
5006		    global_reg_dump = 1;
5007		    break;
5008		  case 'G':
5009		    gcse_dump = 1;
5010		    break;
5011		  case 'j':
5012		    jump_opt_dump = 1;
5013		    break;
5014		  case 'J':
5015		    jump2_opt_dump = 1;
5016		    break;
5017#ifdef STACK_REGS
5018		  case 'k':
5019		    stack_reg_dump = 1;
5020		    break;
5021#endif
5022		  case 'l':
5023		    local_reg_dump = 1;
5024		    break;
5025		  case 'L':
5026		    loop_dump = 1;
5027		    break;
5028		  case 'm':
5029		    flag_print_mem = 1;
5030		    break;
5031#ifdef MACHINE_DEPENDENT_REORG
5032		  case 'M':
5033		    mach_dep_reorg_dump = 1;
5034		    break;
5035#endif
5036		  case 'p':
5037		    flag_print_asm_name = 1;
5038		    break;
5039		  case 'r':
5040		    rtl_dump = 1;
5041		    break;
5042		  case 'R':
5043		    sched2_dump = 1;
5044		    break;
5045		  case 's':
5046		    cse_dump = 1;
5047		    break;
5048		  case 'S':
5049		    sched_dump = 1;
5050		    break;
5051		  case 't':
5052		    cse2_dump = 1;
5053		    break;
5054		  case 'N':
5055		    regmove_dump = 1;
5056		    break;
5057		  case 'v':
5058		    graph_dump_format = vcg;
5059		    break;
5060		  case 'w':
5061		    flow2_dump = 1;
5062		    break;
5063		  case 'y':
5064		    set_yydebug (1);
5065		    break;
5066		  case 'x':
5067		    rtl_dump_and_exit = 1;
5068		    break;
5069		  case 'D':	/* these are handled by the preprocessor */
5070		  case 'I':
5071		    break;
5072		  default:
5073		    warning ("unrecognised gcc debugging option: %c", p[-1]);
5074		    break;
5075		  }
5076	    }
5077	  else if (str[0] == 'f')
5078	    {
5079	      register char *p = &str[1];
5080	      int found = 0;
5081
5082	      /* Some kind of -f option.
5083		 P's value is the option sans `-f'.
5084		 Search for it in the table of options.  */
5085
5086	      for (j = 0;
5087		   !found && j < sizeof (f_options) / sizeof (f_options[0]);
5088		   j++)
5089		{
5090		  if (!strcmp (p, f_options[j].string))
5091		    {
5092		      *f_options[j].variable = f_options[j].on_value;
5093		      /* A goto here would be cleaner,
5094			 but breaks the vax pcc.  */
5095		      found = 1;
5096		    }
5097		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
5098		      && ! strcmp (p+3, f_options[j].string))
5099		    {
5100		      *f_options[j].variable = ! f_options[j].on_value;
5101		      found = 1;
5102		    }
5103		}
5104
5105	      if (found)
5106		;
5107	      else if (!strncmp (p, "inline-limit-", 13))
5108	        inline_max_insns =
5109		  read_integral_parameter (p + 13, p - 2, inline_max_insns);
5110#ifdef HAIFA
5111#ifdef INSN_SCHEDULING
5112	      else if (!strncmp (p, "sched-verbose-",14))
5113		fix_sched_param("verbose",&p[14]);
5114#endif
5115#endif  /* HAIFA */
5116	      else if (!strncmp (p, "fixed-", 6))
5117		fix_register (&p[6], 1, 1);
5118	      else if (!strncmp (p, "call-used-", 10))
5119		fix_register (&p[10], 0, 1);
5120	      else if (!strncmp (p, "call-saved-", 11))
5121		fix_register (&p[11], 0, 0);
5122	      else
5123		error ("Invalid option `%s'", argv[i]);
5124	    }
5125	  else if (str[0] == 'O')
5126	    {
5127	      /* Already been treated above. Do nothing.  */
5128	    }
5129	  else if (!strcmp (str, "pedantic"))
5130	    pedantic = 1;
5131	  else if (!strcmp (str, "pedantic-errors"))
5132	    flag_pedantic_errors = pedantic = 1;
5133	  else if (!strcmp (str, "quiet"))
5134	    quiet_flag = 1;
5135	  else if (!strcmp (str, "version"))
5136	    version_flag = 1;
5137	  else if (!strcmp (str, "w"))
5138	    inhibit_warnings = 1;
5139	  else if (!strcmp (str, "W"))
5140	    {
5141	      extra_warnings = 1;
5142	      /* We save the value of warn_uninitialized, since if they put
5143		 -Wuninitialized on the command line, we need to generate a
5144		 warning about not using it without also specifying -O.  */
5145	      if (warn_uninitialized != 1)
5146		warn_uninitialized = 2;
5147	    }
5148	  else if (str[0] == 'W')
5149	    {
5150	      register char *p = &str[1];
5151	      int found = 0;
5152
5153	      /* Some kind of -W option.
5154		 P's value is the option sans `-W'.
5155		 Search for it in the table of options.  */
5156
5157	      for (j = 0;
5158		   !found && j < sizeof (W_options) / sizeof (W_options[0]);
5159		   j++)
5160		{
5161		  if (!strcmp (p, W_options[j].string))
5162		    {
5163		      *W_options[j].variable = W_options[j].on_value;
5164		      /* A goto here would be cleaner,
5165			 but breaks the vax pcc.  */
5166		      found = 1;
5167		    }
5168		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
5169		      && ! strcmp (p+3, W_options[j].string))
5170		    {
5171		      *W_options[j].variable = ! W_options[j].on_value;
5172		      found = 1;
5173		    }
5174		}
5175
5176	      if (found)
5177		;
5178	      else if (!strncmp (p, "id-clash-", 9))
5179		{
5180		  const int id_clash_val
5181		    = read_integral_parameter (p + 9, p - 2, -1);
5182		  if (id_clash_val != -1)
5183		    {
5184		      id_clash_len = id_clash_val;
5185		      warn_id_clash = 1;
5186		    }
5187		}
5188	      else if (!strncmp (p, "larger-than-", 12))
5189		{
5190		  const int larger_than_val
5191		    = read_integral_parameter (p + 12, p - 2, -1);
5192		  if (larger_than_val != -1)
5193		    {
5194		      larger_than_size = larger_than_val;
5195		      warn_larger_than = 1;
5196		    }
5197		}
5198	      else
5199		error ("Invalid option `%s'", argv[i]);
5200	    }
5201	  else if (!strcmp (str, "p"))
5202	    {
5203	      profile_flag = 1;
5204	    }
5205	  else if (!strcmp (str, "a"))
5206	    {
5207#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
5208	      warning ("`-a' option (basic block profile) not supported");
5209#else
5210              profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
5211#endif
5212	    }
5213	  else if (!strcmp (str, "ax"))
5214	    {
5215#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
5216	      warning ("`-ax' option (jump profiling) not supported");
5217#else
5218	      profile_block_flag = (!profile_block_flag
5219	                               || profile_block_flag == 2) ? 2 : 3;
5220#endif
5221	    }
5222	  else if (str[0] == 'g')
5223	    {
5224	      unsigned level;
5225	      /* A lot of code assumes write_symbols == NO_DEBUG if the
5226		 debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
5227		 of what debugging type has been selected).  This records the
5228		 selected type.  It is an error to specify more than one
5229		 debugging type.  */
5230	      static enum debug_info_type selected_debug_type = NO_DEBUG;
5231	      /* Non-zero if debugging format has been explicitly set.
5232		 -g and -ggdb don't explicitly set the debugging format so
5233		 -gdwarf -g3 is equivalent to -gdwarf3.  */
5234	      static int type_explicitly_set_p = 0;
5235	      /* Indexed by enum debug_info_type.  */
5236	      static const char *debug_type_names[] =
5237	      {
5238		"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
5239	      };
5240
5241	      /* The maximum admissible debug level value.  */
5242	      static const unsigned max_debug_level = 3;
5243
5244	      /* Look up STR in the table.  */
5245	      for (da = debug_args; da->arg; da++)
5246		{
5247		  const int da_len = strlen (da->arg);
5248
5249		  if (! strncmp (str, da->arg, da_len))
5250		    {
5251		      enum debug_info_type type = da->debug_type;
5252		      const char *p = str + da_len;
5253
5254		      if (*p && (*p < '0' || *p > '9'))
5255			continue;
5256
5257		      /* A debug flag without a level defaults to level 2.
5258			 Note we do not want to call read_integral_parameter
5259			 for that case since it will call atoi which
5260			 will return zero.
5261
5262			 ??? We may want to generalize the interface to
5263			 read_integral_parameter to better handle this case
5264			 if this case shows up often.  */
5265		      if (*p)
5266			level = read_integral_parameter (p, 0,
5267							 max_debug_level + 1);
5268		      else
5269			level = 2;
5270
5271		      if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
5272			{
5273			  error ("use -gdwarf -g%d for DWARF v1, level %d",
5274				 level, level);
5275			  if (level == 2)
5276			    error ("use -gdwarf-2   for DWARF v2");
5277			}
5278
5279		      if (level > max_debug_level)
5280			{
5281			  warning ("ignoring option `%s' due to invalid debug level specification",
5282				   str - 1);
5283			  level = debug_info_level;
5284			}
5285
5286		      if (type == NO_DEBUG)
5287			{
5288			  type = PREFERRED_DEBUGGING_TYPE;
5289			  if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
5290			    {
5291#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
5292			      type = DWARF2_DEBUG;
5293#else
5294#ifdef DBX_DEBUGGING_INFO
5295			      type = DBX_DEBUG;
5296#endif
5297#endif
5298			    }
5299			}
5300
5301		      if (type == NO_DEBUG)
5302			warning ("`-%s' not supported by this configuration of GCC",
5303				 str);
5304
5305		      /* Does it conflict with an already selected type?  */
5306		      if (type_explicitly_set_p
5307			  /* -g/-ggdb don't conflict with anything */
5308			  && da->debug_type != NO_DEBUG
5309			  && type != selected_debug_type)
5310			warning ("`-%s' ignored, conflicts with `-g%s'",
5311				 str, debug_type_names[(int) selected_debug_type]);
5312		      else
5313			{
5314			  /* If the format has already been set, -g/-ggdb
5315			     only change the debug level.  */
5316			  if (type_explicitly_set_p
5317			      && da->debug_type == NO_DEBUG)
5318			    ; /* don't change debugging type */
5319			  else
5320			    {
5321			      selected_debug_type = type;
5322			      type_explicitly_set_p = da->debug_type != NO_DEBUG;
5323			    }
5324			  write_symbols = (level == 0
5325					   ? NO_DEBUG
5326					   : selected_debug_type);
5327			  use_gnu_debug_info_extensions = da->use_extensions_p;
5328			  debug_info_level = (enum debug_info_level) level;
5329			}
5330		      break;
5331		    }
5332		}
5333	      if (! da->arg)
5334		warning ("`-%s' not supported by this configuration of GCC",
5335			 str);
5336	    }
5337	  else if (!strcmp (str, "o"))
5338	    {
5339	      asm_file_name = argv[++i];
5340	    }
5341	  else if (str[0] == 'G')
5342	    {
5343	      const int g_switch_val = (str[1] != '\0') ?
5344	                               read_integral_parameter(str + 1, 0, -1) :
5345			               read_integral_parameter(argv[++i], 0, -1);
5346
5347	      if (g_switch_val != -1)
5348	        {
5349		  g_switch_set = TRUE;
5350		  g_switch_value = g_switch_val;
5351		}
5352	      else
5353	        {
5354		  error("Invalid option `-%s'",str);
5355		}
5356	    }
5357	  else if (!strncmp (str, "aux-info", 8))
5358	    {
5359	      flag_gen_aux_info = 1;
5360	      aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
5361	    }
5362	  else if (!strcmp (str, "-help"))
5363	    {
5364	      display_help ();
5365	      exit (0);
5366	    }
5367	  else
5368	    error ("Invalid option `%s'", argv[i]);
5369	}
5370      else if (argv[i][0] == '+')
5371	error ("Invalid option `%s'", argv[i]);
5372      else
5373	filename = argv[i];
5374    }
5375
5376  /* Checker uses the frame pointer.  */
5377  if (flag_check_memory_usage)
5378    flag_omit_frame_pointer = 0;
5379
5380  if (optimize == 0)
5381    {
5382      /* Inlining does not work if not optimizing,
5383	 so force it not to be done.  */
5384      flag_no_inline = 1;
5385      warn_inline = 0;
5386
5387      /* The c_decode_option and lang_decode_option functions set
5388	 this to `2' if -Wall is used, so we can avoid giving out
5389	 lots of errors for people who don't realize what -Wall does.  */
5390      if (warn_uninitialized == 1)
5391	warning ("-Wuninitialized is not supported without -O");
5392    }
5393
5394#ifdef OVERRIDE_OPTIONS
5395  /* Some machines may reject certain combinations of options.  */
5396  OVERRIDE_OPTIONS;
5397#endif
5398
5399  if (exceptions_via_longjmp == 2)
5400    {
5401#ifdef DWARF2_UNWIND_INFO
5402      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
5403#else
5404      exceptions_via_longjmp = 1;
5405#endif
5406    }
5407
5408  if (profile_block_flag == 3)
5409    {
5410      warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
5411      profile_block_flag = 2;
5412    }
5413
5414  /* Unrolling all loops implies that standard loop unrolling must also
5415     be done.  */
5416  if (flag_unroll_all_loops)
5417    flag_unroll_loops = 1;
5418  /* Loop unrolling requires that strength_reduction be on also.  Silently
5419     turn on strength reduction here if it isn't already on.  Also, the loop
5420     unrolling code assumes that cse will be run after loop, so that must
5421     be turned on also.  */
5422  if (flag_unroll_loops)
5423    {
5424      flag_strength_reduce = 1;
5425      flag_rerun_cse_after_loop = 1;
5426    }
5427
5428  /* Warn about options that are not supported on this machine.  */
5429#ifndef INSN_SCHEDULING
5430  if (flag_schedule_insns || flag_schedule_insns_after_reload)
5431    warning ("instruction scheduling not supported on this target machine");
5432#endif
5433#ifndef DELAY_SLOTS
5434  if (flag_delayed_branch)
5435    warning ("this target machine does not have delayed branches");
5436#endif
5437
5438  user_label_prefix = USER_LABEL_PREFIX;
5439  if (flag_leading_underscore != -1)
5440    {
5441      /* If the default prefix is more complicated than "" or "_",
5442	 issue a warning and ignore this option.  */
5443      if (user_label_prefix[0] == 0 ||
5444	  (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
5445	{
5446	  user_label_prefix = flag_leading_underscore ? "_" : "";
5447	}
5448      else
5449	warning ("-f%sleading-underscore not supported on this target machine",
5450		 flag_leading_underscore ? "" : "no-");
5451    }
5452
5453  /* If we are in verbose mode, write out the version and maybe all the
5454     option flags in use.  */
5455  if (version_flag)
5456    {
5457      print_version (stderr, "");
5458      if (! quiet_flag)
5459	print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
5460    }
5461
5462  compile_file (filename);
5463
5464#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
5465  if (flag_print_mem)
5466    {
5467      char *lim = (char *) sbrk (0);
5468
5469      notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
5470      fflush (stderr);
5471
5472#ifndef __MSDOS__
5473#ifdef USG
5474      system ("ps -l 1>&2");
5475#else /* not USG */
5476      system ("ps v");
5477#endif /* not USG */
5478#endif
5479    }
5480#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
5481
5482  if (errorcount)
5483    exit (FATAL_EXIT_CODE);
5484  if (sorrycount)
5485    exit (FATAL_EXIT_CODE);
5486  exit (SUCCESS_EXIT_CODE);
5487  return 0;
5488}
5489
5490/* Decode -m switches.  */
5491/* Decode the switch -mNAME.  */
5492
5493static void
5494set_target_switch (name)
5495  const char *name;
5496{
5497  register size_t j;
5498  int valid_target_option = 0;
5499
5500  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
5501    if (!strcmp (target_switches[j].name, name))
5502      {
5503	if (target_switches[j].value < 0)
5504	  target_flags &= ~-target_switches[j].value;
5505	else
5506	  target_flags |= target_switches[j].value;
5507	valid_target_option = 1;
5508      }
5509
5510#ifdef TARGET_OPTIONS
5511  if (!valid_target_option)
5512    for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
5513      {
5514	int len = strlen (target_options[j].prefix);
5515	if (!strncmp (target_options[j].prefix, name, len))
5516	  {
5517	    *target_options[j].variable = name + len;
5518	    valid_target_option = 1;
5519	  }
5520      }
5521#endif
5522
5523  if (!valid_target_option)
5524    error ("Invalid option `%s'", name);
5525}
5526
5527/* Print version information to FILE.
5528   Each line begins with INDENT (for the case where FILE is the
5529   assembler output file).  */
5530
5531static void
5532print_version (file, indent)
5533     FILE *file;
5534     const char *indent;
5535{
5536#ifndef __VERSION__
5537#define __VERSION__ "[?]"
5538#endif
5539  fnotice (file,
5540#ifdef __GNUC__
5541	   "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
5542#else
5543	   "%s%s%s version %s (%s) compiled by CC.\n"
5544#endif
5545	   , indent, *indent != 0 ? " " : "",
5546	   language_string, version_string, TARGET_NAME, __VERSION__);
5547}
5548
5549/* Print an option value and return the adjusted position in the line.
5550   ??? We don't handle error returns from fprintf (disk full); presumably
5551   other code will catch a disk full though.  */
5552
5553static int
5554print_single_switch (file, pos, max, indent, sep, term, type, name)
5555     FILE *file;
5556     int pos, max;
5557     const char *indent, *sep, *term, *type, *name;
5558{
5559  /* The ultrix fprintf returns 0 on success, so compute the result we want
5560     here since we need it for the following test.  */
5561  int len = strlen (sep) + strlen (type) + strlen (name);
5562
5563  if (pos != 0
5564      && pos + len > max)
5565    {
5566      fprintf (file, "%s", term);
5567      pos = 0;
5568    }
5569  if (pos == 0)
5570    {
5571      fprintf (file, "%s", indent);
5572      pos = strlen (indent);
5573    }
5574  fprintf (file, "%s%s%s", sep, type, name);
5575  pos += len;
5576  return pos;
5577}
5578
5579/* Print active target switches to FILE.
5580   POS is the current cursor position and MAX is the size of a "line".
5581   Each line begins with INDENT and ends with TERM.
5582   Each switch is separated from the next by SEP.  */
5583
5584static void
5585print_switch_values (file, pos, max, indent, sep, term)
5586     FILE *file;
5587     int pos, max;
5588     const char *indent, *sep, *term;
5589{
5590  size_t j;
5591  char **p;
5592
5593  /* Print the options as passed.  */
5594
5595  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
5596			     _("options passed: "), "");
5597
5598  for (p = &save_argv[1]; *p != NULL; p++)
5599    if (**p == '-')
5600      {
5601	/* Ignore these.  */
5602	if (strcmp (*p, "-o") == 0)
5603	  {
5604	    if (p[1] != NULL)
5605	      p++;
5606	    continue;
5607	  }
5608	if (strcmp (*p, "-quiet") == 0)
5609	  continue;
5610	if (strcmp (*p, "-version") == 0)
5611	  continue;
5612	if ((*p)[1] == 'd')
5613	  continue;
5614
5615	pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
5616      }
5617  if (pos > 0)
5618    fprintf (file, "%s", term);
5619
5620  /* Print the -f and -m options that have been enabled.
5621     We don't handle language specific options but printing argv
5622     should suffice.  */
5623
5624  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
5625			     _("options enabled: "), "");
5626
5627  for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
5628    if (*f_options[j].variable == f_options[j].on_value)
5629      pos = print_single_switch (file, pos, max, indent, sep, term,
5630				 "-f", f_options[j].string);
5631
5632  /* Print target specific options.  */
5633
5634  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
5635    if (target_switches[j].name[0] != '\0'
5636	&& target_switches[j].value > 0
5637	&& ((target_switches[j].value & target_flags)
5638	    == target_switches[j].value))
5639      {
5640	pos = print_single_switch (file, pos, max, indent, sep, term,
5641				   "-m", target_switches[j].name);
5642      }
5643
5644#ifdef TARGET_OPTIONS
5645  for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
5646    if (*target_options[j].variable != NULL)
5647      {
5648	char prefix[256];
5649	sprintf (prefix, "-m%s", target_options[j].prefix);
5650	pos = print_single_switch (file, pos, max, indent, sep, term,
5651				   prefix, *target_options[j].variable);
5652      }
5653#endif
5654
5655  fprintf (file, "%s", term);
5656}
5657
5658/* Record the beginning of a new source file, named FILENAME.  */
5659
5660void
5661debug_start_source_file (filename)
5662     register char *filename ATTRIBUTE_UNUSED;
5663{
5664#ifdef DBX_DEBUGGING_INFO
5665  if (write_symbols == DBX_DEBUG)
5666    dbxout_start_new_source_file (filename);
5667#endif
5668#ifdef DWARF_DEBUGGING_INFO
5669  if (debug_info_level == DINFO_LEVEL_VERBOSE
5670      && write_symbols == DWARF_DEBUG)
5671    dwarfout_start_new_source_file (filename);
5672#endif /* DWARF_DEBUGGING_INFO */
5673#ifdef DWARF2_DEBUGGING_INFO
5674  if (debug_info_level == DINFO_LEVEL_VERBOSE
5675      && write_symbols == DWARF2_DEBUG)
5676    dwarf2out_start_source_file (filename);
5677#endif /* DWARF2_DEBUGGING_INFO */
5678#ifdef SDB_DEBUGGING_INFO
5679  if (write_symbols == SDB_DEBUG)
5680    sdbout_start_new_source_file (filename);
5681#endif
5682}
5683
5684/* Record the resumption of a source file.  LINENO is the line number in
5685   the source file we are returning to.  */
5686
5687void
5688debug_end_source_file (lineno)
5689     register unsigned lineno ATTRIBUTE_UNUSED;
5690{
5691#ifdef DBX_DEBUGGING_INFO
5692  if (write_symbols == DBX_DEBUG)
5693    dbxout_resume_previous_source_file ();
5694#endif
5695#ifdef DWARF_DEBUGGING_INFO
5696  if (debug_info_level == DINFO_LEVEL_VERBOSE
5697      && write_symbols == DWARF_DEBUG)
5698    dwarfout_resume_previous_source_file (lineno);
5699#endif /* DWARF_DEBUGGING_INFO */
5700#ifdef DWARF2_DEBUGGING_INFO
5701  if (debug_info_level == DINFO_LEVEL_VERBOSE
5702      && write_symbols == DWARF2_DEBUG)
5703    dwarf2out_end_source_file ();
5704#endif /* DWARF2_DEBUGGING_INFO */
5705#ifdef SDB_DEBUGGING_INFO
5706  if (write_symbols == SDB_DEBUG)
5707    sdbout_resume_previous_source_file ();
5708#endif
5709}
5710
5711/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
5712   the tail part of the directive line, i.e. the part which is past the
5713   initial whitespace, #, whitespace, directive-name, whitespace part.  */
5714
5715void
5716debug_define (lineno, buffer)
5717     register unsigned lineno ATTRIBUTE_UNUSED;
5718     register char *buffer ATTRIBUTE_UNUSED;
5719{
5720#ifdef DWARF_DEBUGGING_INFO
5721  if (debug_info_level == DINFO_LEVEL_VERBOSE
5722      && write_symbols == DWARF_DEBUG)
5723    dwarfout_define (lineno, buffer);
5724#endif /* DWARF_DEBUGGING_INFO */
5725#ifdef DWARF2_DEBUGGING_INFO
5726  if (debug_info_level == DINFO_LEVEL_VERBOSE
5727      && write_symbols == DWARF2_DEBUG)
5728    dwarf2out_define (lineno, buffer);
5729#endif /* DWARF2_DEBUGGING_INFO */
5730}
5731
5732/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
5733   the tail part of the directive line, i.e. the part which is past the
5734   initial whitespace, #, whitespace, directive-name, whitespace part.  */
5735
5736void
5737debug_undef (lineno, buffer)
5738     register unsigned lineno ATTRIBUTE_UNUSED;
5739     register char *buffer ATTRIBUTE_UNUSED;
5740{
5741#ifdef DWARF_DEBUGGING_INFO
5742  if (debug_info_level == DINFO_LEVEL_VERBOSE
5743      && write_symbols == DWARF_DEBUG)
5744    dwarfout_undef (lineno, buffer);
5745#endif /* DWARF_DEBUGGING_INFO */
5746#ifdef DWARF2_DEBUGGING_INFO
5747  if (debug_info_level == DINFO_LEVEL_VERBOSE
5748      && write_symbols == DWARF2_DEBUG)
5749    dwarf2out_undef (lineno, buffer);
5750#endif /* DWARF2_DEBUGGING_INFO */
5751}
5752