toplev.c revision 72566
118334Speter/* Top level of GNU C compiler
272566Sobrien   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
372566Sobrien   1999, 2000, 2001 Free Software Foundation, Inc.
418334Speter
518334SpeterThis file is part of GNU CC.
618334Speter
718334SpeterGNU CC is free software; you can redistribute it and/or modify
818334Speterit under the terms of the GNU General Public License as published by
918334Speterthe Free Software Foundation; either version 2, or (at your option)
1018334Speterany later version.
1118334Speter
1218334SpeterGNU CC is distributed in the hope that it will be useful,
1318334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1418334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1518334SpeterGNU General Public License for more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1818334Speteralong with GNU CC; see the file COPYING.  If not, write to
1918334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
2018334SpeterBoston, MA 02111-1307, USA.  */
2118334Speter
2252558Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 72566 2001-02-17 09:06:31Z obrien $ */
2352558Sobrien
2418334Speter/* This is the top level of cc1/c++.
2518334Speter   It parses command args, opens files, invokes the various passes
2618334Speter   in the proper order, and counts the time used by each.
2718334Speter   Error messages and low-level interface to malloc also handled here.  */
2818334Speter
2918334Speter#include "config.h"
3050615Sobrien#undef FLOAT /* This is for hpux. They should change hpux.  */
3150615Sobrien#undef FFS  /* Some systems define this in param.h.  */
3250615Sobrien#include "system.h"
3318334Speter#include <signal.h>
3418334Speter#include <setjmp.h>
3518334Speter
3650615Sobrien#ifdef HAVE_SYS_RESOURCE_H
3750615Sobrien# include <sys/resource.h>
3818334Speter#endif
3950615Sobrien
4050615Sobrien#ifdef HAVE_SYS_TIMES_H
4150615Sobrien# include <sys/times.h>
4218334Speter#endif
4318334Speter
4418334Speter#include "input.h"
4518334Speter#include "tree.h"
4618334Speter#include "rtl.h"
4718334Speter#include "flags.h"
4818334Speter#include "insn-attr.h"
4950615Sobrien#include "insn-codes.h"
5050615Sobrien#include "insn-config.h"
5150615Sobrien#include "recog.h"
5218334Speter#include "defaults.h"
5318334Speter#include "output.h"
5450615Sobrien#include "except.h"
5550615Sobrien#include "toplev.h"
5652558Sobrien#include "expr.h"
5752558Sobrien#include "basic-block.h"
5852558Sobrien#include "intl.h"
5918334Speter
6050615Sobrien#ifdef DWARF_DEBUGGING_INFO
6150615Sobrien#include "dwarfout.h"
6250615Sobrien#endif
6350615Sobrien
6450615Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
6550615Sobrien#include "dwarf2out.h"
6650615Sobrien#endif
6750615Sobrien
6850615Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
6950615Sobrien#include "dbxout.h"
7050615Sobrien#endif
7150615Sobrien
7250615Sobrien#ifdef SDB_DEBUGGING_INFO
7350615Sobrien#include "sdbout.h"
7450615Sobrien#endif
7550615Sobrien
7618334Speter#ifdef XCOFF_DEBUGGING_INFO
7718334Speter#include "xcoffout.h"
7818334Speter#endif
7918334Speter
8018334Speter#ifdef VMS
8118334Speter/* The extra parameters substantially improve the I/O performance.  */
8218334Speterstatic FILE *
8318334Spetervms_fopen (fname, type)
8418334Speter     char * fname;
8518334Speter     char * type;
8618334Speter{
8718334Speter  /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
8818334Speter     fixed arguments, which matches ANSI's specification but not VAXCRTL's
8918334Speter     pre-ANSI implementation.  This hack circumvents the mismatch problem.  */
9018334Speter  FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
9118334Speter
9218334Speter  if (*type == 'w')
9318334Speter    return (*vmslib_fopen) (fname, type, "mbc=32",
9418334Speter			    "deq=64", "fop=tef", "shr=nil");
9518334Speter  else
9618334Speter    return (*vmslib_fopen) (fname, type, "mbc=32");
9718334Speter}
9818334Speter#define fopen vms_fopen
9918334Speter#endif	/* VMS */
10018334Speter
10118334Speter#ifndef DEFAULT_GDB_EXTENSIONS
10218334Speter#define DEFAULT_GDB_EXTENSIONS 1
10318334Speter#endif
10418334Speter
10550615Sobrien/* If more than one debugging type is supported, you must define
10650615Sobrien   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way.
10750615Sobrien
10850615Sobrien   This is one long line cause VAXC can't handle a \-newline.  */
10950615Sobrien#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
11050615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE
11150615SobrienYou Lose!  You must define PREFERRED_DEBUGGING_TYPE!
11250615Sobrien#endif /* no PREFERRED_DEBUGGING_TYPE */
11350615Sobrien#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
11450615Sobrien	 so the following code needn't care.  */
11550615Sobrien#ifdef DBX_DEBUGGING_INFO
11650615Sobrien#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
11750615Sobrien#endif
11850615Sobrien#ifdef SDB_DEBUGGING_INFO
11950615Sobrien#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
12050615Sobrien#endif
12150615Sobrien#ifdef DWARF_DEBUGGING_INFO
12250615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
12350615Sobrien#endif
12450615Sobrien#ifdef DWARF2_DEBUGGING_INFO
12550615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
12650615Sobrien#endif
12750615Sobrien#ifdef XCOFF_DEBUGGING_INFO
12850615Sobrien#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
12950615Sobrien#endif
13050615Sobrien#endif /* More than one debugger format enabled.  */
13150615Sobrien
13250615Sobrien/* If still not defined, must have been because no debugging formats
13350615Sobrien   are supported.  */
13450615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE
13550615Sobrien#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
13650615Sobrien#endif
13750615Sobrien
13852558Sobrien#ifndef DIR_SEPARATOR
13952558Sobrien#define DIR_SEPARATOR '/'
14052558Sobrien#endif
14152558Sobrien
14218334Speterextern int rtx_equal_function_value_matters;
14318334Speter
14418334Speter#if ! (defined (VMS) || defined (OS2))
14518334Speterextern char **environ;
14618334Speter#endif
14718334Speterextern char *version_string, *language_string;
14818334Speter
14918334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME
15018334Speter   to ASM_FINISH_DECLARE_OBJECT.  */
15118334Speter
15218334Speterextern int size_directive_output;
15318334Speterextern tree last_assemble_variable_decl;
15418334Speter
15550615Sobrienextern char *init_parse PVPROTO((char *));
15650615Sobrienextern void finish_parse ();
15718334Speterextern void init_decl_processing ();
15818334Speterextern void init_obstacks ();
15918334Speterextern void init_tree_codes ();
16018334Speterextern void init_rtl ();
16118334Speterextern void init_regs ();
16218334Speterextern void init_optabs ();
16318334Speterextern void init_stmt ();
16418334Speterextern void init_reg_sets ();
16518334Speterextern void dump_flow_info ();
16618334Speterextern void dump_sched_info ();
16718334Speterextern void dump_local_alloc ();
16850615Sobrienextern void regset_release_memory ();
16918334Speter
17050615Sobrienextern void print_rtl ();
17150615Sobrienextern void print_rtl_with_bb ();
17250615Sobrien
17318334Spetervoid rest_of_decl_compilation ();
17452558Sobrienvoid error_with_file_and_line PVPROTO((const char *file,
17552558Sobrien				       int line, const char *s, ...));
17652558Sobrienvoid error_with_decl PVPROTO((tree decl, const char *s, ...));
17752558Sobrienvoid error_for_asm PVPROTO((rtx insn, const char *s, ...));
17852558Sobrienvoid notice PVPROTO((const char *s, ...));
17952558Sobrienvoid error PVPROTO((const char *s, ...));
18052558Sobrienvoid fatal PVPROTO((const char *s, ...));
18152558Sobrienvoid warning_with_file_and_line PVPROTO((const char *file,
18252558Sobrien					 int line, const char *s, ...));
18352558Sobrienvoid warning_with_decl PVPROTO((tree decl, const char *s, ...));
18452558Sobrienvoid warning PVPROTO((const char *s, ...));
18552558Sobrienvoid pedwarn PVPROTO((const char *s, ...));
18652558Sobrienvoid pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
18752558Sobrienvoid pedwarn_with_file_and_line PVPROTO((const char *file,
18852558Sobrien					 int line, const char *s, ...));
18952558Sobrienvoid sorry PVPROTO((const char *s, ...));
19052558Sobrienstatic void set_target_switch PROTO((const char *));
19150615Sobrienstatic char *decl_name PROTO((tree, int));
19252558Sobrienstatic void vmessage PROTO((const char *, const char *, va_list));
19352558Sobrienstatic void v_message_with_file_and_line PROTO((const char *, int, int,
19452558Sobrien						const char *, va_list));
19552558Sobrienstatic void v_message_with_decl PROTO((tree, int, const char *, va_list));
19650615Sobrienstatic void file_and_line_for_asm PROTO((rtx, char **, int *));
19752558Sobrienstatic void v_error_with_file_and_line PROTO((const char *, int,
19852558Sobrien					      const char *, va_list));
19952558Sobrienstatic void v_error_with_decl PROTO((tree, const char *, va_list));
20052558Sobrienstatic void v_error_for_asm PROTO((rtx, const char *, va_list));
20152558Sobrienstatic void verror PROTO((const char *, va_list));
20252558Sobrienstatic void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
20352558Sobrienstatic void v_warning_with_file_and_line PROTO ((const char *, int,
20452558Sobrien						 const char *, va_list));
20552558Sobrienstatic void v_warning_with_decl PROTO((tree, const char *, va_list));
20652558Sobrienstatic void v_warning_for_asm PROTO((rtx, const char *, va_list));
20752558Sobrienstatic void vwarning PROTO((const char *, va_list));
20852558Sobrienstatic void vpedwarn PROTO((const char *, va_list));
20952558Sobrienstatic void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
21052558Sobrienstatic void v_pedwarn_with_file_and_line PROTO((const char *, int,
21152558Sobrien						const char *, va_list));
21252558Sobrienstatic void vsorry PROTO((const char *, va_list));
21352558Sobrienstatic void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
21452558Sobrienstatic void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
21552558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE
21652558Sobrien/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
21752558Sobrienstatic void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
21852558Sobrien#endif
21952558Sobrienstatic void open_dump_file PROTO((const char *, const char *));
22050615Sobrienstatic void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
22152558Sobrienstatic void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
22252558Sobrienstatic void clean_dump_file PROTO((const char *));
22350615Sobrienstatic void compile_file PROTO((char *));
22450615Sobrienstatic void display_help PROTO ((void));
22518334Speter
22652558Sobrienstatic void print_version PROTO((FILE *, const char *));
22752558Sobrienstatic int print_single_switch PROTO((FILE *, int, int, const char *,
22852558Sobrien				      const char *, const char *,
22952558Sobrien				      const char *, const char *));
23052558Sobrienstatic void print_switch_values PROTO((FILE *, int, int, const char *,
23152558Sobrien				       const char *, const char *));
23252558Sobrien
23352558Sobrienvoid print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
23452558Sobrienvoid clean_graph_dump_file PROTO ((const char *, const char *));
23552558Sobrienvoid finish_graph_dump_file PROTO ((const char *, const char *));
23650615Sobrien/* Length of line when printing switch values.  */
23750615Sobrien#define MAX_LINE 75
23818334Speter
23918334Speter/* Name of program invoked, sans directories.  */
24018334Speter
24118334Speterchar *progname;
24218334Speter
24318334Speter/* Copy of arguments to main.  */
24418334Speterint save_argc;
24518334Speterchar **save_argv;
24618334Speter
24718334Speter/* Name of current original source file (what was input to cpp).
24818334Speter   This comes from each #-command in the actual input.  */
24918334Speter
25018334Speterchar *input_filename;
25118334Speter
25218334Speter/* Name of top-level original source file (what was input to cpp).
25318334Speter   This comes from the #-command at the beginning of the actual input.
25418334Speter   If there isn't any there, then this is the cc1 input file name.  */
25518334Speter
25618334Speterchar *main_input_filename;
25718334Speter
25818334Speter/* Current line number in real source file.  */
25918334Speter
26018334Speterint lineno;
26118334Speter
26252558Sobrien/* Nonzero if it is unsafe to create any new pseudo registers.  */
26352558Sobrienint no_new_pseudos;
26452558Sobrien
26518334Speter/* Stack of currently pending input files.  */
26618334Speter
26718334Speterstruct file_stack *input_file_stack;
26818334Speter
26918334Speter/* Incremented on each change to input_file_stack.  */
27018334Speterint input_file_stack_tick;
27118334Speter
27218334Speter/* FUNCTION_DECL for function now being parsed or compiled.  */
27318334Speter
27418334Speterextern tree current_function_decl;
27518334Speter
27618334Speter/* Name to use as base of names for dump output files.  */
27718334Speter
27852558Sobrienconst char *dump_base_name;
27918334Speter
28018334Speter/* Bit flags that specify the machine subtype we are compiling for.
28118334Speter   Bits are tested using macros TARGET_... defined in the tm.h file
28218334Speter   and set by `-m...' switches.  Must be defined in rtlanal.c.  */
28318334Speter
28418334Speterextern int target_flags;
28518334Speter
28618334Speter/* Flags saying which kinds of debugging dump have been requested.  */
28718334Speter
28818334Speterint rtl_dump = 0;
28918334Speterint rtl_dump_and_exit = 0;
29018334Speterint jump_opt_dump = 0;
29150615Sobrienint addressof_dump = 0;
29218334Speterint cse_dump = 0;
29350615Sobrienint gcse_dump = 0;
29418334Speterint loop_dump = 0;
29518334Speterint cse2_dump = 0;
29650615Sobrienint branch_prob_dump = 0;
29718334Speterint flow_dump = 0;
29818334Speterint combine_dump = 0;
29950615Sobrienint regmove_dump = 0;
30018334Speterint sched_dump = 0;
30118334Speterint local_reg_dump = 0;
30218334Speterint global_reg_dump = 0;
30352558Sobrienint flow2_dump = 0;
30418334Speterint sched2_dump = 0;
30518334Speterint jump2_opt_dump = 0;
30650615Sobrien#ifdef DELAY_SLOTS
30718334Speterint dbr_sched_dump = 0;
30850615Sobrien#endif
30918334Speterint flag_print_asm_name = 0;
31050615Sobrien#ifdef STACK_REGS
31118334Speterint stack_reg_dump = 0;
31250615Sobrien#endif
31350615Sobrien#ifdef MACHINE_DEPENDENT_REORG
31450615Sobrienint mach_dep_reorg_dump = 0;
31550615Sobrien#endif
31652558Sobrienenum graph_dump_types graph_dump_format;
31718334Speter
31818334Speter/* Name for output file of assembly code, specified with -o.  */
31918334Speter
32018334Speterchar *asm_file_name;
32118334Speter
32218334Speter/* Value of the -G xx switch, and whether it was passed or not.  */
32318334Speterint g_switch_value;
32418334Speterint g_switch_set;
32518334Speter
32618334Speter/* Type(s) of debugging information we are producing (if any).
32718334Speter   See flags.h for the definitions of the different possible
32818334Speter   types of debugging information.  */
32918334Speterenum debug_info_type write_symbols = NO_DEBUG;
33018334Speter
33118334Speter/* Level of debugging information we are producing.  See flags.h
33218334Speter   for the definitions of the different possible levels.  */
33318334Speterenum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
33418334Speter
33518334Speter/* Nonzero means use GNU-only extensions in the generated symbolic
33618334Speter   debugging information.  */
33718334Speter/* Currently, this only has an effect when write_symbols is set to
33818334Speter   DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
33918334Speterint use_gnu_debug_info_extensions = 0;
34018334Speter
34118334Speter/* Nonzero means do optimizations.  -O.
34218334Speter   Particular numeric values stand for particular amounts of optimization;
34318334Speter   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
34418334Speter   ones are not controlled directly by this variable.  Instead, they are
34518334Speter   controlled by individual `flag_...' variables that are defaulted
34618334Speter   based on this variable.  */
34718334Speter
34818334Speterint optimize = 0;
34918334Speter
35050615Sobrien/* Nonzero means optimize for size.  -Os.
35150615Sobrien   The only valid values are zero and non-zero. When optimize_size is
35250615Sobrien   non-zero, optimize defaults to 2, but certain individual code
35350615Sobrien   bloating optimizations are disabled.  */
35450615Sobrien
35550615Sobrienint optimize_size = 0;
35650615Sobrien
35718334Speter/* Number of error messages and warning messages so far.  */
35818334Speter
35918334Speterint errorcount = 0;
36018334Speterint warningcount = 0;
36118334Speterint sorrycount = 0;
36218334Speter
36350615Sobrien/* Pointer to function to compute the name to use to print a declaration.
36450615Sobrien   DECL is the declaration in question.
36550615Sobrien   VERBOSITY determines what information will be printed:
36650615Sobrien     0: DECL_NAME, demangled as necessary.
36750615Sobrien     1: and scope information.
36850615Sobrien     2: and any other information that might be interesting, such as function
36950615Sobrien        parameter types in C++.  */
37018334Speter
37152558Sobrienchar *(*decl_printable_name)		PROTO ((tree, int));
37218334Speter
37318334Speter/* Pointer to function to compute rtl for a language-specific tree code.  */
37418334Speter
37552558Sobrientypedef rtx (*lang_expand_expr_t)
37652558Sobrien  PROTO ((union tree_node *, rtx, enum machine_mode,
37752558Sobrien	  enum expand_modifier modifier));
37818334Speter
37952558Sobrienlang_expand_expr_t lang_expand_expr = 0;
38052558Sobrien
38152558Sobrientree (*lang_expand_constant) PROTO((tree)) = 0;
38252558Sobrien
38318334Speter/* Pointer to function to finish handling an incomplete decl at the
38418334Speter   end of compilation.  */
38518334Speter
38652558Sobrienvoid (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
38718334Speter
38818334Speter/* Nonzero if generating code to do profiling.  */
38918334Speter
39018334Speterint profile_flag = 0;
39118334Speter
39218334Speter/* Nonzero if generating code to do profiling on a line-by-line basis.  */
39318334Speter
39418334Speterint profile_block_flag;
39518334Speter
39650615Sobrien/* Nonzero if generating code to profile program flow graph arcs.  */
39750615Sobrien
39850615Sobrienint profile_arc_flag = 0;
39950615Sobrien
40050615Sobrien/* Nonzero if generating info for gcov to calculate line test coverage.  */
40150615Sobrien
40250615Sobrienint flag_test_coverage = 0;
40350615Sobrien
40450615Sobrien/* Nonzero indicates that branch taken probabilities should be calculated.  */
40550615Sobrien
40650615Sobrienint flag_branch_probabilities = 0;
40750615Sobrien
40818334Speter/* Nonzero for -pedantic switch: warn about anything
40918334Speter   that standard spec forbids.  */
41018334Speter
41118334Speterint pedantic = 0;
41218334Speter
41318334Speter/* Temporarily suppress certain warnings.
41418334Speter   This is set while reading code from a system header file.  */
41518334Speter
41618334Speterint in_system_header = 0;
41718334Speter
41818334Speter/* Nonzero means do stupid register allocation.
41918334Speter   Currently, this is 1 if `optimize' is 0.  */
42018334Speter
42118334Speterint obey_regdecls = 0;
42218334Speter
42318334Speter/* Don't print functions as they are compiled and don't print
42418334Speter   times taken by the various passes.  -quiet.  */
42518334Speter
42618334Speterint quiet_flag = 0;
42718334Speter
42818334Speter/* -f flags.  */
42918334Speter
43018334Speter/* Nonzero means `char' should be signed.  */
43118334Speter
43218334Speterint flag_signed_char;
43318334Speter
43418334Speter/* Nonzero means give an enum type only as many bytes as it needs.  */
43518334Speter
43618334Speterint flag_short_enums;
43718334Speter
43818334Speter/* Nonzero for -fcaller-saves: allocate values in regs that need to
43918334Speter   be saved across function calls, if that produces overall better code.
44018334Speter   Optional now, so people can test it.  */
44118334Speter
44218334Speter#ifdef DEFAULT_CALLER_SAVES
44318334Speterint flag_caller_saves = 1;
44418334Speter#else
44518334Speterint flag_caller_saves = 0;
44618334Speter#endif
44718334Speter
44818334Speter/* Nonzero if structures and unions should be returned in memory.
44918334Speter
45018334Speter   This should only be defined if compatibility with another compiler or
45118334Speter   with an ABI is needed, because it results in slower code.  */
45218334Speter
45318334Speter#ifndef DEFAULT_PCC_STRUCT_RETURN
45418334Speter#define DEFAULT_PCC_STRUCT_RETURN 1
45518334Speter#endif
45618334Speter
45718334Speter/* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */
45818334Speter
45918334Speterint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
46018334Speter
46118334Speter/* Nonzero for -fforce-mem: load memory value into a register
46218334Speter   before arithmetic on it.  This makes better cse but slower compilation.  */
46318334Speter
46418334Speterint flag_force_mem = 0;
46518334Speter
46618334Speter/* Nonzero for -fforce-addr: load memory address into a register before
46718334Speter   reference to memory.  This makes better cse but slower compilation.  */
46818334Speter
46918334Speterint flag_force_addr = 0;
47018334Speter
47118334Speter/* Nonzero for -fdefer-pop: don't pop args after each function call;
47218334Speter   instead save them up to pop many calls' args with one insns.  */
47318334Speter
47418334Speterint flag_defer_pop = 0;
47518334Speter
47618334Speter/* Nonzero for -ffloat-store: don't allocate floats and doubles
47718334Speter   in extended-precision registers.  */
47818334Speter
47918334Speterint flag_float_store = 0;
48018334Speter
48118334Speter/* Nonzero for -fcse-follow-jumps:
48218334Speter   have cse follow jumps to do a more extensive job.  */
48318334Speter
48418334Speterint flag_cse_follow_jumps;
48518334Speter
48618334Speter/* Nonzero for -fcse-skip-blocks:
48718334Speter   have cse follow a branch around a block.  */
48818334Speterint flag_cse_skip_blocks;
48918334Speter
49018334Speter/* Nonzero for -fexpensive-optimizations:
49118334Speter   perform miscellaneous relatively-expensive optimizations.  */
49218334Speterint flag_expensive_optimizations;
49318334Speter
49418334Speter/* Nonzero for -fthread-jumps:
49518334Speter   have jump optimize output of loop.  */
49618334Speter
49718334Speterint flag_thread_jumps;
49818334Speter
49918334Speter/* Nonzero enables strength-reduction in loop.c.  */
50018334Speter
50118334Speterint flag_strength_reduce = 0;
50218334Speter
50318334Speter/* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
50418334Speter   number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
50518334Speter   UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
50618334Speter   unrolled.  */
50718334Speter
50818334Speterint flag_unroll_loops;
50918334Speter
51018334Speter/* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
51118334Speter   This is generally not a win.  */
51218334Speter
51318334Speterint flag_unroll_all_loops;
51418334Speter
51550615Sobrien/* Nonzero forces all invariant computations in loops to be moved
51650615Sobrien   outside the loop. */
51750615Sobrien
51850615Sobrienint flag_move_all_movables = 0;
51950615Sobrien
52050615Sobrien/* Nonzero forces all general induction variables in loops to be
52150615Sobrien   strength reduced. */
52250615Sobrien
52350615Sobrienint flag_reduce_all_givs = 0;
52450615Sobrien
52550615Sobrien/* Nonzero to perform full register move optimization passes.  This is the
52650615Sobrien   default for -O2.  */
52750615Sobrien
52850615Sobrienint flag_regmove = 0;
52950615Sobrien
53018334Speter/* Nonzero for -fwritable-strings:
53118334Speter   store string constants in data segment and don't uniquize them.  */
53218334Speter
53318334Speterint flag_writable_strings = 0;
53418334Speter
53518334Speter/* Nonzero means don't put addresses of constant functions in registers.
53618334Speter   Used for compiling the Unix kernel, where strange substitutions are
53718334Speter   done on the assembly output.  */
53818334Speter
53918334Speterint flag_no_function_cse = 0;
54018334Speter
54118334Speter/* Nonzero for -fomit-frame-pointer:
54218334Speter   don't make a frame pointer in simple functions that don't require one.  */
54318334Speter
54418334Speterint flag_omit_frame_pointer = 0;
54518334Speter
54650615Sobrien/* Nonzero means place each function into its own section on those platforms
54750615Sobrien   which support arbitrary section names and unlimited numbers of sections.  */
54850615Sobrien
54950615Sobrienint flag_function_sections = 0;
55050615Sobrien
55152558Sobrien/* ... and similar for data.  */
55252558Sobrien
55352558Sobrienint flag_data_sections = 0;
55452558Sobrien
55518334Speter/* Nonzero to inhibit use of define_optimization peephole opts.  */
55618334Speter
55718334Speterint flag_no_peephole = 0;
55818334Speter
55918334Speter/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
56018334Speter   operations in the interest of optimization.  For example it allows
56118334Speter   GCC to assume arguments to sqrt are nonnegative numbers, allowing
56250615Sobrien   faster code for sqrt to be generated.  */
56318334Speter
56418334Speterint flag_fast_math = 0;
56518334Speter
56652558Sobrien/* Nonzero means the front end generally wants `errno' maintained by math
56752558Sobrien   operations, like built-in SQRT, unless overridden by flag_fast_math.  */
56852558Sobrien
56952558Sobrienint flag_errno_math = 1;
57052558Sobrien
57152558Sobrien/* 0 means straightforward implementation of complex divide acceptable.
57252558Sobrien   1 means wide ranges of inputs must work for complex divide.
57352558Sobrien   2 means C9X-like requirements for complex divide (not yet implemented).  */
57452558Sobrien
57552558Sobrienint flag_complex_divide_method = 0;
57652558Sobrien
57718334Speter/* Nonzero means all references through pointers are volatile.  */
57818334Speter
57918334Speterint flag_volatile;
58018334Speter
58152558Sobrien/* Nonzero means treat all global and extern variables as volatile.  */
58218334Speter
58318334Speterint flag_volatile_global;
58418334Speter
58552558Sobrien/* Nonzero means treat all static variables as volatile.  */
58652558Sobrien
58752558Sobrienint flag_volatile_static;
58852558Sobrien
58918334Speter/* Nonzero means just do syntax checking; don't output anything.  */
59018334Speter
59118334Speterint flag_syntax_only = 0;
59218334Speter
59350615Sobrien/* Nonzero means perform global cse.  */
59450615Sobrien
59550615Sobrienstatic int flag_gcse;
59650615Sobrien
59718334Speter/* Nonzero means to rerun cse after loop optimization.  This increases
59818334Speter   compilation time about 20% and picks up a few more common expressions.  */
59918334Speter
60018334Speterstatic int flag_rerun_cse_after_loop;
60118334Speter
60250615Sobrien/* Nonzero means to run loop optimizations twice.  */
60350615Sobrien
60450615Sobrienint flag_rerun_loop_opt;
60550615Sobrien
60618334Speter/* Nonzero for -finline-functions: ok to inline functions that look like
60718334Speter   good inline candidates.  */
60818334Speter
60918334Speterint flag_inline_functions;
61018334Speter
61118334Speter/* Nonzero for -fkeep-inline-functions: even if we make a function
61218334Speter   go inline everywhere, keep its definition around for debugging
61318334Speter   purposes.  */
61418334Speter
61518334Speterint flag_keep_inline_functions;
61618334Speter
61718334Speter/* Nonzero means that functions will not be inlined.  */
61818334Speter
61918334Speterint flag_no_inline;
62018334Speter
62150615Sobrien/* Nonzero means that we should emit static const variables
62250615Sobrien   regardless of whether or not optimization is turned on.  */
62350615Sobrien
62450615Sobrienint flag_keep_static_consts = 1;
62550615Sobrien
62618334Speter/* Nonzero means we should be saving declaration info into a .X file.  */
62718334Speter
62818334Speterint flag_gen_aux_info = 0;
62918334Speter
63018334Speter/* Specified name of aux-info file.  */
63118334Speter
63218334Speterstatic char *aux_info_file_name;
63318334Speter
63418334Speter/* Nonzero means make the text shared if supported.  */
63518334Speter
63618334Speterint flag_shared_data;
63718334Speter
63818334Speter/* Nonzero means schedule into delayed branch slots if supported.  */
63918334Speter
64018334Speterint flag_delayed_branch;
64118334Speter
64218334Speter/* Nonzero if we are compiling pure (sharable) code.
64318334Speter   Value is 1 if we are doing reasonable (i.e. simple
64418334Speter   offset into offset table) pic.  Value is 2 if we can
64518334Speter   only perform register offsets.  */
64618334Speter
64718334Speterint flag_pic;
64818334Speter
64950615Sobrien/* Nonzero means generate extra code for exception handling and enable
65050615Sobrien   exception handling.  */
65118334Speter
65250615Sobrienint flag_exceptions;
65350615Sobrien
65450615Sobrien/* Nonzero means use the new model for exception handling. Replaces
65550615Sobrien   -DNEW_EH_MODEL as a compile option. */
65650615Sobrien
65750615Sobrienint flag_new_exceptions = 0;
65850615Sobrien
65950615Sobrien/* Nonzero means don't place uninitialized global data in common storage
66050615Sobrien   by default.  */
66150615Sobrien
66218334Speterint flag_no_common;
66318334Speter
66418334Speter/* Nonzero means pretend it is OK to examine bits of target floats,
66518334Speter   even if that isn't true.  The resulting code will have incorrect constants,
66618334Speter   but the same series of instructions that the native compiler would make.  */
66718334Speter
66818334Speterint flag_pretend_float;
66918334Speter
67018334Speter/* Nonzero means change certain warnings into errors.
67118334Speter   Usually these are warnings about failure to conform to some standard.  */
67218334Speter
67318334Speterint flag_pedantic_errors = 0;
67418334Speter
67518334Speter/* flag_schedule_insns means schedule insns within basic blocks (before
67618334Speter   local_alloc).
67718334Speter   flag_schedule_insns_after_reload means schedule insns after
67818334Speter   global_alloc.  */
67918334Speter
68018334Speterint flag_schedule_insns = 0;
68118334Speterint flag_schedule_insns_after_reload = 0;
68218334Speter
68350615Sobrien#ifdef HAIFA
68450615Sobrien/* The following flags have effect only for scheduling before register
68550615Sobrien   allocation:
68650615Sobrien
68750615Sobrien   flag_schedule_interblock means schedule insns accross basic blocks.
68850615Sobrien   flag_schedule_speculative means allow speculative motion of non-load insns.
68950615Sobrien   flag_schedule_speculative_load means allow speculative motion of some
69050615Sobrien   load insns.
69150615Sobrien   flag_schedule_speculative_load_dangerous allows speculative motion of more
69250615Sobrien   load insns.  */
69350615Sobrien
69450615Sobrienint flag_schedule_interblock = 1;
69550615Sobrienint flag_schedule_speculative = 1;
69650615Sobrienint flag_schedule_speculative_load = 0;
69750615Sobrienint flag_schedule_speculative_load_dangerous = 0;
69852558Sobrien#endif  /* HAIFA */
69950615Sobrien
70050615Sobrien/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
70150615Sobrien   by a cheaper branch, on a count register. */
70250615Sobrienint flag_branch_on_count_reg;
70350615Sobrien
70418334Speter/* -finhibit-size-directive inhibits output of .size for ELF.
70518334Speter   This is used only for compiling crtstuff.c,
70618334Speter   and it may be extended to other effects
70718334Speter   needed for crtstuff.c on other systems.  */
70818334Speterint flag_inhibit_size_directive = 0;
70918334Speter
71018334Speter/* -fverbose-asm causes extra commentary information to be produced in
71118334Speter   the generated assembly code (to make it more readable).  This option
71218334Speter   is generally only of use to those who actually need to read the
71350615Sobrien   generated assembly code (perhaps while debugging the compiler itself).
71450615Sobrien   -fno-verbose-asm, the default, causes the extra information
71550615Sobrien   to be omitted and is useful when comparing two assembler files.  */
71618334Speter
71718334Speterint flag_verbose_asm = 0;
71818334Speter
71950615Sobrien/* -dA causes debug commentary information to be produced in
72050615Sobrien   the generated assembly code (to make it more readable).  This option
72150615Sobrien   is generally only of use to those who actually need to read the
72250615Sobrien   generated assembly code (perhaps while debugging the compiler itself).
72350615Sobrien   Currently, this switch is only used by dwarfout.c; however, it is intended
72450615Sobrien   to be a catchall for printing debug information in the assembler file.  */
72550615Sobrien
72650615Sobrienint flag_debug_asm = 0;
72750615Sobrien
72818334Speter/* -fgnu-linker specifies use of the GNU linker for initializations.
72918334Speter   (Or, more generally, a linker that handles initializations.)
73018334Speter   -fno-gnu-linker says that collect2 will be used.  */
73118334Speter#ifdef USE_COLLECT2
73218334Speterint flag_gnu_linker = 0;
73318334Speter#else
73418334Speterint flag_gnu_linker = 1;
73518334Speter#endif
73618334Speter
73718334Speter/* Tag all structures with __attribute__(packed) */
73818334Speterint flag_pack_struct = 0;
73918334Speter
74038510Sbde/* Nonzero means that -Wformat accepts certain system-dependent formats.  */
74138510Sbdeint flag_format_extensions = 0;
74238510Sbde
74350615Sobrien/* Emit code to check for stack overflow; also may cause large objects
74450615Sobrien   to be allocated dynamically.  */
74550615Sobrienint flag_stack_check;
74650615Sobrien
74750615Sobrien/* -fcheck-memory-usage causes extra code to be generated in order to check
74850615Sobrien   memory accesses.  This is used by a detector of bad memory accesses such
74950615Sobrien   as Checker.  */
75050615Sobrienint flag_check_memory_usage = 0;
75150615Sobrien
75250615Sobrien/* -fprefix-function-name causes function name to be prefixed.  This
75350615Sobrien   can be used with -fcheck-memory-usage to isolate code compiled with
75450615Sobrien   -fcheck-memory-usage.  */
75550615Sobrienint flag_prefix_function_name = 0;
75650615Sobrien
75750615Sobrien/* 0 if pointer arguments may alias each other.  True in C.
75850615Sobrien   1 if pointer arguments may not alias each other but may alias
75950615Sobrien   global variables.
76050615Sobrien   2 if pointer arguments may not alias each other and may not
76150615Sobrien   alias global variables.  True in Fortran.
76250615Sobrien   This defaults to 0 for C.  */
76350615Sobrienint flag_argument_noalias = 0;
76450615Sobrien
76550615Sobrien/* Nonzero if we should do (language-dependent) alias analysis.
76650615Sobrien   Typically, this analysis will assume that expressions of certain
76750615Sobrien   types do not alias expressions of certain other types.  Only used
76850615Sobrien   if alias analysis (in general) is enabled.  */
76950615Sobrienint flag_strict_aliasing = 0;
77050615Sobrien
77152558Sobrien/* Instrument functions with calls at entry and exit, for profiling.  */
77252558Sobrienint flag_instrument_function_entry_exit = 0;
77350615Sobrien
77452558Sobrien/* Nonzero means ignore `#ident' directives.  0 means handle them.
77552558Sobrien   On SVR4 targets, it also controls whether or not to emit a
77652558Sobrien   string identifying the compiler.  */
77750615Sobrien
77852558Sobrienint flag_no_ident = 0;
77952558Sobrien
78050615Sobrien/* Table of supported debugging formats.  */
78150615Sobrienstatic struct
78250615Sobrien{
78352558Sobrien  const char * arg;
78450615Sobrien  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
78550615Sobrien     constant expression, we use NO_DEBUG in its place.  */
78650615Sobrien  enum debug_info_type debug_type;
78750615Sobrien  int use_extensions_p;
78852558Sobrien  const char * description;
78950615Sobrien} *da,
79050615Sobriendebug_args[] =
79150615Sobrien{
79250615Sobrien  { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
79350615Sobrien    "Generate default debug format output" },
79450615Sobrien  { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
79550615Sobrien#ifdef DBX_DEBUGGING_INFO
79650615Sobrien  { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
79750615Sobrien  { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
79850615Sobrien#endif
79950615Sobrien#ifdef DWARF_DEBUGGING_INFO
80050615Sobrien  { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
80150615Sobrien  { "gdwarf+", DWARF_DEBUG, 1,
80250615Sobrien    "Generated extended DWARF-1 format debug output" },
80350615Sobrien#endif
80450615Sobrien#ifdef DWARF2_DEBUGGING_INFO
80550615Sobrien  { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
80650615Sobrien#endif
80750615Sobrien#ifdef XCOFF_DEBUGGING_INFO
80850615Sobrien  { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
80950615Sobrien  { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
81050615Sobrien#endif
81150615Sobrien#ifdef SDB_DEBUGGING_INFO
81250615Sobrien  { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
81350615Sobrien#endif
81452558Sobrien  { 0, 0, 0, 0 }
81550615Sobrien};
81650615Sobrien
81750615Sobrientypedef struct
81850615Sobrien{
81952558Sobrien  const char * string;
82050615Sobrien  int *  variable;
82150615Sobrien  int    on_value;
82252558Sobrien  const char * description;
82350615Sobrien}
82450615Sobrienlang_independent_options;
82550615Sobrien
82652558Sobrien/* Add or remove a leading underscore from user symbols.  */
82752558Sobrienint flag_leading_underscore = -1;
82852558Sobrien
82952558Sobrien/* The user symbol prefix after having resolved same.  */
83052558Sobrienconst char *user_label_prefix;
83152558Sobrien
83252558Sobrien/* A default for same.  */
83352558Sobrien#ifndef USER_LABEL_PREFIX
83452558Sobrien#define USER_LABEL_PREFIX ""
83552558Sobrien#endif
83652558Sobrien
83718334Speter/* Table of language-independent -f options.
83818334Speter   STRING is the option name.  VARIABLE is the address of the variable.
83918334Speter   ON_VALUE is the value to store in VARIABLE
84018334Speter    if `-fSTRING' is seen as an option.
84118334Speter   (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
84218334Speter
84350615Sobrienlang_independent_options f_options[] =
84418334Speter{
84550615Sobrien  {"float-store", &flag_float_store, 1,
84650615Sobrien   "Do not store floats in registers" },
84750615Sobrien  {"volatile", &flag_volatile, 1,
84850615Sobrien   "Consider all mem refs through pointers as volatile"},
84950615Sobrien  {"volatile-global", &flag_volatile_global, 1,
85050615Sobrien   "Consider all mem refs to global data to be volatile" },
85152558Sobrien  {"volatile-static", &flag_volatile_static, 1,
85252558Sobrien   "Consider all mem refs to static data to be volatile" },
85350615Sobrien  {"defer-pop", &flag_defer_pop, 1,
85450615Sobrien   "Defer popping functions args from stack until later" },
85550615Sobrien  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
85650615Sobrien   "When possible do not generate stack frames"},
85750615Sobrien  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
85850615Sobrien   "When running CSE, follow jumps to their targets" },
85950615Sobrien  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
86050615Sobrien   "When running CSE, follow conditional jumps" },
86150615Sobrien  {"expensive-optimizations", &flag_expensive_optimizations, 1,
86250615Sobrien   "Perform a number of minor, expensive optimisations" },
86350615Sobrien  {"thread-jumps", &flag_thread_jumps, 1,
86450615Sobrien   "Perform jump threading optimisations"},
86550615Sobrien  {"strength-reduce", &flag_strength_reduce, 1,
86650615Sobrien   "Perform strength reduction optimisations" },
86750615Sobrien  {"unroll-loops", &flag_unroll_loops, 1,
86852558Sobrien   "Perform loop unrolling when iteration count is known" },
86950615Sobrien  {"unroll-all-loops", &flag_unroll_all_loops, 1,
87052558Sobrien   "Perform loop unrolling for all loops" },
87150615Sobrien  {"move-all-movables", &flag_move_all_movables, 1,
87250615Sobrien   "Force all loop invariant computations out of loops" },
87350615Sobrien  {"reduce-all-givs", &flag_reduce_all_givs, 1,
87450615Sobrien   "Strength reduce all loop general induction variables" },
87550615Sobrien  {"writable-strings", &flag_writable_strings, 1,
87650615Sobrien   "Store strings in writable data section" },
87750615Sobrien  {"peephole", &flag_no_peephole, 0,
87850615Sobrien   "Enable machine specific peephole optimisations" },
87950615Sobrien  {"force-mem", &flag_force_mem, 1,
88050615Sobrien   "Copy memory operands into registers before using" },
88150615Sobrien  {"force-addr", &flag_force_addr, 1,
88250615Sobrien   "Copy memory address constants into regs before using" },
88350615Sobrien  {"function-cse", &flag_no_function_cse, 0,
88450615Sobrien   "Allow function addresses to be held in registers" },
88550615Sobrien  {"inline-functions", &flag_inline_functions, 1,
88650615Sobrien   "Integrate simple functions into their callers" },
88750615Sobrien  {"keep-inline-functions", &flag_keep_inline_functions, 1,
88850615Sobrien   "Generate code for funcs even if they are fully inlined" },
88950615Sobrien  {"inline", &flag_no_inline, 0,
89050615Sobrien   "Pay attention to the 'inline' keyword"},
89150615Sobrien  {"keep-static-consts", &flag_keep_static_consts, 1,
89250615Sobrien   "Emit static const variables even if they are not used" },
89350615Sobrien  {"syntax-only", &flag_syntax_only, 1,
89450615Sobrien   "Check for syntax errors, then stop" },
89550615Sobrien  {"shared-data", &flag_shared_data, 1,
89650615Sobrien   "Mark data as shared rather than private" },
89750615Sobrien  {"caller-saves", &flag_caller_saves, 1,
89850615Sobrien   "Enable saving registers around function calls" },
89950615Sobrien  {"pcc-struct-return", &flag_pcc_struct_return, 1,
90050615Sobrien   "Return 'short' aggregates in memory, not registers" },
90150615Sobrien  {"reg-struct-return", &flag_pcc_struct_return, 0,
90250615Sobrien   "Return 'short' aggregates in registers" },
90350615Sobrien  {"delayed-branch", &flag_delayed_branch, 1,
90450615Sobrien   "Attempt to fill delay slots of branch instructions" },
90550615Sobrien  {"gcse", &flag_gcse, 1,
90650615Sobrien   "Perform the global common subexpression elimination" },
90750615Sobrien  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
90850615Sobrien   "Run CSE pass after loop optimisations"},
90950615Sobrien  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
91050615Sobrien   "Run the loop optimiser twice"},
91150615Sobrien  {"pretend-float", &flag_pretend_float, 1,
91250615Sobrien   "Pretend that host and target use the same FP format"},
91350615Sobrien  {"schedule-insns", &flag_schedule_insns, 1,
91450615Sobrien   "Reschedule instructions to avoid pipeline stalls"},
91550615Sobrien  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
91650615Sobrien  "Run two passes of the instruction scheduler"},
91750615Sobrien#ifdef HAIFA
91850615Sobrien  {"sched-interblock",&flag_schedule_interblock, 1,
91950615Sobrien   "Enable scheduling across basic blocks" },
92050615Sobrien  {"sched-spec",&flag_schedule_speculative, 1,
92150615Sobrien   "Allow speculative motion of non-loads" },
92250615Sobrien  {"sched-spec-load",&flag_schedule_speculative_load, 1,
92350615Sobrien   "Allow speculative motion of some loads" },
92450615Sobrien  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
92550615Sobrien   "Allow speculative motion of more loads" },
92652558Sobrien#endif  /* HAIFA */
92750615Sobrien  {"branch-count-reg",&flag_branch_on_count_reg, 1,
92850615Sobrien   "Replace add,compare,branch with branch on count reg"},
92950615Sobrien  {"pic", &flag_pic, 1,
93050615Sobrien   "Generate position independent code, if possible"},
93150615Sobrien  {"PIC", &flag_pic, 2, ""},
93250615Sobrien  {"exceptions", &flag_exceptions, 1,
93350615Sobrien   "Enable exception handling" },
93450615Sobrien  {"new-exceptions", &flag_new_exceptions, 1,
93550615Sobrien   "Use the new model for exception handling" },
93650615Sobrien  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
93750615Sobrien   "Use setjmp/longjmp to handle exceptions" },
93850615Sobrien  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
93950615Sobrien   "Support asynchronous exceptions" },
94050615Sobrien  {"profile-arcs", &profile_arc_flag, 1,
94150615Sobrien   "Insert arc based program profiling code" },
94250615Sobrien  {"test-coverage", &flag_test_coverage, 1,
94350615Sobrien   "Create data files needed by gcov" },
94450615Sobrien  {"branch-probabilities", &flag_branch_probabilities, 1,
94552558Sobrien   "Use profiling information for branch probabilities" },
94650615Sobrien  {"fast-math", &flag_fast_math, 1,
94750615Sobrien   "Improve FP speed by violating ANSI & IEEE rules" },
94850615Sobrien  {"common", &flag_no_common, 0,
94950615Sobrien   "Do not put unitialised globals in the common section" },
95050615Sobrien  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
95150615Sobrien   "Do not generate .size directives" },
95250615Sobrien  {"function-sections", &flag_function_sections, 1,
95350615Sobrien   "place each function into its own section" },
95452558Sobrien  {"data-sections", &flag_data_sections, 1,
95552558Sobrien   "place data items into their own section" },
95650615Sobrien  {"verbose-asm", &flag_verbose_asm, 1,
95750615Sobrien   "Add extra commentry to assembler output"},
95850615Sobrien  {"gnu-linker", &flag_gnu_linker, 1,
95950615Sobrien   "Output GNU ld formatted global initialisers"},
96050615Sobrien  {"regmove", &flag_regmove, 1,
96152558Sobrien   "Enables a register move optimisation"},
96252558Sobrien  {"optimize-register-move", &flag_regmove, 1,
96352558Sobrien   "Do the full regmove optimization pass"},
96450615Sobrien  {"pack-struct", &flag_pack_struct, 1,
96550615Sobrien   "Pack structure members together without holes" },
96650615Sobrien  {"format-extensions", &flag_format_extensions, 1,
96750615Sobrien   "-Wformat accepts certain FreeBSD system-dependent formats" },
96850615Sobrien  {"stack-check", &flag_stack_check, 1,
96950615Sobrien   "Insert stack checking code into the program" },
97050615Sobrien  {"argument-alias", &flag_argument_noalias, 0,
97150615Sobrien   "Specify that arguments may alias each other & globals"},
97250615Sobrien  {"argument-noalias", &flag_argument_noalias, 1,
97350615Sobrien   "Assume arguments may alias globals but not each other"},
97450615Sobrien  {"argument-noalias-global", &flag_argument_noalias, 2,
97550615Sobrien   "Assume arguments do not alias each other or globals" },
97650615Sobrien  {"strict-aliasing", &flag_strict_aliasing, 1,
97750615Sobrien   "Assume strict aliasing rules apply" },
97850615Sobrien  {"check-memory-usage", &flag_check_memory_usage, 1,
97950615Sobrien   "Generate code to check every memory access" },
98050615Sobrien  {"prefix-function-name", &flag_prefix_function_name, 1,
98150615Sobrien   "Add a prefix to all function names" },
98252558Sobrien  {"dump-unnumbered", &flag_dump_unnumbered, 1,
98352558Sobrien   "Suppress output of instruction numbers and line number notes in debugging dumps"},
98452558Sobrien  {"instrument-functions", &flag_instrument_function_entry_exit, 1,
98552558Sobrien   "Instrument function entry/exit with profiling calls"},
98652558Sobrien  {"leading-underscore", &flag_leading_underscore, 1,
98752558Sobrien   "External symbols have a leading underscore" },
98852558Sobrien  {"ident", &flag_no_ident, 0,
98952558Sobrien   "Process #ident directives"}
99018334Speter};
99118334Speter
99250615Sobrien#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
99350615Sobrien
99418334Speter/* Table of language-specific options.  */
99518334Speter
99650615Sobrienstatic struct lang_opt
99718334Speter{
99852558Sobrien  const char * option;
99952558Sobrien  const char * description;
100050615Sobrien}
100150615Sobriendocumented_lang_options[] =
100250615Sobrien{
100350615Sobrien  /* In order not to overload the --help output, the convention
100450615Sobrien     used here is to only describe those options which are not
100550615Sobrien     enabled by default.  */
100618334Speter
100750615Sobrien  { "-ansi", "Compile just for ANSI C" },
100850615Sobrien  { "-fallow-single-precision",
100950615Sobrien    "Do not promote floats to double if using -traditional" },
101052558Sobrien  { "-std= ", "Determine language standard"},
101118334Speter
101250615Sobrien  { "-fsigned-bitfields", "" },
101350615Sobrien  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
101450615Sobrien  { "-fno-signed-bitfields", "" },
101550615Sobrien  { "-fno-unsigned-bitfields","" },
101650615Sobrien  { "-fsigned-char", "Make 'char' be signed by default"},
101750615Sobrien  { "-funsigned-char", "Make 'char' be unsigned by default"},
101850615Sobrien  { "-fno-signed-char", "" },
101950615Sobrien  { "-fno-unsigned-char", "" },
102018334Speter
102150615Sobrien  { "-ftraditional", "" },
102250615Sobrien  { "-traditional", "Attempt to support traditional K&R style C"},
102350615Sobrien  { "-fnotraditional", "" },
102450615Sobrien  { "-fno-traditional", "" },
102518334Speter
102650615Sobrien  { "-fasm", "" },
102750615Sobrien  { "-fno-asm", "Do not recognise the 'asm' keyword" },
102850615Sobrien  { "-fbuiltin", "" },
102950615Sobrien  { "-fno-builtin", "Do not recognise any built in functions" },
103050615Sobrien  { "-fhosted", "Assume normal C execution environment" },
103150615Sobrien  { "-fno-hosted", "" },
103250615Sobrien  { "-ffreestanding",
103350615Sobrien    "Assume that standard libraries & main might not exist" },
103450615Sobrien  { "-fno-freestanding", "" },
103550615Sobrien  { "-fcond-mismatch", "Allow different types as args of ? operator"},
103650615Sobrien  { "-fno-cond-mismatch", "" },
103752558Sobrien  { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
103850615Sobrien  { "-fno-dollars-in-identifiers", "" },
103950615Sobrien  { "-fshort-double", "Use the same size for double as for float" },
104050615Sobrien  { "-fno-short-double", "" },
104150615Sobrien  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
104250615Sobrien  { "-fno-short-enums", "" },
104318334Speter
104450615Sobrien  { "-Wall", "Enable most warning messages" },
104550615Sobrien  { "-Wbad-function-cast",
104650615Sobrien    "Warn about casting functions to incompatible types" },
104750615Sobrien  { "-Wno-bad-function-cast", "" },
104852558Sobrien  { "-Wmissing-noreturn",
104952558Sobrien    "Warn about functions which might be candidates for attribute noreturn" },
105052558Sobrien  { "-Wno-missing-noreturn", "" },
105150615Sobrien  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
105250615Sobrien  { "-Wno-cast-qual", "" },
105352558Sobrien  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
105450615Sobrien  { "-Wno-char-subscripts", "" },
105550615Sobrien  { "-Wcomment", "Warn if nested comments are detected" },
105652558Sobrien  { "-Wno-comment", "" },
105752558Sobrien  { "-Wcomments", "Warn if nested comments are detected" },
105852558Sobrien  { "-Wno-comments", "" },
105950615Sobrien  { "-Wconversion", "Warn about possibly confusing type conversions" },
106050615Sobrien  { "-Wno-conversion", "" },
106150615Sobrien  { "-Wformat", "Warn about printf format anomalies" },
106250615Sobrien  { "-Wno-format", "" },
106350615Sobrien  { "-Wimplicit-function-declaration",
106450615Sobrien    "Warn about implicit function declarations" },
106550615Sobrien  { "-Wno-implicit-function-declaration", "" },
106650615Sobrien  { "-Werror-implicit-function-declaration", "" },
106750615Sobrien  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
106850615Sobrien  { "-Wno-implicit-int", "" },
106950615Sobrien  { "-Wimplicit", "" },
107050615Sobrien  { "-Wno-implicit", "" },
107150615Sobrien  { "-Wimport", "Warn about the use of the #import directive" },
107250615Sobrien  { "-Wno-import", "" },
107350615Sobrien  { "-Wlong-long","" },
107450615Sobrien  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
107550615Sobrien  { "-Wmain", "Warn about suspicious declarations of main" },
107650615Sobrien  { "-Wno-main", "" },
107750615Sobrien  { "-Wmissing-braces",
107850615Sobrien    "Warn about possibly missing braces around initialisers" },
107950615Sobrien  { "-Wno-missing-braces", "" },
108050615Sobrien  { "-Wmissing-declarations",
108150615Sobrien    "Warn about global funcs without previous declarations"},
108250615Sobrien  { "-Wno-missing-declarations", "" },
108350615Sobrien  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
108450615Sobrien  { "-Wno-missing-prototypes", "" },
108550615Sobrien  { "-Wmultichar", "Warn about use of multicharacter literals"},
108650615Sobrien  { "-Wno-multichar", "" },
108750615Sobrien  { "-Wnested-externs", "Warn about externs not at file scope level" },
108850615Sobrien  { "-Wno-nested-externs", "" },
108950615Sobrien  { "-Wparentheses", "Warn about possible missing parentheses" },
109050615Sobrien  { "-Wno-parentheses", "" },
109150615Sobrien  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
109250615Sobrien  { "-Wno-pointer-arith", "" },
109350615Sobrien  { "-Wredundant-decls",
109450615Sobrien    "Warn about multiple declarations of the same object" },
109550615Sobrien  { "-Wno-redundant-decls", "" },
109650615Sobrien  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
109750615Sobrien  { "-Wno-sign-compare", "" },
109850615Sobrien  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
109950615Sobrien  { "-Wno-unknown-pragmas", "" },
110050615Sobrien  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
110150615Sobrien  { "-Wno-strict-prototypes", "" },
110252558Sobrien  { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
110350615Sobrien  { "-Wno-traditional", "" },
110450615Sobrien  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
110550615Sobrien  { "-Wno-trigraphs", "" },
110650615Sobrien  { "-Wundef", "" },
110750615Sobrien  { "-Wno-undef", "" },
110850615Sobrien  { "-Wwrite-strings", "Mark strings as 'const char *'"},
110950615Sobrien  { "-Wno-write-strings", "" },
111018334Speter
111150615Sobrien  /* These are for languages with USE_CPPLIB.  */
111250615Sobrien  /* These options are already documented in cpplib.c */
111350615Sobrien  { "--help", "" },
111450615Sobrien  { "-A", "" },
111550615Sobrien  { "-D", "" },
111650615Sobrien  { "-I", "" },
111752558Sobrien#if USE_CPPLIB
111852558Sobrien  { "-MD", "Print dependencies to FILE.d" },
111952558Sobrien  { "-MMD", "Print dependencies to FILE.d" },
112052558Sobrien  { "-M", "Print dependencies to stdout" },
112152558Sobrien  { "-MM", "Print dependencies to stdout" },
112252558Sobrien#endif /* USE_CPPLIB */
112350615Sobrien  { "-U", "" },
112452558Sobrien  { "-H", "" },
112550615Sobrien  { "-idirafter", "" },
112652558Sobrien  { "-imacros", "" },
112752558Sobrien  { "-include", "" },
112850615Sobrien  { "-iprefix", "" },
112950615Sobrien  { "-isystem", "" },
113052558Sobrien  { "-iwithprefix", "" },
113152558Sobrien  { "-iwithprefixbefore", "" },
113250615Sobrien  { "-lang-c", "" },
113350615Sobrien  { "-lang-c89", "" },
113450615Sobrien  { "-lang-c++", "" },
113552558Sobrien  { "-remap", "" },
113650615Sobrien  { "-nostdinc", "" },
113750615Sobrien  { "-nostdinc++", "" },
113850615Sobrien  { "-trigraphs", "" },
113950615Sobrien  { "-undef", "" },
114050615Sobrien
114150615Sobrien#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
114250615Sobrien
114350615Sobrien  /* These are for obj c.  */
114450615Sobrien  DEFINE_LANG_NAME ("Objective C")
114550615Sobrien
114650615Sobrien  { "-lang-objc", "" },
114750615Sobrien  { "-gen-decls", "Dump decls to a .decl file" },
114852558Sobrien  { "-fgnu-runtime", "Generate code for GNU runtime environment" },
114950615Sobrien  { "-fno-gnu-runtime", "" },
115050615Sobrien  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
115150615Sobrien  { "-fno-next-runtime", "" },
115250615Sobrien  { "-Wselector", "Warn if a selector has multiple methods" },
115350615Sobrien  { "-Wno-selector", "" },
115450615Sobrien  { "-Wprotocol", "" },
115550615Sobrien  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
115650615Sobrien  { "-print-objc-runtime-info",
115750615Sobrien    "Generate C header of platform specific features" },
115850615Sobrien
115918334Speter#include "options.h"
116050615Sobrien
116118334Speter};
116250615Sobrien
116350615Sobrien/* Here is a table, controlled by the tm.h file, listing each -m switch
116450615Sobrien   and which bits in `target_switches' it should set or clear.
116550615Sobrien   If VALUE is positive, it is bits to set.
116650615Sobrien   If VALUE is negative, -VALUE is bits to clear.
116750615Sobrien   (The sign bit is not used so there is no confusion.)  */
116850615Sobrien
116950615Sobrienstruct
117050615Sobrien{
117152558Sobrien  const char * name;
117250615Sobrien  int    value;
117352558Sobrien  const char * description;
117450615Sobrien}
117550615Sobrientarget_switches [] = TARGET_SWITCHES;
117650615Sobrien
117750615Sobrien/* This table is similar, but allows the switch to have a value.  */
117850615Sobrien
117950615Sobrien#ifdef TARGET_OPTIONS
118050615Sobrienstruct
118150615Sobrien{
118252558Sobrien  const char *  prefix;
118352558Sobrien  const char ** variable;
118452558Sobrien  const char *  description;
118550615Sobrien}
118650615Sobrientarget_options [] = TARGET_OPTIONS;
118750615Sobrien#endif
118818334Speter
118918334Speter/* Options controlling warnings */
119018334Speter
119118334Speter/* Don't print warning messages.  -w.  */
119218334Speter
119318334Speterint inhibit_warnings = 0;
119418334Speter
119518334Speter/* Print various extra warnings.  -W.  */
119618334Speter
119718334Speterint extra_warnings = 0;
119818334Speter
119918334Speter/* Treat warnings as errors.  -Werror.  */
120018334Speter
120118334Speterint warnings_are_errors = 0;
120218334Speter
120318334Speter/* Nonzero to warn about unused local variables.  */
120418334Speter
120518334Speterint warn_unused;
120618334Speter
120718334Speter/* Nonzero to warn about variables used before they are initialized.  */
120818334Speter
120918334Speterint warn_uninitialized;
121018334Speter
121118334Speter/* Nonzero means warn about all declarations which shadow others.   */
121218334Speter
121318334Speterint warn_shadow;
121418334Speter
121518334Speter/* Warn if a switch on an enum fails to have a case for every enum value.  */
121618334Speter
121718334Speterint warn_switch;
121818334Speter
121918334Speter/* Nonzero means warn about function definitions that default the return type
122018334Speter   or that use a null return and have a return-type other than void.  */
122118334Speter
122218334Speterint warn_return_type;
122318334Speter
122418334Speter/* Nonzero means warn about pointer casts that increase the required
122518334Speter   alignment of the target type (and might therefore lead to a crash
122618334Speter   due to a misaligned access).  */
122718334Speter
122818334Speterint warn_cast_align;
122918334Speter
123018334Speter/* Nonzero means warn about any identifiers that match in the first N
123118334Speter   characters.  The value N is in `id_clash_len'.  */
123218334Speter
123318334Speterint warn_id_clash;
123418334Speterunsigned id_clash_len;
123518334Speter
123618334Speter/* Nonzero means warn about any objects definitions whose size is larger
123718334Speter   than N bytes.  Also want about function definitions whose returned
123818334Speter   values are larger than N bytes. The value N is in `larger_than_size'.  */
123918334Speter
124018334Speterint warn_larger_than;
124118334Speterunsigned larger_than_size;
124218334Speter
124318334Speter/* Nonzero means warn if inline function is too large.  */
124418334Speter
124518334Speterint warn_inline;
124618334Speter
124718334Speter/* Warn if a function returns an aggregate,
124818334Speter   since there are often incompatible calling conventions for doing this.  */
124918334Speter
125018334Speterint warn_aggregate_return;
125118334Speter
125218334Speter/* Likewise for -W.  */
125318334Speter
125450615Sobrienlang_independent_options W_options[] =
125518334Speter{
125650615Sobrien  {"unused", &warn_unused, 1, "Warn when a variable is unused" },
125750615Sobrien  {"error", &warnings_are_errors, 1, ""},
125850615Sobrien  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
125950615Sobrien  {"switch", &warn_switch, 1,
126050615Sobrien   "Warn about enumerated switches missing a specific case" },
126150615Sobrien  {"aggregate-return", &warn_aggregate_return, 1,
126250615Sobrien   "Warn about returning structures, unions or arrays" },
126350615Sobrien  {"cast-align", &warn_cast_align, 1,
126450615Sobrien   "Warn about pointer casts which increase alignment" },
126550615Sobrien  {"uninitialized", &warn_uninitialized, 1,
126650615Sobrien   "Warn about unitialized automatic variables"},
126750615Sobrien  {"inline", &warn_inline, 1,
126850615Sobrien   "Warn when an inlined function cannot be inlined"}
126918334Speter};
127018334Speter
127118334Speter/* Output files for assembler code (real compiler output)
127218334Speter   and debugging dumps.  */
127318334Speter
127418334SpeterFILE *asm_out_file;
127518334SpeterFILE *aux_info_file;
127650615SobrienFILE *rtl_dump_file = NULL;
127718334Speter
127852558Sobrien/* Decode the string P as an integral parameter.
127952558Sobrien   If the string is indeed an integer return its numeric value else
128052558Sobrien   issue an Invalid Option error for the option PNAME and return DEFVAL.
128152558Sobrien   If PNAME is zero just return DEFVAL, do not call error.               */
128252558Sobrien
128352558Sobrienint
128452558Sobrienread_integral_parameter (p, pname, defval)
128552558Sobrien     const char *p;
128652558Sobrien     const char *pname;
128752558Sobrien     const int  defval;
128852558Sobrien{
128952558Sobrien  const char *endp = p;
129052558Sobrien
129152558Sobrien  while (*endp)
129252558Sobrien    {
129352558Sobrien      if (*endp >= '0' && *endp <= '9')
129452558Sobrien	endp++;
129552558Sobrien      else
129652558Sobrien	break;
129752558Sobrien    }
129852558Sobrien
129952558Sobrien  if (*endp != 0)
130052558Sobrien    {
130152558Sobrien      if (pname != 0)
130252558Sobrien	error ("Invalid option `%s'", pname);
130352558Sobrien      return defval;
130452558Sobrien    }
130552558Sobrien
130652558Sobrien  return atoi (p);
130752558Sobrien}
130852558Sobrien
130952558Sobrien
131018334Speter/* Time accumulators, to count the total time spent in various passes.  */
131118334Speter
131218334Speterint parse_time;
131318334Speterint varconst_time;
131418334Speterint integration_time;
131518334Speterint jump_time;
131618334Speterint cse_time;
131750615Sobrienint gcse_time;
131818334Speterint loop_time;
131918334Speterint cse2_time;
132050615Sobrienint branch_prob_time;
132118334Speterint flow_time;
132218334Speterint combine_time;
132350615Sobrienint regmove_time;
132418334Speterint sched_time;
132518334Speterint local_alloc_time;
132618334Speterint global_alloc_time;
132752558Sobrienint flow2_time;
132818334Speterint sched2_time;
132950615Sobrien#ifdef DELAY_SLOTS
133018334Speterint dbr_sched_time;
133150615Sobrien#endif
133218334Speterint shorten_branch_time;
133318334Speterint stack_reg_time;
133418334Speterint final_time;
133518334Speterint symout_time;
133618334Speterint dump_time;
133718334Speter
133818334Speter/* Return time used so far, in microseconds.  */
133918334Speter
134052558Sobrienlong
134118334Speterget_run_time ()
134218334Speter{
134318334Speter  if (quiet_flag)
134418334Speter    return 0;
134550615Sobrien
134650615Sobrien#ifdef __BEOS__
134750615Sobrien  return 0;
134850615Sobrien#else /* not BeOS */
134952558Sobrien#if defined (_WIN32) && !defined (__CYGWIN__)
135018334Speter  if (clock() < 0)
135118334Speter    return 0;
135218334Speter  else
135318334Speter    return (clock() * 1000);
135418334Speter#else /* not _WIN32 */
135550615Sobrien#ifdef _SC_CLK_TCK
135650615Sobrien  {
135750615Sobrien    static int tick;
135850615Sobrien    struct tms tms;
135950615Sobrien    if (tick == 0)
136050615Sobrien      tick = 1000000 / sysconf(_SC_CLK_TCK);
136150615Sobrien    times (&tms);
136250615Sobrien    return (tms.tms_utime + tms.tms_stime) * tick;
136350615Sobrien  }
136450615Sobrien#else
136518334Speter#ifdef USG
136650615Sobrien  {
136750615Sobrien    struct tms tms;
136850615Sobrien#   if HAVE_SYSCONF && defined _SC_CLK_TCK
136950615Sobrien#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
137050615Sobrien#   else
137150615Sobrien#    ifdef CLK_TCK
137250615Sobrien#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
137350615Sobrien#    else
137450615Sobrien#     define TICKS_PER_SECOND HZ /* traditional UNIX */
137550615Sobrien#    endif
137650615Sobrien#   endif
137750615Sobrien    times (&tms);
137850615Sobrien    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
137950615Sobrien  }
138018334Speter#else
138118334Speter#ifndef VMS
138250615Sobrien  {
138350615Sobrien    struct rusage rusage;
138450615Sobrien    getrusage (0, &rusage);
138550615Sobrien    return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
138650615Sobrien	    + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
138750615Sobrien  }
138818334Speter#else /* VMS */
138950615Sobrien  {
139050615Sobrien    struct
139150615Sobrien      {
139250615Sobrien        int proc_user_time;
139350615Sobrien        int proc_system_time;
139450615Sobrien        int child_user_time;
139550615Sobrien        int child_system_time;
139650615Sobrien      } vms_times;
139750615Sobrien    times ((void *) &vms_times);
139850615Sobrien    return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
139950615Sobrien  }
140050615Sobrien#endif	/* VMS */
140150615Sobrien#endif	/* USG */
140250615Sobrien#endif  /* _SC_CLK_TCK */
140350615Sobrien#endif	/* _WIN32 */
140450615Sobrien#endif	/* __BEOS__ */
140518334Speter}
140618334Speter
140718334Speter#define TIMEVAR(VAR, BODY)    \
140818334Speterdo { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
140918334Speter
141018334Spetervoid
141118334Speterprint_time (str, total)
141252558Sobrien     const char *str;
141318334Speter     int total;
141418334Speter{
141518334Speter  fprintf (stderr,
141618334Speter	   "time in %s: %d.%06d\n",
141718334Speter	   str, total / 1000000, total % 1000000);
141818334Speter}
141918334Speter
142018334Speter/* Count an error or warning.  Return 1 if the message should be printed.  */
142118334Speter
142218334Speterint
142318334Spetercount_error (warningp)
142418334Speter     int warningp;
142518334Speter{
142618334Speter  if (warningp && inhibit_warnings)
142718334Speter    return 0;
142818334Speter
142918334Speter  if (warningp && !warnings_are_errors)
143018334Speter    warningcount++;
143118334Speter  else
143218334Speter    {
143318334Speter      static int warning_message = 0;
143418334Speter
143518334Speter      if (warningp && !warning_message)
143618334Speter	{
143752558Sobrien	  notice ("%s: warnings being treated as errors\n", progname);
143818334Speter	  warning_message = 1;
143918334Speter	}
144018334Speter      errorcount++;
144118334Speter    }
144218334Speter
144318334Speter  return 1;
144418334Speter}
144518334Speter
144618334Speter/* Print a fatal error message.  NAME is the text.
144718334Speter   Also include a system error message based on `errno'.  */
144818334Speter
144918334Spetervoid
145018334Speterpfatal_with_name (name)
145152558Sobrien  const char *name;
145218334Speter{
145318334Speter  fprintf (stderr, "%s: ", progname);
145418334Speter  perror (name);
145518334Speter  exit (FATAL_EXIT_CODE);
145618334Speter}
145718334Speter
145818334Spetervoid
145918334Speterfatal_io_error (name)
146052558Sobrien  const char *name;
146118334Speter{
146252558Sobrien  notice ("%s: %s: I/O error\n", progname, name);
146318334Speter  exit (FATAL_EXIT_CODE);
146418334Speter}
146518334Speter
146618334Speter/* Called to give a better error message for a bad insn rather than
146718334Speter   just calling abort().  */
146818334Speter
146918334Spetervoid
147052558Sobrienfatal_insn VPROTO((const char *msgid, rtx insn, ...))
147118334Speter{
147252558Sobrien#ifndef ANSI_PROTOTYPES
147352558Sobrien  const char *msgid;
147452558Sobrien  rtx insn;
147552558Sobrien#endif
147652558Sobrien  va_list ap;
147752558Sobrien
147852558Sobrien  VA_START (ap, insn);
147952558Sobrien
148052558Sobrien#ifndef ANSI_PROTOTYPES
148152558Sobrien  msgid = va_arg (ap, const char *);
148252558Sobrien  insn = va_arg (ap, rtx);
148352558Sobrien#endif
148452558Sobrien
148552558Sobrien  verror (msgid, ap);
148650615Sobrien  debug_rtx (insn);
148752558Sobrien  exit (FATAL_EXIT_CODE);
148818334Speter}
148918334Speter
149018334Speter/* Called to give a better error message when we don't have an insn to match
149118334Speter   what we are looking for or if the insn's constraints aren't satisfied,
149218334Speter   rather than just calling abort().  */
149318334Speter
149418334Spetervoid
149518334Speterfatal_insn_not_found (insn)
149618334Speter     rtx insn;
149718334Speter{
149818334Speter  if (INSN_CODE (insn) < 0)
149918334Speter    fatal_insn ("internal error--unrecognizable insn:", insn);
150018334Speter  else
150118334Speter    fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
150218334Speter}
150318334Speter
150418334Speter/* This is the default decl_printable_name function.  */
150518334Speter
150618334Speterstatic char *
150750615Sobriendecl_name (decl, verbosity)
150818334Speter     tree decl;
150952558Sobrien     int verbosity ATTRIBUTE_UNUSED;
151018334Speter{
151118334Speter  return IDENTIFIER_POINTER (DECL_NAME (decl));
151218334Speter}
151318334Speter
151418334Speterstatic int need_error_newline;
151518334Speter
151618334Speter/* Function of last error message;
151718334Speter   more generally, function such that if next error message is in it
151818334Speter   then we don't have to mention the function name.  */
151918334Speterstatic tree last_error_function = NULL;
152018334Speter
152118334Speter/* Used to detect when input_file_stack has changed since last described.  */
152218334Speterstatic int last_error_tick;
152318334Speter
152418334Speter/* Called when the start of a function definition is parsed,
152518334Speter   this function prints on stderr the name of the function.  */
152618334Speter
152718334Spetervoid
152818334Speterannounce_function (decl)
152918334Speter     tree decl;
153018334Speter{
153118334Speter  if (! quiet_flag)
153218334Speter    {
153318334Speter      if (rtl_dump_and_exit)
153418334Speter	fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
153518334Speter      else
153650615Sobrien	fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
153718334Speter      fflush (stderr);
153818334Speter      need_error_newline = 1;
153918334Speter      last_error_function = current_function_decl;
154018334Speter    }
154118334Speter}
154218334Speter
154318334Speter/* The default function to print out name of current function that caused
154418334Speter   an error.  */
154518334Speter
154618334Spetervoid
154718334Speterdefault_print_error_function (file)
154852558Sobrien  const char *file;
154918334Speter{
155018334Speter  if (last_error_function != current_function_decl)
155118334Speter    {
155218334Speter      if (file)
155318334Speter	fprintf (stderr, "%s: ", file);
155418334Speter
155518334Speter      if (current_function_decl == NULL)
155652558Sobrien	notice ("At top level:\n");
155718334Speter      else
155852558Sobrien	notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
155952558Sobrien		 ? "In method `%s':\n"
156052558Sobrien		 : "In function `%s':\n"),
156152558Sobrien		(*decl_printable_name) (current_function_decl, 2));
156218334Speter
156318334Speter      last_error_function = current_function_decl;
156418334Speter    }
156518334Speter}
156618334Speter
156718334Speter/* Called by report_error_function to print out function name.
156850615Sobrien * Default may be overridden by language front-ends.  */
156918334Speter
157052558Sobrienvoid (*print_error_function) PROTO((const char *)) =
157152558Sobrien  default_print_error_function;
157218334Speter
157318334Speter/* Prints out, if necessary, the name of the current function
157452558Sobrien  that caused an error.  Called from all error and warning functions.
157552558Sobrien  We ignore the FILE parameter, as it cannot be relied upon.  */
157618334Speter
157718334Spetervoid
157818334Speterreport_error_function (file)
157952558Sobrien  const char *file ATTRIBUTE_UNUSED;
158018334Speter{
158118334Speter  struct file_stack *p;
158218334Speter
158318334Speter  if (need_error_newline)
158418334Speter    {
158518334Speter      fprintf (stderr, "\n");
158618334Speter      need_error_newline = 0;
158718334Speter    }
158818334Speter
158918334Speter  if (input_file_stack && input_file_stack->next != 0
159052558Sobrien      && input_file_stack_tick != last_error_tick)
159118334Speter    {
159218334Speter      for (p = input_file_stack->next; p; p = p->next)
159352558Sobrien	notice ((p == input_file_stack->next
159452558Sobrien		 ?    "In file included from %s:%d"
159552558Sobrien		 : ",\n                 from %s:%d"),
159652558Sobrien		p->name, p->line);
159718334Speter      fprintf (stderr, ":\n");
159818334Speter      last_error_tick = input_file_stack_tick;
159918334Speter    }
160052558Sobrien
160152558Sobrien  (*print_error_function) (input_filename);
160218334Speter}
160318334Speter
160418334Speter/* Print a message.  */
160518334Speter
160618334Speterstatic void
160752558Sobrienvnotice (file, msgid, ap)
160852558Sobrien     FILE *file;
160952558Sobrien     char *msgid;
161018334Speter     va_list ap;
161118334Speter{
161252558Sobrien  vfprintf (file, _(msgid), ap);
161352558Sobrien}
161418334Speter
161552558Sobrienvoid
161652558Sobriennotice VPROTO((const char *msgid, ...))
161752558Sobrien{
161852558Sobrien#ifndef ANSI_PROTOTYPES
161952558Sobrien  char *msgid;
162052558Sobrien#endif
162152558Sobrien  va_list ap;
162252558Sobrien
162352558Sobrien  VA_START (ap, msgid);
162452558Sobrien
162552558Sobrien#ifndef ANSI_PROTOTYPES
162652558Sobrien  msgid = va_arg (ap, char *);
162752558Sobrien#endif
162852558Sobrien
162952558Sobrien  vnotice (stderr, msgid, ap);
163052558Sobrien  va_end (ap);
163118334Speter}
163218334Speter
163352558Sobrienvoid
163452558Sobrienfnotice VPROTO((FILE *file, const char *msgid, ...))
163552558Sobrien{
163652558Sobrien#ifndef ANSI_PROTOTYPES
163752558Sobrien  FILE *file;
163852558Sobrien  const char *msgid;
163952558Sobrien#endif
164052558Sobrien  va_list ap;
164118334Speter
164252558Sobrien  VA_START (ap, msgid);
164352558Sobrien
164452558Sobrien#ifndef ANSI_PROTOTYPES
164552558Sobrien  file = va_arg (ap, FILE *);
164652558Sobrien  msgid = va_arg (ap, const char *);
164752558Sobrien#endif
164852558Sobrien
164952558Sobrien  vnotice (file, msgid, ap);
165052558Sobrien  va_end (ap);
165152558Sobrien}
165252558Sobrien
165352558Sobrien/* Report FILE and LINE (or program name), and optionally just WARN.  */
165452558Sobrien
165518334Speterstatic void
165652558Sobrienreport_file_and_line (file, line, warn)
165718334Speter     char *file;
165818334Speter     int line;
165952558Sobrien     int warn;
166018334Speter{
166118334Speter  if (file)
166218334Speter    fprintf (stderr, "%s:%d: ", file, line);
166318334Speter  else
166418334Speter    fprintf (stderr, "%s: ", progname);
166518334Speter
166652558Sobrien  if (warn)
166752558Sobrien    notice ("warning: ");
166852558Sobrien}
166952558Sobrien
167052558Sobrien/* Print a message.  */
167152558Sobrien
167252558Sobrienstatic void
167352558Sobrienvmessage (prefix, msgid, ap)
167452558Sobrien     const char *prefix;
167552558Sobrien     const char *msgid;
167652558Sobrien     va_list ap;
167752558Sobrien{
167852558Sobrien  if (prefix)
167952558Sobrien    fprintf (stderr, "%s: ", prefix);
168052558Sobrien
168152558Sobrien  vfprintf (stderr, msgid, ap);
168252558Sobrien}
168352558Sobrien
168452558Sobrien/* Print a message relevant to line LINE of file FILE.  */
168552558Sobrien
168652558Sobrienstatic void
168752558Sobrienv_message_with_file_and_line (file, line, warn, msgid, ap)
168852558Sobrien     const char *file;
168952558Sobrien     int line;
169052558Sobrien     int warn;
169152558Sobrien     const char *msgid;
169252558Sobrien     va_list ap;
169352558Sobrien{
169452558Sobrien  report_file_and_line (file, line, warn);
169552558Sobrien  vnotice (stderr, msgid, ap);
169618334Speter  fputc ('\n', stderr);
169718334Speter}
169818334Speter
169918334Speter/* Print a message relevant to the given DECL.  */
170018334Speter
170118334Speterstatic void
170252558Sobrienv_message_with_decl (decl, warn, msgid, ap)
170318334Speter     tree decl;
170452558Sobrien     int warn;
170552558Sobrien     const char *msgid;
170618334Speter     va_list ap;
170718334Speter{
170852558Sobrien  const char *p;
170918334Speter
171052558Sobrien  report_file_and_line (DECL_SOURCE_FILE (decl),
171152558Sobrien			DECL_SOURCE_LINE (decl), warn);
171218334Speter
171318334Speter  /* Do magic to get around lack of varargs support for insertion
171418334Speter     of arguments into existing list.  We know that the decl is first;
171518334Speter     we ass_u_me that it will be printed with "%s".  */
171618334Speter
171752558Sobrien  for (p = _(msgid); *p; ++p)
171818334Speter    {
171918334Speter      if (*p == '%')
172018334Speter	{
172118334Speter	  if (*(p + 1) == '%')
172218334Speter	    ++p;
172352558Sobrien	  else if (*(p + 1) != 's')
172452558Sobrien	    abort ();
172518334Speter	  else
172618334Speter	    break;
172718334Speter	}
172818334Speter    }
172918334Speter
173052558Sobrien  if (p > _(msgid))			/* Print the left-hand substring.  */
173118334Speter    {
173218334Speter      char fmt[sizeof "%.255s"];
173352558Sobrien      long width = p - _(msgid);
173418334Speter
173518334Speter      if (width > 255L) width = 255L;	/* arbitrary */
173618334Speter      sprintf (fmt, "%%.%lds", width);
173752558Sobrien      fprintf (stderr, fmt, _(msgid));
173818334Speter    }
173918334Speter
174018334Speter  if (*p == '%')		/* Print the name.  */
174118334Speter    {
174252558Sobrien      const char *n = (DECL_NAME (decl)
174350615Sobrien		 ? (*decl_printable_name) (decl, 2)
174418334Speter		 : "((anonymous))");
174518334Speter      fputs (n, stderr);
174618334Speter      while (*p)
174718334Speter	{
174818334Speter	  ++p;
174950615Sobrien	  if (ISALPHA (*(p - 1) & 0xFF))
175018334Speter	    break;
175118334Speter	}
175218334Speter    }
175318334Speter
175418334Speter  if (*p)			/* Print the rest of the message.  */
175518334Speter    vmessage ((char *)NULL, p, ap);
175618334Speter
175718334Speter  fputc ('\n', stderr);
175818334Speter}
175918334Speter
176018334Speter/* Figure file and line of the given INSN.  */
176118334Speter
176218334Speterstatic void
176318334Speterfile_and_line_for_asm (insn, pfile, pline)
176418334Speter     rtx insn;
176518334Speter     char **pfile;
176618334Speter     int *pline;
176718334Speter{
176818334Speter  rtx body = PATTERN (insn);
176918334Speter  rtx asmop;
177018334Speter
177118334Speter  /* Find the (or one of the) ASM_OPERANDS in the insn.  */
177218334Speter  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
177318334Speter    asmop = SET_SRC (body);
177418334Speter  else if (GET_CODE (body) == ASM_OPERANDS)
177518334Speter    asmop = body;
177618334Speter  else if (GET_CODE (body) == PARALLEL
177718334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
177818334Speter    asmop = SET_SRC (XVECEXP (body, 0, 0));
177918334Speter  else if (GET_CODE (body) == PARALLEL
178018334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
178118334Speter    asmop = XVECEXP (body, 0, 0);
178218334Speter  else
178318334Speter    asmop = NULL;
178418334Speter
178518334Speter  if (asmop)
178618334Speter    {
178718334Speter      *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
178818334Speter      *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
178918334Speter    }
179018334Speter  else
179118334Speter    {
179218334Speter      *pfile = input_filename;
179318334Speter      *pline = lineno;
179418334Speter    }
179518334Speter}
179618334Speter
179718334Speter/* Report an error at line LINE of file FILE.  */
179818334Speter
179918334Speterstatic void
180052558Sobrienv_error_with_file_and_line (file, line, msgid, ap)
180152558Sobrien     const char *file;
180218334Speter     int line;
180352558Sobrien     const char *msgid;
180418334Speter     va_list ap;
180518334Speter{
180618334Speter  count_error (0);
180718334Speter  report_error_function (file);
180852558Sobrien  v_message_with_file_and_line (file, line, 0, msgid, ap);
180918334Speter}
181018334Speter
181118334Spetervoid
181252558Sobrienerror_with_file_and_line VPROTO((const char *file, int line,
181352558Sobrien				 const char *msgid, ...))
181418334Speter{
181552558Sobrien#ifndef ANSI_PROTOTYPES
181652558Sobrien  const char *file;
181718334Speter  int line;
181852558Sobrien  const char *msgid;
181918334Speter#endif
182018334Speter  va_list ap;
182118334Speter
182252558Sobrien  VA_START (ap, msgid);
182318334Speter
182452558Sobrien#ifndef ANSI_PROTOTYPES
182552558Sobrien  file = va_arg (ap, const char *);
182618334Speter  line = va_arg (ap, int);
182752558Sobrien  msgid = va_arg (ap, const char *);
182818334Speter#endif
182918334Speter
183052558Sobrien  v_error_with_file_and_line (file, line, msgid, ap);
183118334Speter  va_end (ap);
183218334Speter}
183318334Speter
183418334Speter/* Report an error at the declaration DECL.
183552558Sobrien   MSGID is a format string which uses %s to substitute the declaration
183618334Speter   name; subsequent substitutions are a la printf.  */
183718334Speter
183818334Speterstatic void
183952558Sobrienv_error_with_decl (decl, msgid, ap)
184018334Speter     tree decl;
184152558Sobrien     const char *msgid;
184218334Speter     va_list ap;
184318334Speter{
184418334Speter  count_error (0);
184518334Speter  report_error_function (DECL_SOURCE_FILE (decl));
184652558Sobrien  v_message_with_decl (decl, 0, msgid, ap);
184718334Speter}
184818334Speter
184918334Spetervoid
185052558Sobrienerror_with_decl VPROTO((tree decl, const char *msgid, ...))
185118334Speter{
185252558Sobrien#ifndef ANSI_PROTOTYPES
185318334Speter  tree decl;
185452558Sobrien  const char *msgid;
185518334Speter#endif
185618334Speter  va_list ap;
185718334Speter
185852558Sobrien  VA_START (ap, msgid);
185918334Speter
186052558Sobrien#ifndef ANSI_PROTOTYPES
186118334Speter  decl = va_arg (ap, tree);
186252558Sobrien  msgid = va_arg (ap, const char *);
186318334Speter#endif
186418334Speter
186552558Sobrien  v_error_with_decl (decl, msgid, ap);
186618334Speter  va_end (ap);
186718334Speter}
186818334Speter
186918334Speter/* Report an error at the line number of the insn INSN.
187018334Speter   This is used only when INSN is an `asm' with operands,
187118334Speter   and each ASM_OPERANDS records its own source file and line.  */
187218334Speter
187318334Speterstatic void
187452558Sobrienv_error_for_asm (insn, msgid, ap)
187518334Speter     rtx insn;
187652558Sobrien     const char *msgid;
187718334Speter     va_list ap;
187818334Speter{
187918334Speter  char *file;
188018334Speter  int line;
188118334Speter
188218334Speter  count_error (0);
188318334Speter  file_and_line_for_asm (insn, &file, &line);
188418334Speter  report_error_function (file);
188552558Sobrien  v_message_with_file_and_line (file, line, 0, msgid, ap);
188618334Speter}
188718334Speter
188818334Spetervoid
188952558Sobrienerror_for_asm VPROTO((rtx insn, const char *msgid, ...))
189018334Speter{
189152558Sobrien#ifndef ANSI_PROTOTYPES
189218334Speter  rtx insn;
189352558Sobrien  const char *msgid;
189418334Speter#endif
189518334Speter  va_list ap;
189618334Speter
189752558Sobrien  VA_START (ap, msgid);
189818334Speter
189952558Sobrien#ifndef ANSI_PROTOTYPES
190018334Speter  insn = va_arg (ap, rtx);
190152558Sobrien  msgid = va_arg (ap, const char *);
190218334Speter#endif
190318334Speter
190452558Sobrien  v_error_for_asm (insn, msgid, ap);
190518334Speter  va_end (ap);
190618334Speter}
190718334Speter
190818334Speter/* Report an error at the current line number.  */
190918334Speter
191018334Speterstatic void
191152558Sobrienverror (msgid, ap)
191252558Sobrien     const char *msgid;
191318334Speter     va_list ap;
191418334Speter{
191552558Sobrien  v_error_with_file_and_line (input_filename, lineno, msgid, ap);
191618334Speter}
191718334Speter
191818334Spetervoid
191952558Sobrienerror VPROTO((const char *msgid, ...))
192018334Speter{
192152558Sobrien#ifndef ANSI_PROTOTYPES
192252558Sobrien  const char *msgid;
192318334Speter#endif
192418334Speter  va_list ap;
192518334Speter
192652558Sobrien  VA_START (ap, msgid);
192718334Speter
192852558Sobrien#ifndef ANSI_PROTOTYPES
192952558Sobrien  msgid = va_arg (ap, const char *);
193018334Speter#endif
193118334Speter
193252558Sobrien  verror (msgid, ap);
193318334Speter  va_end (ap);
193418334Speter}
193518334Speter
193618334Speter/* Report a fatal error at the current line number.  */
193718334Speter
193818334Speterstatic void
193952558Sobrienvfatal (msgid, ap)
194052558Sobrien     const char *msgid;
194118334Speter     va_list ap;
194218334Speter{
194352558Sobrien  verror (msgid, ap);
194418334Speter  exit (FATAL_EXIT_CODE);
194518334Speter}
194618334Speter
194718334Spetervoid
194852558Sobrienfatal VPROTO((const char *msgid, ...))
194918334Speter{
195052558Sobrien#ifndef ANSI_PROTOTYPES
195152558Sobrien  const char *msgid;
195218334Speter#endif
195318334Speter  va_list ap;
195418334Speter
195552558Sobrien  VA_START (ap, msgid);
195618334Speter
195752558Sobrien#ifndef ANSI_PROTOTYPES
195852558Sobrien  msgid = va_arg (ap, const char *);
195918334Speter#endif
196018334Speter
196152558Sobrien  vfatal (msgid, ap);
196218334Speter  va_end (ap);
196318334Speter}
196418334Speter
196518334Speter/* Report a warning at line LINE of file FILE.  */
196618334Speter
196718334Speterstatic void
196852558Sobrienv_warning_with_file_and_line (file, line, msgid, ap)
196952558Sobrien     const char *file;
197018334Speter     int line;
197152558Sobrien     const char *msgid;
197218334Speter     va_list ap;
197318334Speter{
197418334Speter  if (count_error (1))
197518334Speter    {
197618334Speter      report_error_function (file);
197752558Sobrien      v_message_with_file_and_line (file, line, 1, msgid, ap);
197818334Speter    }
197918334Speter}
198018334Speter
198118334Spetervoid
198252558Sobrienwarning_with_file_and_line VPROTO((const char *file, int line,
198352558Sobrien				   const char *msgid, ...))
198418334Speter{
198552558Sobrien#ifndef ANSI_PROTOTYPES
198652558Sobrien  const char *file;
198718334Speter  int line;
198852558Sobrien  const char *msgid;
198918334Speter#endif
199018334Speter  va_list ap;
199118334Speter
199252558Sobrien  VA_START (ap, msgid);
199318334Speter
199452558Sobrien#ifndef ANSI_PROTOTYPES
199552558Sobrien  file = va_arg (ap, const char *);
199618334Speter  line = va_arg (ap, int);
199752558Sobrien  msgid = va_arg (ap, const char *);
199818334Speter#endif
199918334Speter
200052558Sobrien  v_warning_with_file_and_line (file, line, msgid, ap);
200118334Speter  va_end (ap);
200218334Speter}
200318334Speter
200418334Speter/* Report a warning at the declaration DECL.
200552558Sobrien   MSGID is a format string which uses %s to substitute the declaration
200618334Speter   name; subsequent substitutions are a la printf.  */
200718334Speter
200818334Speterstatic void
200952558Sobrienv_warning_with_decl (decl, msgid, ap)
201018334Speter     tree decl;
201152558Sobrien     const char *msgid;
201218334Speter     va_list ap;
201318334Speter{
201418334Speter  if (count_error (1))
201518334Speter    {
201618334Speter      report_error_function (DECL_SOURCE_FILE (decl));
201752558Sobrien      v_message_with_decl (decl, 1, msgid, ap);
201818334Speter    }
201918334Speter}
202018334Speter
202118334Spetervoid
202252558Sobrienwarning_with_decl VPROTO((tree decl, const char *msgid, ...))
202318334Speter{
202452558Sobrien#ifndef ANSI_PROTOTYPES
202518334Speter  tree decl;
202652558Sobrien  const char *msgid;
202718334Speter#endif
202818334Speter  va_list ap;
202918334Speter
203052558Sobrien  VA_START (ap, msgid);
203118334Speter
203252558Sobrien#ifndef ANSI_PROTOTYPES
203318334Speter  decl = va_arg (ap, tree);
203452558Sobrien  msgid = va_arg (ap, const char *);
203518334Speter#endif
203618334Speter
203752558Sobrien  v_warning_with_decl (decl, msgid, ap);
203818334Speter  va_end (ap);
203918334Speter}
204018334Speter
204118334Speter/* Report a warning at the line number of the insn INSN.
204218334Speter   This is used only when INSN is an `asm' with operands,
204318334Speter   and each ASM_OPERANDS records its own source file and line.  */
204418334Speter
204518334Speterstatic void
204652558Sobrienv_warning_for_asm (insn, msgid, ap)
204718334Speter     rtx insn;
204852558Sobrien     const char *msgid;
204918334Speter     va_list ap;
205018334Speter{
205118334Speter  if (count_error (1))
205218334Speter    {
205318334Speter      char *file;
205418334Speter      int line;
205518334Speter
205618334Speter      file_and_line_for_asm (insn, &file, &line);
205718334Speter      report_error_function (file);
205852558Sobrien      v_message_with_file_and_line (file, line, 1, msgid, ap);
205918334Speter    }
206018334Speter}
206118334Speter
206218334Spetervoid
206352558Sobrienwarning_for_asm VPROTO((rtx insn, const char *msgid, ...))
206418334Speter{
206552558Sobrien#ifndef ANSI_PROTOTYPES
206618334Speter  rtx insn;
206752558Sobrien  const char *msgid;
206818334Speter#endif
206918334Speter  va_list ap;
207018334Speter
207152558Sobrien  VA_START (ap, msgid);
207218334Speter
207352558Sobrien#ifndef ANSI_PROTOTYPES
207418334Speter  insn = va_arg (ap, rtx);
207552558Sobrien  msgid = va_arg (ap, const char *);
207618334Speter#endif
207718334Speter
207852558Sobrien  v_warning_for_asm (insn, msgid, ap);
207918334Speter  va_end (ap);
208018334Speter}
208118334Speter
208218334Speter/* Report a warning at the current line number.  */
208318334Speter
208418334Speterstatic void
208552558Sobrienvwarning (msgid, ap)
208652558Sobrien     const char *msgid;
208718334Speter     va_list ap;
208818334Speter{
208952558Sobrien  v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
209018334Speter}
209118334Speter
209218334Spetervoid
209352558Sobrienwarning VPROTO((const char *msgid, ...))
209418334Speter{
209552558Sobrien#ifndef ANSI_PROTOTYPES
209652558Sobrien  const char *msgid;
209718334Speter#endif
209818334Speter  va_list ap;
209918334Speter
210052558Sobrien  VA_START (ap, msgid);
210118334Speter
210252558Sobrien#ifndef ANSI_PROTOTYPES
210352558Sobrien  msgid = va_arg (ap, const char *);
210418334Speter#endif
210518334Speter
210652558Sobrien  vwarning (msgid, ap);
210718334Speter  va_end (ap);
210818334Speter}
210918334Speter
211018334Speter/* These functions issue either warnings or errors depending on
211118334Speter   -pedantic-errors.  */
211218334Speter
211318334Speterstatic void
211452558Sobrienvpedwarn (msgid, ap)
211552558Sobrien     const char *msgid;
211618334Speter     va_list ap;
211718334Speter{
211818334Speter  if (flag_pedantic_errors)
211952558Sobrien    verror (msgid, ap);
212018334Speter  else
212152558Sobrien    vwarning (msgid, ap);
212218334Speter}
212318334Speter
212418334Spetervoid
212552558Sobrienpedwarn VPROTO((const char *msgid, ...))
212618334Speter{
212752558Sobrien#ifndef ANSI_PROTOTYPES
212852558Sobrien  const char *msgid;
212918334Speter#endif
213018334Speter  va_list ap;
213118334Speter
213252558Sobrien  VA_START (ap, msgid);
213318334Speter
213452558Sobrien#ifndef ANSI_PROTOTYPES
213552558Sobrien  msgid = va_arg (ap, const char *);
213618334Speter#endif
213718334Speter
213852558Sobrien  vpedwarn (msgid, ap);
213918334Speter  va_end (ap);
214018334Speter}
214118334Speter
214218334Speterstatic void
214352558Sobrienv_pedwarn_with_decl (decl, msgid, ap)
214418334Speter     tree decl;
214552558Sobrien     const char *msgid;
214618334Speter     va_list ap;
214718334Speter{
214818334Speter  /* We don't want -pedantic-errors to cause the compilation to fail from
214918334Speter     "errors" in system header files.  Sometimes fixincludes can't fix what's
215018334Speter     broken (eg: unsigned char bitfields - fixing it may change the alignment
215118334Speter     which will cause programs to mysteriously fail because the C library
215218334Speter     or kernel uses the original layout).  There's no point in issuing a
215318334Speter     warning either, it's just unnecessary noise.  */
215418334Speter
215518334Speter  if (! DECL_IN_SYSTEM_HEADER (decl))
215618334Speter    {
215718334Speter      if (flag_pedantic_errors)
215852558Sobrien	v_error_with_decl (decl, msgid, ap);
215918334Speter      else
216052558Sobrien	v_warning_with_decl (decl, msgid, ap);
216118334Speter    }
216218334Speter}
216318334Speter
216418334Spetervoid
216552558Sobrienpedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
216618334Speter{
216752558Sobrien#ifndef ANSI_PROTOTYPES
216818334Speter  tree decl;
216952558Sobrien  const char *msgid;
217018334Speter#endif
217118334Speter  va_list ap;
217218334Speter
217352558Sobrien  VA_START (ap, msgid);
217418334Speter
217552558Sobrien#ifndef ANSI_PROTOTYPES
217618334Speter  decl = va_arg (ap, tree);
217752558Sobrien  msgid = va_arg (ap, const char *);
217818334Speter#endif
217918334Speter
218052558Sobrien  v_pedwarn_with_decl (decl, msgid, ap);
218118334Speter  va_end (ap);
218218334Speter}
218318334Speter
218418334Speterstatic void
218552558Sobrienv_pedwarn_with_file_and_line (file, line, msgid, ap)
218652558Sobrien     const char *file;
218718334Speter     int line;
218852558Sobrien     const char *msgid;
218918334Speter     va_list ap;
219018334Speter{
219118334Speter  if (flag_pedantic_errors)
219252558Sobrien    v_error_with_file_and_line (file, line, msgid, ap);
219318334Speter  else
219452558Sobrien    v_warning_with_file_and_line (file, line, msgid, ap);
219518334Speter}
219618334Speter
219718334Spetervoid
219852558Sobrienpedwarn_with_file_and_line VPROTO((const char *file, int line,
219952558Sobrien				   const char *msgid, ...))
220018334Speter{
220152558Sobrien#ifndef ANSI_PROTOTYPES
220252558Sobrien  const char *file;
220318334Speter  int line;
220452558Sobrien  const char *msgid;
220518334Speter#endif
220618334Speter  va_list ap;
220718334Speter
220852558Sobrien  VA_START (ap, msgid);
220918334Speter
221052558Sobrien#ifndef ANSI_PROTOTYPES
221152558Sobrien  file = va_arg (ap, const char *);
221218334Speter  line = va_arg (ap, int);
221352558Sobrien  msgid = va_arg (ap, const char *);
221418334Speter#endif
221518334Speter
221652558Sobrien  v_pedwarn_with_file_and_line (file, line, msgid, ap);
221718334Speter  va_end (ap);
221818334Speter}
221918334Speter
222018334Speter/* Apologize for not implementing some feature.  */
222118334Speter
222218334Speterstatic void
222352558Sobrienvsorry (msgid, ap)
222452558Sobrien     const char *msgid;
222518334Speter     va_list ap;
222618334Speter{
222718334Speter  sorrycount++;
222818334Speter  if (input_filename)
222918334Speter    fprintf (stderr, "%s:%d: ", input_filename, lineno);
223018334Speter  else
223118334Speter    fprintf (stderr, "%s: ", progname);
223252558Sobrien  notice ("sorry, not implemented: ");
223352558Sobrien  vnotice (stderr, msgid, ap);
223418334Speter  fputc ('\n', stderr);
223518334Speter}
223618334Speter
223718334Spetervoid
223852558Sobriensorry VPROTO((const char *msgid, ...))
223918334Speter{
224052558Sobrien#ifndef ANSI_PROTOTYPES
224152558Sobrien  const char *msgid;
224218334Speter#endif
224318334Speter  va_list ap;
224418334Speter
224552558Sobrien  VA_START (ap, msgid);
224618334Speter
224752558Sobrien#ifndef ANSI_PROTOTYPES
224852558Sobrien  msgid = va_arg (ap, const char *);
224918334Speter#endif
225018334Speter
225152558Sobrien  vsorry (msgid, ap);
225218334Speter  va_end (ap);
225318334Speter}
225452558Sobrien
225552558Sobrien/* Given a partial pathname as input, return another pathname that shares
225652558Sobrien   no elements with the pathname of __FILE__.  This is used by abort() to
225752558Sobrien   print `Internal compiler error in expr.c' instead of `Internal compiler
225852558Sobrien   error in ../../egcs/gcc/expr.c'.  */
225952558Sobrienconst char *
226052558Sobrientrim_filename (name)
226152558Sobrien     const char *name;
226218334Speter{
226352558Sobrien  static const char *this_file = __FILE__;
226452558Sobrien  const char *p = name, *q = this_file;
226518334Speter
226652558Sobrien  while (*p == *q && *p != 0 && *q != 0) p++, q++;
226752558Sobrien  while (p > name && p[-1] != DIR_SEPARATOR
226852558Sobrien#ifdef DIR_SEPARATOR_2
226952558Sobrien	 && p[-1] != DIR_SEPARATOR_2
227018334Speter#endif
227152558Sobrien	 )
227252558Sobrien    p--;
227318334Speter
227452558Sobrien  return p;
227552558Sobrien}
227618334Speter
227718334Speter/* More 'friendly' abort that prints the line and file.
227818334Speter   config.h can #define abort fancy_abort if you like that sort of thing.
227918334Speter
228018334Speter   I don't think this is actually a good idea.
228118334Speter   Other sorts of crashes will look a certain way.
228218334Speter   It is a good thing if crashes from calling abort look the same way.
228318334Speter     -- RMS  */
228418334Speter
228518334Spetervoid
228618334Speterfancy_abort ()
228718334Speter{
228818334Speter  fatal ("internal gcc abort");
228918334Speter}
229018334Speter
229118334Speter/* This calls abort and is used to avoid problems when abort if a macro.
229218334Speter   It is used when we need to pass the address of abort.  */
229318334Speter
229418334Spetervoid
229518334Speterdo_abort ()
229618334Speter{
229718334Speter  abort ();
229818334Speter}
229918334Speter
230018334Speter/* When `malloc.c' is compiled with `rcheck' defined,
230118334Speter   it calls this function to report clobberage.  */
230218334Speter
230318334Spetervoid
230418334Speterbotch (s)
230552558Sobrien  const char * s ATTRIBUTE_UNUSED;
230618334Speter{
230718334Speter  abort ();
230818334Speter}
230918334Speter
231018334Speter/* Same as `malloc' but report error if no memory available.  */
231118334Speter
231252558SobrienPTR
231318334Speterxmalloc (size)
231452558Sobrien  size_t size;
231518334Speter{
231652558Sobrien  register PTR value;
231750615Sobrien
231850615Sobrien  if (size == 0)
231950615Sobrien    size = 1;
232050615Sobrien
232152558Sobrien  value = (PTR) malloc (size);
232218334Speter  if (value == 0)
232318334Speter    fatal ("virtual memory exhausted");
232418334Speter  return value;
232518334Speter}
232618334Speter
232750615Sobrien/* Same as `calloc' but report error if no memory available.  */
232818334Speter
232952558SobrienPTR
233050615Sobrienxcalloc (size1, size2)
233152558Sobrien  size_t size1, size2;
233250615Sobrien{
233352558Sobrien  register PTR value;
233450615Sobrien
233550615Sobrien  if (size1 == 0 || size2 == 0)
233650615Sobrien    size1 = size2 = 1;
233750615Sobrien
233852558Sobrien  value = (PTR) calloc (size1, size2);
233950615Sobrien  if (value == 0)
234050615Sobrien    fatal ("virtual memory exhausted");
234150615Sobrien  return value;
234250615Sobrien}
234350615Sobrien
234450615Sobrien
234550615Sobrien/* Same as `realloc' but report error if no memory available.
234650615Sobrien   Also handle null PTR even if the vendor realloc gets it wrong.  */
234750615Sobrien
234852558SobrienPTR
234918334Speterxrealloc (ptr, size)
235052558Sobrien  PTR ptr;
235152558Sobrien  size_t size;
235218334Speter{
235352558Sobrien  register PTR result;
235450615Sobrien
235550615Sobrien  if (size == 0)
235650615Sobrien    size = 1;
235750615Sobrien
235852558Sobrien  result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
235950615Sobrien
236018334Speter  if (!result)
236118334Speter    fatal ("virtual memory exhausted");
236250615Sobrien
236318334Speter  return result;
236418334Speter}
236550615Sobrien
236650615Sobrien/* Same as `strdup' but report error if no memory available.  */
236750615Sobrien
236850615Sobrienchar *
236950615Sobrienxstrdup (s)
237052558Sobrien  register const char *s;
237150615Sobrien{
237250615Sobrien  register char *result = (char *) malloc (strlen (s) + 1);
237350615Sobrien
237450615Sobrien  if (! result)
237550615Sobrien    fatal ("virtual memory exhausted");
237650615Sobrien  strcpy (result, s);
237750615Sobrien  return result;
237850615Sobrien}
237918334Speter
238018334Speter/* Return the logarithm of X, base 2, considering X unsigned,
238118334Speter   if X is a power of 2.  Otherwise, returns -1.
238218334Speter
238318334Speter   This should be used via the `exact_log2' macro.  */
238418334Speter
238518334Speterint
238618334Speterexact_log2_wide (x)
238718334Speter     register unsigned HOST_WIDE_INT x;
238818334Speter{
238918334Speter  register int log = 0;
239018334Speter  /* Test for 0 or a power of 2.  */
239118334Speter  if (x == 0 || x != (x & -x))
239218334Speter    return -1;
239318334Speter  while ((x >>= 1) != 0)
239418334Speter    log++;
239518334Speter  return log;
239618334Speter}
239718334Speter
239818334Speter/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
239918334Speter   If X is 0, return -1.
240018334Speter
240118334Speter   This should be used via the floor_log2 macro.  */
240218334Speter
240318334Speterint
240418334Speterfloor_log2_wide (x)
240518334Speter     register unsigned HOST_WIDE_INT x;
240618334Speter{
240718334Speter  register int log = -1;
240818334Speter  while (x != 0)
240918334Speter    log++,
241018334Speter    x >>= 1;
241118334Speter  return log;
241218334Speter}
241318334Speter
241450615Sobrienstatic int float_handler_set;
241518334Speterint float_handled;
241618334Speterjmp_buf float_handler;
241718334Speter
241850615Sobrien/* Signals actually come here.  */
241950615Sobrien
242050615Sobrienstatic void
242150615Sobrienfloat_signal (signo)
242250615Sobrien     /* If this is missing, some compilers complain.  */
242350615Sobrien     int signo ATTRIBUTE_UNUSED;
242450615Sobrien{
242550615Sobrien  if (float_handled == 0)
242650615Sobrien    abort ();
242750615Sobrien#if defined (USG) || defined (hpux)
242850615Sobrien  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
242950615Sobrien#endif
243050615Sobrien  float_handled = 0;
243150615Sobrien  signal (SIGFPE, float_signal);
243250615Sobrien  longjmp (float_handler, 1);
243350615Sobrien}
243450615Sobrien
243518334Speter/* Specify where to longjmp to when a floating arithmetic error happens.
243618334Speter   If HANDLER is 0, it means don't handle the errors any more.  */
243718334Speter
243818334Spetervoid
243918334Speterset_float_handler (handler)
244018334Speter     jmp_buf handler;
244118334Speter{
244218334Speter  float_handled = (handler != 0);
244318334Speter  if (handler)
244418334Speter    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
244550615Sobrien
244650615Sobrien  if (float_handled && ! float_handler_set)
244750615Sobrien    {
244850615Sobrien      signal (SIGFPE, float_signal);
244950615Sobrien      float_handler_set = 1;
245050615Sobrien    }
245118334Speter}
245218334Speter
245352558Sobrien/* This is a wrapper function for code which might elicit an
245452558Sobrien   arithmetic exception.  That code should be passed in as a function
245552558Sobrien   pointer FN, and one argument DATA.  DATA is usually a struct which
245652558Sobrien   contains the real input and output for function FN.  This function
245752558Sobrien   returns 0 (failure) if longjmp was called (i.e. an exception
245852558Sobrien   occured.)  It returns 1 (success) otherwise. */
245952558Sobrien
246052558Sobrienint
246152558Sobriendo_float_handler (fn, data)
246252558Sobrien  void (*fn) PROTO ((PTR));
246352558Sobrien  PTR data;
246452558Sobrien{
246552558Sobrien  jmp_buf buf;
246652558Sobrien
246752558Sobrien  if (setjmp (buf))
246852558Sobrien    {
246952558Sobrien      /* We got here via longjmp() caused by an exception in function fn() */
247052558Sobrien      set_float_handler (NULL);
247152558Sobrien      return 0;
247252558Sobrien    }
247352558Sobrien
247452558Sobrien  set_float_handler (buf);
247552558Sobrien  (*fn)(data);
247652558Sobrien  set_float_handler (NULL);
247752558Sobrien  return 1;
247852558Sobrien}
247952558Sobrien
248018334Speter/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
248118334Speter   error happens, pushing the previous specification into OLD_HANDLER.
248218334Speter   Return an indication of whether there was a previous handler in effect.  */
248318334Speter
248418334Speterint
248518334Speterpush_float_handler (handler, old_handler)
248618334Speter     jmp_buf handler, old_handler;
248718334Speter{
248818334Speter  int was_handled = float_handled;
248918334Speter
249018334Speter  float_handled = 1;
249118334Speter  if (was_handled)
249252558Sobrien    memcpy ((char *) old_handler, (char *) float_handler,
249318334Speter	   sizeof (float_handler));
249418334Speter
249552558Sobrien  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
249618334Speter  return was_handled;
249718334Speter}
249818334Speter
249918334Speter/* Restore the previous specification of whether and where to longjmp to
250018334Speter   when a floating arithmetic error happens.  */
250118334Speter
250218334Spetervoid
250318334Speterpop_float_handler (handled, handler)
250418334Speter     int handled;
250518334Speter     jmp_buf handler;
250618334Speter{
250718334Speter  float_handled = handled;
250818334Speter  if (handled)
250918334Speter    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
251018334Speter}
251118334Speter
251218334Speter/* Handler for SIGPIPE.  */
251318334Speter
251418334Speterstatic void
251518334Speterpipe_closed (signo)
251618334Speter     /* If this is missing, some compilers complain.  */
251750615Sobrien     int signo ATTRIBUTE_UNUSED;
251818334Speter{
251918334Speter  fatal ("output pipe has been closed");
252018334Speter}
252118334Speter
252218334Speter/* Strip off a legitimate source ending from the input string NAME of
252318334Speter   length LEN.  Rather than having to know the names used by all of
252450615Sobrien   our front ends, we strip off an ending of a period followed by
252550615Sobrien   up to five characters.  (Java uses ".class".) */
252618334Speter
252718334Spetervoid
252818334Speterstrip_off_ending (name, len)
252918334Speter     char *name;
253018334Speter     int len;
253118334Speter{
253250615Sobrien  int i;
253350615Sobrien  for (i = 2;  i < 6 && len > i;  i++)
253450615Sobrien    {
253550615Sobrien      if (name[len - i] == '.')
253650615Sobrien	{
253750615Sobrien	  name[len - i] = '\0';
253850615Sobrien	  break;
253950615Sobrien	}
254050615Sobrien    }
254118334Speter}
254218334Speter
254318334Speter/* Output a quoted string.  */
254450615Sobrien
254518334Spetervoid
254618334Speteroutput_quoted_string (asm_file, string)
254718334Speter     FILE *asm_file;
254852558Sobrien     const char *string;
254918334Speter{
255050615Sobrien#ifdef OUTPUT_QUOTED_STRING
255150615Sobrien  OUTPUT_QUOTED_STRING (asm_file, string);
255250615Sobrien#else
255318334Speter  char c;
255418334Speter
255518334Speter  putc ('\"', asm_file);
255618334Speter  while ((c = *string++) != 0)
255718334Speter    {
255818334Speter      if (c == '\"' || c == '\\')
255918334Speter	putc ('\\', asm_file);
256018334Speter      putc (c, asm_file);
256118334Speter    }
256218334Speter  putc ('\"', asm_file);
256350615Sobrien#endif
256418334Speter}
256518334Speter
256618334Speter/* Output a file name in the form wanted by System V.  */
256718334Speter
256818334Spetervoid
256918334Speteroutput_file_directive (asm_file, input_name)
257018334Speter     FILE *asm_file;
257152558Sobrien     const char *input_name;
257218334Speter{
257318334Speter  int len = strlen (input_name);
257452558Sobrien  const char *na = input_name + len;
257518334Speter
257618334Speter  /* NA gets INPUT_NAME sans directory names.  */
257718334Speter  while (na > input_name)
257818334Speter    {
257918334Speter      if (na[-1] == '/')
258018334Speter	break;
258152558Sobrien#ifdef DIR_SEPARATOR
258252558Sobrien      if (na[-1] == DIR_SEPARATOR)
258352558Sobrien	break;
258452558Sobrien#endif
258518334Speter      na--;
258618334Speter    }
258718334Speter
258818334Speter#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
258918334Speter  ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
259018334Speter#else
259118334Speter#ifdef ASM_OUTPUT_SOURCE_FILENAME
259218334Speter  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
259318334Speter#else
259418334Speter  fprintf (asm_file, "\t.file\t");
259518334Speter  output_quoted_string (asm_file, na);
259618334Speter  fputc ('\n', asm_file);
259718334Speter#endif
259818334Speter#endif
259918334Speter}
260018334Speter
260152558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE
260250615Sobrien/* Routine to build language identifier for object file.  */
260318334Speterstatic void
260418334Speteroutput_lang_identify (asm_out_file)
260518334Speter     FILE *asm_out_file;
260618334Speter{
260718334Speter  int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
260818334Speter  char *s = (char *) alloca (len);
260918334Speter  sprintf (s, "__gnu_compiled_%s", lang_identify ());
261018334Speter  ASM_OUTPUT_LABEL (asm_out_file, s);
261118334Speter}
261252558Sobrien#endif
261318334Speter
261418334Speter/* Routine to open a dump file.  */
261550615Sobrienstatic void
261650615Sobrienopen_dump_file (suffix, function_name)
261752558Sobrien     const char *suffix;
261852558Sobrien     const char *function_name;
261918334Speter{
262050615Sobrien  char *dumpname;
262118334Speter
262250615Sobrien  TIMEVAR
262350615Sobrien    (dump_time,
262450615Sobrien     {
262550615Sobrien       dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
262650615Sobrien
262750615Sobrien       if (rtl_dump_file != NULL)
262850615Sobrien	 fclose (rtl_dump_file);
262950615Sobrien
263050615Sobrien       strcpy (dumpname, dump_base_name);
263150615Sobrien       strcat (dumpname, suffix);
263250615Sobrien
263350615Sobrien       rtl_dump_file = fopen (dumpname, "a");
263450615Sobrien
263550615Sobrien       if (rtl_dump_file == NULL)
263650615Sobrien	 pfatal_with_name (dumpname);
263750615Sobrien
263850615Sobrien       free (dumpname);
263950615Sobrien
264050615Sobrien       if (function_name)
264150615Sobrien	 fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
264250615Sobrien     });
264350615Sobrien
264450615Sobrien  return;
264550615Sobrien}
264650615Sobrien
264750615Sobrien/* Routine to close a dump file.  */
264850615Sobrienstatic void
264950615Sobrienclose_dump_file (func, insns)
265050615Sobrien     void (*func) PROTO ((FILE *, rtx));
265150615Sobrien     rtx    insns;
265250615Sobrien{
265350615Sobrien  TIMEVAR
265450615Sobrien    (dump_time,
265550615Sobrien     {
265650615Sobrien       if (func)
265750615Sobrien	 func (rtl_dump_file, insns);
265850615Sobrien
265950615Sobrien       fflush (rtl_dump_file);
266050615Sobrien       fclose (rtl_dump_file);
266150615Sobrien
266250615Sobrien       rtl_dump_file = NULL;
266350615Sobrien     });
266450615Sobrien
266550615Sobrien  return;
266650615Sobrien}
266750615Sobrien
266850615Sobrien/* Routine to dump rtl into a file.  */
266950615Sobrienstatic void
267050615Sobriendump_rtl (suffix, decl, func, insns)
267152558Sobrien     const char *suffix;
267250615Sobrien     tree   decl;
267350615Sobrien     void (*func) PROTO ((FILE *, rtx));
267450615Sobrien     rtx    insns;
267550615Sobrien{
267650615Sobrien  open_dump_file (suffix, decl_printable_name (decl, 2));
267750615Sobrien  close_dump_file (func, insns);
267850615Sobrien}
267950615Sobrien
268050615Sobrien/* Routine to empty a dump file.  */
268150615Sobrienstatic void
268250615Sobrienclean_dump_file (suffix)
268352558Sobrien  const char *suffix;
268450615Sobrien{
268552558Sobrien  char *dumpname;
268650615Sobrien
268750615Sobrien  dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
268850615Sobrien
268950615Sobrien  strcpy (dumpname, dump_base_name);
269018334Speter  strcat (dumpname, suffix);
269150615Sobrien
269250615Sobrien  rtl_dump_file = fopen (dumpname, "w");
269350615Sobrien
269450615Sobrien  if (rtl_dump_file == NULL)
269550615Sobrien    pfatal_with_name (dumpname);
269650615Sobrien
269750615Sobrien  free (dumpname);
269850615Sobrien
269950615Sobrien  fclose (rtl_dump_file);
270050615Sobrien  rtl_dump_file = NULL;
270150615Sobrien
270250615Sobrien  return;
270318334Speter}
270418334Speter
270552558Sobrien/* Do any final processing required for the declarations in VEC, of
270652558Sobrien   which there are LEN.  We write out inline functions and variables
270752558Sobrien   that have been deferred until this point, but which are required.
270852558Sobrien   Returns non-zero if anything was put out.  */
270952558Sobrienint
271052558Sobrienwrapup_global_declarations (vec, len)
271152558Sobrien     tree *vec;
271252558Sobrien     int len;
271352558Sobrien{
271452558Sobrien  tree decl;
271552558Sobrien  int i;
271652558Sobrien  int reconsider;
271752558Sobrien  int output_something = 0;
271850615Sobrien
271952558Sobrien  for (i = 0; i < len; i++)
272052558Sobrien    {
272152558Sobrien      decl = vec[i];
272252558Sobrien
272352558Sobrien      /* We're not deferring this any longer.  */
272452558Sobrien      DECL_DEFER_OUTPUT (decl) = 0;
272552558Sobrien
272652558Sobrien      if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
272752558Sobrien	  && incomplete_decl_finalize_hook != 0)
272852558Sobrien	(*incomplete_decl_finalize_hook) (decl);
272952558Sobrien    }
273052558Sobrien
273152558Sobrien  /* Now emit any global variables or functions that we have been
273252558Sobrien     putting off.  We need to loop in case one of the things emitted
273352558Sobrien     here references another one which comes earlier in the list.  */
273452558Sobrien  do
273552558Sobrien    {
273652558Sobrien      reconsider = 0;
273752558Sobrien      for (i = 0; i < len; i++)
273852558Sobrien	{
273952558Sobrien	  decl = vec[i];
274052558Sobrien
274152558Sobrien	  if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
274252558Sobrien	    continue;
274352558Sobrien
274452558Sobrien	  /* Don't write out static consts, unless we still need them.
274552558Sobrien
274652558Sobrien	     We also keep static consts if not optimizing (for debugging),
274752558Sobrien	     unless the user specified -fno-keep-static-consts.
274852558Sobrien	     ??? They might be better written into the debug information.
274952558Sobrien	     This is possible when using DWARF.
275052558Sobrien
275152558Sobrien	     A language processor that wants static constants to be always
275252558Sobrien	     written out (even if it is not used) is responsible for
275352558Sobrien	     calling rest_of_decl_compilation itself.  E.g. the C front-end
275452558Sobrien	     calls rest_of_decl_compilation from finish_decl.
275552558Sobrien	     One motivation for this is that is conventional in some
275652558Sobrien	     environments to write things like:
275752558Sobrien	     static const char rcsid[] = "... version string ...";
275852558Sobrien	     intending to force the string to be in the executable.
275952558Sobrien
276052558Sobrien	     A language processor that would prefer to have unneeded
276152558Sobrien	     static constants "optimized away" would just defer writing
276252558Sobrien	     them out until here.  E.g. C++ does this, because static
276352558Sobrien	     constants are often defined in header files.
276452558Sobrien
276552558Sobrien	     ??? A tempting alternative (for both C and C++) would be
276652558Sobrien	     to force a constant to be written if and only if it is
276752558Sobrien	     defined in a main file, as opposed to an include file.  */
276852558Sobrien
276952558Sobrien	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
277052558Sobrien	      && (! TREE_READONLY (decl)
277152558Sobrien		  || TREE_PUBLIC (decl)
277252558Sobrien		  || (!optimize && flag_keep_static_consts)
277352558Sobrien		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
277452558Sobrien	    {
277552558Sobrien	      reconsider = 1;
277652558Sobrien	      rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
277752558Sobrien	    }
277852558Sobrien
277952558Sobrien	  if (TREE_CODE (decl) == FUNCTION_DECL
278052558Sobrien	      && DECL_INITIAL (decl) != 0
278152558Sobrien	      && DECL_SAVED_INSNS (decl) != 0
278252558Sobrien	      && (flag_keep_inline_functions
278352558Sobrien		  || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
278452558Sobrien		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
278552558Sobrien	    {
278652558Sobrien	      reconsider = 1;
278752558Sobrien	      temporary_allocation ();
278852558Sobrien	      output_inline_function (decl);
278952558Sobrien	      permanent_allocation (1);
279052558Sobrien	    }
279152558Sobrien	}
279252558Sobrien
279352558Sobrien      if (reconsider)
279452558Sobrien	output_something = 1;
279552558Sobrien    }
279652558Sobrien  while (reconsider);
279752558Sobrien
279852558Sobrien  return output_something;
279952558Sobrien}
280052558Sobrien
280152558Sobrien/* Issue appropriate warnings for the global declarations in VEC (of
280252558Sobrien   which there are LEN).  Output debugging information for them.  */
280352558Sobrienvoid
280452558Sobriencheck_global_declarations (vec, len)
280552558Sobrien     tree *vec;
280652558Sobrien     int len;
280752558Sobrien{
280852558Sobrien  tree decl;
280952558Sobrien  int i;
281052558Sobrien
281152558Sobrien  for (i = 0; i < len; i++)
281252558Sobrien    {
281352558Sobrien      decl = vec[i];
281452558Sobrien
281552558Sobrien      if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
281652558Sobrien	  && ! TREE_ASM_WRITTEN (decl))
281752558Sobrien	/* Cancel the RTL for this decl so that, if debugging info
281852558Sobrien	   output for global variables is still to come,
281952558Sobrien	   this one will be omitted.  */
282052558Sobrien	DECL_RTL (decl) = NULL;
282152558Sobrien
282252558Sobrien      /* Warn about any function
282352558Sobrien	 declared static but not defined.
282452558Sobrien	 We don't warn about variables,
282552558Sobrien	 because many programs have static variables
282652558Sobrien	 that exist only to get some text into the object file.  */
282752558Sobrien      if (TREE_CODE (decl) == FUNCTION_DECL
282852558Sobrien	  && (warn_unused
282952558Sobrien	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
283052558Sobrien	  && DECL_INITIAL (decl) == 0
283152558Sobrien	  && DECL_EXTERNAL (decl)
283252558Sobrien	  && ! DECL_ARTIFICIAL (decl)
283352558Sobrien	  && ! TREE_PUBLIC (decl))
283452558Sobrien	{
283552558Sobrien	  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
283652558Sobrien	    pedwarn_with_decl (decl,
283752558Sobrien			       "`%s' used but never defined");
283852558Sobrien	  else
283952558Sobrien	    warning_with_decl (decl,
284052558Sobrien			       "`%s' declared `static' but never defined");
284152558Sobrien	  /* This symbol is effectively an "extern" declaration now.  */
284252558Sobrien	  TREE_PUBLIC (decl) = 1;
284352558Sobrien	  assemble_external (decl);
284452558Sobrien	}
284552558Sobrien
284652558Sobrien      /* Warn about static fns or vars defined but not used,
284752558Sobrien	 but not about inline functions or static consts
284852558Sobrien	 since defining those in header files is normal practice.  */
284952558Sobrien      if (warn_unused
285052558Sobrien	  && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
285152558Sobrien	      || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
285252558Sobrien	  && ! DECL_IN_SYSTEM_HEADER (decl)
285352558Sobrien	  && ! DECL_EXTERNAL (decl)
285452558Sobrien	  && ! TREE_PUBLIC (decl)
285552558Sobrien	  && ! TREE_USED (decl)
285652558Sobrien	  && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl))
285752558Sobrien	  /* The TREE_USED bit for file-scope decls
285852558Sobrien	     is kept in the identifier, to handle multiple
285952558Sobrien	     external decls in different scopes.  */
286052558Sobrien	  && ! TREE_USED (DECL_NAME (decl)))
286152558Sobrien	warning_with_decl (decl, "`%s' defined but not used");
286252558Sobrien
286352558Sobrien#ifdef SDB_DEBUGGING_INFO
286452558Sobrien      /* The COFF linker can move initialized global vars to the end.
286552558Sobrien	 And that can screw up the symbol ordering.
286652558Sobrien	 By putting the symbols in that order to begin with,
286752558Sobrien	 we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
286852558Sobrien      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
286952558Sobrien	  && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
287052558Sobrien	  && ! DECL_EXTERNAL (decl)
287152558Sobrien	  && DECL_RTL (decl) != 0)
287252558Sobrien	TIMEVAR (symout_time, sdbout_symbol (decl, 0));
287352558Sobrien
287452558Sobrien      /* Output COFF information for non-global
287552558Sobrien	 file-scope initialized variables.  */
287652558Sobrien      if (write_symbols == SDB_DEBUG
287752558Sobrien	  && TREE_CODE (decl) == VAR_DECL
287852558Sobrien	  && DECL_INITIAL (decl)
287952558Sobrien	  && ! DECL_EXTERNAL (decl)
288052558Sobrien	  && DECL_RTL (decl) != 0
288152558Sobrien	  && GET_CODE (DECL_RTL (decl)) == MEM)
288252558Sobrien	TIMEVAR (symout_time, sdbout_toplevel_data (decl));
288352558Sobrien#endif /* SDB_DEBUGGING_INFO */
288452558Sobrien#ifdef DWARF_DEBUGGING_INFO
288552558Sobrien      /* Output DWARF information for file-scope tentative data object
288652558Sobrien	 declarations, file-scope (extern) function declarations (which
288752558Sobrien	 had no corresponding body) and file-scope tagged type declarations
288852558Sobrien	 and definitions which have not yet been forced out.  */
288952558Sobrien
289052558Sobrien      if (write_symbols == DWARF_DEBUG
289152558Sobrien	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
289252558Sobrien	TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
289352558Sobrien#endif
289452558Sobrien#ifdef DWARF2_DEBUGGING_INFO
289552558Sobrien      /* Output DWARF2 information for file-scope tentative data object
289652558Sobrien	 declarations, file-scope (extern) function declarations (which
289752558Sobrien	 had no corresponding body) and file-scope tagged type declarations
289852558Sobrien	 and definitions which have not yet been forced out.  */
289952558Sobrien
290052558Sobrien      if (write_symbols == DWARF2_DEBUG
290152558Sobrien	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
290252558Sobrien	TIMEVAR (symout_time, dwarf2out_decl (decl));
290352558Sobrien#endif
290452558Sobrien    }
290552558Sobrien}
290652558Sobrien
290718334Speter/* Compile an entire file of output from cpp, named NAME.
290818334Speter   Write a file of assembly output and various debugging dumps.  */
290918334Speter
291018334Speterstatic void
291118334Spetercompile_file (name)
291218334Speter     char *name;
291318334Speter{
291418334Speter  tree globals;
291518334Speter  int start_time;
291618334Speter
291718334Speter  int name_specified = name != 0;
291818334Speter
291918334Speter  if (dump_base_name == 0)
292018334Speter    dump_base_name = name ? name : "gccdump";
292118334Speter
292218334Speter  parse_time = 0;
292318334Speter  varconst_time = 0;
292418334Speter  integration_time = 0;
292518334Speter  jump_time = 0;
292618334Speter  cse_time = 0;
292750615Sobrien  gcse_time = 0;
292818334Speter  loop_time = 0;
292918334Speter  cse2_time = 0;
293050615Sobrien  branch_prob_time = 0;
293118334Speter  flow_time = 0;
293218334Speter  combine_time = 0;
293350615Sobrien  regmove_time = 0;
293418334Speter  sched_time = 0;
293518334Speter  local_alloc_time = 0;
293618334Speter  global_alloc_time = 0;
293752558Sobrien  flow2_time = 0;
293818334Speter  sched2_time = 0;
293950615Sobrien#ifdef DELAY_SLOTS
294018334Speter  dbr_sched_time = 0;
294150615Sobrien#endif
294218334Speter  shorten_branch_time = 0;
294318334Speter  stack_reg_time = 0;
294418334Speter  final_time = 0;
294518334Speter  symout_time = 0;
294618334Speter  dump_time = 0;
294718334Speter
294818334Speter  /* Initialize data in various passes.  */
294918334Speter
295018334Speter  init_obstacks ();
295118334Speter  init_tree_codes ();
295250615Sobrien  name = init_parse (name);
295318334Speter  init_rtl ();
295418334Speter  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
295550615Sobrien		  || debug_info_level == DINFO_LEVEL_VERBOSE
295650615Sobrien		  || flag_test_coverage);
295718334Speter  init_regs ();
295818334Speter  init_decl_processing ();
295918334Speter  init_optabs ();
296018334Speter  init_stmt ();
296118334Speter  init_expmed ();
296218334Speter  init_expr_once ();
296318334Speter  init_loop ();
296418334Speter  init_reload ();
296550615Sobrien  init_alias_once ();
296618334Speter
296718334Speter  if (flag_caller_saves)
296818334Speter    init_caller_save ();
296918334Speter
297018334Speter  /* If auxiliary info generation is desired, open the output file.
297118334Speter     This goes in the same directory as the source file--unlike
297218334Speter     all the other output files.  */
297318334Speter  if (flag_gen_aux_info)
297418334Speter    {
297518334Speter      aux_info_file = fopen (aux_info_file_name, "w");
297618334Speter      if (aux_info_file == 0)
297718334Speter	pfatal_with_name (aux_info_file_name);
297818334Speter    }
297918334Speter
298052558Sobrien  /* Clear the dump files.  */
298118334Speter  if (rtl_dump)
298250615Sobrien    clean_dump_file (".rtl");
298318334Speter  if (jump_opt_dump)
298452558Sobrien    {
298552558Sobrien      clean_dump_file (".jump");
298652558Sobrien      if (graph_dump_format != no_graph)
298752558Sobrien	clean_graph_dump_file (dump_base_name, ".jump");
298852558Sobrien    }
298950615Sobrien  if (addressof_dump)
299052558Sobrien    {
299152558Sobrien      clean_dump_file (".addressof");
299252558Sobrien      if (graph_dump_format != no_graph)
299352558Sobrien	clean_graph_dump_file (dump_base_name, ".addressof");
299452558Sobrien    }
299518334Speter  if (cse_dump)
299652558Sobrien    {
299752558Sobrien      clean_dump_file (".cse");
299852558Sobrien      if (graph_dump_format != no_graph)
299952558Sobrien	clean_graph_dump_file (dump_base_name, ".cse");
300052558Sobrien    }
300118334Speter  if (loop_dump)
300252558Sobrien    {
300352558Sobrien      clean_dump_file (".loop");
300452558Sobrien      if (graph_dump_format != no_graph)
300552558Sobrien	clean_graph_dump_file (dump_base_name, ".loop");
300652558Sobrien    }
300718334Speter  if (cse2_dump)
300852558Sobrien    {
300952558Sobrien      clean_dump_file (".cse2");
301052558Sobrien      if (graph_dump_format != no_graph)
301152558Sobrien	clean_graph_dump_file (dump_base_name, ".cse2");
301252558Sobrien    }
301350615Sobrien  if (branch_prob_dump)
301452558Sobrien    {
301552558Sobrien      clean_dump_file (".bp");
301652558Sobrien      if (graph_dump_format != no_graph)
301752558Sobrien	clean_graph_dump_file (dump_base_name, ".bp");
301852558Sobrien    }
301918334Speter  if (flow_dump)
302052558Sobrien    {
302152558Sobrien      clean_dump_file (".flow");
302252558Sobrien      if (graph_dump_format != no_graph)
302352558Sobrien	clean_graph_dump_file (dump_base_name, ".flow");
302452558Sobrien    }
302518334Speter  if (combine_dump)
302652558Sobrien    {
302752558Sobrien      clean_dump_file (".combine");
302852558Sobrien      if (graph_dump_format != no_graph)
302952558Sobrien	clean_graph_dump_file (dump_base_name, ".combine");
303052558Sobrien    }
303150615Sobrien  if (regmove_dump)
303252558Sobrien    {
303352558Sobrien      clean_dump_file (".regmove");
303452558Sobrien      if (graph_dump_format != no_graph)
303552558Sobrien	clean_graph_dump_file (dump_base_name, ".regmove");
303652558Sobrien    }
303718334Speter  if (sched_dump)
303852558Sobrien    {
303952558Sobrien      clean_dump_file (".sched");
304052558Sobrien      if (graph_dump_format != no_graph)
304152558Sobrien	clean_graph_dump_file (dump_base_name, ".sched");
304252558Sobrien    }
304318334Speter  if (local_reg_dump)
304452558Sobrien    {
304552558Sobrien      clean_dump_file (".lreg");
304652558Sobrien      if (graph_dump_format != no_graph)
304752558Sobrien	clean_graph_dump_file (dump_base_name, ".lreg");
304852558Sobrien    }
304918334Speter  if (global_reg_dump)
305052558Sobrien    {
305152558Sobrien      clean_dump_file (".greg");
305252558Sobrien      if (graph_dump_format != no_graph)
305352558Sobrien	clean_graph_dump_file (dump_base_name, ".greg");
305452558Sobrien    }
305552558Sobrien  if (flow2_dump)
305652558Sobrien    {
305752558Sobrien      clean_dump_file (".flow2");
305852558Sobrien      if (graph_dump_format != no_graph)
305952558Sobrien	clean_graph_dump_file (dump_base_name, ".flow2");
306052558Sobrien    }
306118334Speter  if (sched2_dump)
306252558Sobrien    {
306352558Sobrien      clean_dump_file (".sched2");
306452558Sobrien      if (graph_dump_format != no_graph)
306552558Sobrien	clean_graph_dump_file (dump_base_name, ".sched2");
306652558Sobrien    }
306718334Speter  if (jump2_opt_dump)
306852558Sobrien    {
306952558Sobrien      clean_dump_file (".jump2");
307052558Sobrien      if (graph_dump_format != no_graph)
307152558Sobrien	clean_graph_dump_file (dump_base_name, ".jump2");
307252558Sobrien    }
307350615Sobrien#ifdef DELAY_SLOTS
307418334Speter  if (dbr_sched_dump)
307552558Sobrien    {
307652558Sobrien      clean_dump_file (".dbr");
307752558Sobrien      if (graph_dump_format != no_graph)
307852558Sobrien	clean_graph_dump_file (dump_base_name, ".dbr");
307952558Sobrien    }
308050615Sobrien#endif
308150615Sobrien  if (gcse_dump)
308252558Sobrien    {
308352558Sobrien      clean_dump_file (".gcse");
308452558Sobrien      if (graph_dump_format != no_graph)
308552558Sobrien	clean_graph_dump_file (dump_base_name, ".gcse");
308652558Sobrien    }
308718334Speter#ifdef STACK_REGS
308818334Speter  if (stack_reg_dump)
308952558Sobrien    {
309052558Sobrien      clean_dump_file (".stack");
309152558Sobrien      if (graph_dump_format != no_graph)
309252558Sobrien	clean_graph_dump_file (dump_base_name, ".stack");
309352558Sobrien    }
309418334Speter#endif
309550615Sobrien#ifdef MACHINE_DEPENDENT_REORG
309650615Sobrien  if (mach_dep_reorg_dump)
309752558Sobrien    {
309852558Sobrien      clean_dump_file (".mach");
309952558Sobrien      if (graph_dump_format != no_graph)
310052558Sobrien	clean_graph_dump_file (dump_base_name, ".mach");
310152558Sobrien    }
310250615Sobrien#endif
310318334Speter
310418334Speter  /* Open assembler code output file.  */
310518334Speter
310652558Sobrien  if (flag_syntax_only)
310752558Sobrien    asm_out_file = NULL;
310818334Speter  else
310918334Speter    {
311052558Sobrien      if (! name_specified && asm_file_name == 0)
311152558Sobrien	asm_out_file = stdout;
311252558Sobrien      else
311318334Speter	{
311452558Sobrien	  int len = strlen (dump_base_name);
311552558Sobrien	  register char *dumpname = (char *) xmalloc (len + 6);
311652558Sobrien	  strcpy (dumpname, dump_base_name);
311752558Sobrien	  strip_off_ending (dumpname, len);
311852558Sobrien	  strcat (dumpname, ".s");
311952558Sobrien	  if (asm_file_name == 0)
312052558Sobrien	    {
312152558Sobrien	      asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
312252558Sobrien	      strcpy (asm_file_name, dumpname);
312352558Sobrien	    }
312452558Sobrien	  if (!strcmp (asm_file_name, "-"))
312552558Sobrien	    asm_out_file = stdout;
312652558Sobrien	  else
312752558Sobrien	    asm_out_file = fopen (asm_file_name, "w");
312852558Sobrien	  if (asm_out_file == 0)
312952558Sobrien	    pfatal_with_name (asm_file_name);
313018334Speter	}
313118334Speter
313218334Speter#ifdef IO_BUFFER_SIZE
313352558Sobrien      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
313452558Sobrien	       _IOFBF, IO_BUFFER_SIZE);
313518334Speter#endif
313652558Sobrien    }
313718334Speter
313818334Speter  input_filename = name;
313918334Speter
314018334Speter  /* Put an entry on the input file stack for the main input file.  */
314118334Speter  input_file_stack
314218334Speter    = (struct file_stack *) xmalloc (sizeof (struct file_stack));
314318334Speter  input_file_stack->next = 0;
314418334Speter  input_file_stack->name = input_filename;
314518334Speter
314618334Speter  /* Perform language-specific initialization.
314718334Speter     This may set main_input_filename.  */
314818334Speter  lang_init ();
314918334Speter
315018334Speter  /* If the input doesn't start with a #line, use the input name
315118334Speter     as the official input file name.  */
315218334Speter  if (main_input_filename == 0)
315318334Speter    main_input_filename = name;
315418334Speter
315552558Sobrien  if (flag_syntax_only)
315652558Sobrien    {
315752558Sobrien      write_symbols = NO_DEBUG;
315852558Sobrien      profile_flag = 0;
315952558Sobrien      profile_block_flag = 0;
316052558Sobrien    }
316152558Sobrien  else
316252558Sobrien    {
316352558Sobrien      ASM_FILE_START (asm_out_file);
316450615Sobrien
316550615Sobrien#ifdef ASM_COMMENT_START
316652558Sobrien      if (flag_verbose_asm)
316752558Sobrien	{
316852558Sobrien	  /* Print the list of options in effect.  */
316952558Sobrien	  print_version (asm_out_file, ASM_COMMENT_START);
317052558Sobrien	  print_switch_values (asm_out_file, 0, MAX_LINE,
317150615Sobrien			       ASM_COMMENT_START, " ", "\n");
317252558Sobrien	  /* Add a blank line here so it appears in assembler output but not
317352558Sobrien	     screen output.  */
317452558Sobrien	  fprintf (asm_out_file, "\n");
317552558Sobrien	}
317650615Sobrien#endif
317718334Speter
317852558Sobrien      /* Output something to inform GDB that this compilation was by GCC.  */
317918334Speter#ifndef ASM_IDENTIFY_GCC
318052558Sobrien      fprintf (asm_out_file, "gcc2_compiled.:\n");
318118334Speter#else
318252558Sobrien      ASM_IDENTIFY_GCC (asm_out_file);
318318334Speter#endif
318418334Speter
318550615Sobrien  /* Output something to identify which front-end produced this file.  */
318618334Speter#ifdef ASM_IDENTIFY_LANGUAGE
318752558Sobrien      ASM_IDENTIFY_LANGUAGE (asm_out_file);
318818334Speter#endif
318952558Sobrien    } /* ! flag_syntax_only */
319018334Speter
319150615Sobrien#ifndef ASM_OUTPUT_SECTION_NAME
319250615Sobrien  if (flag_function_sections)
319318334Speter    {
319450615Sobrien      warning ("-ffunction-sections not supported for this target.");
319550615Sobrien      flag_function_sections = 0;
319618334Speter    }
319752558Sobrien  if (flag_data_sections)
319852558Sobrien    {
319952558Sobrien      warning ("-fdata-sections not supported for this target.");
320052558Sobrien      flag_data_sections = 0;
320152558Sobrien    }
320250615Sobrien#endif
320350615Sobrien
320450615Sobrien  if (flag_function_sections
320550615Sobrien      && (profile_flag || profile_block_flag))
320618334Speter    {
320750615Sobrien      warning ("-ffunction-sections disabled; it makes profiling impossible.");
320850615Sobrien      flag_function_sections = 0;
320950615Sobrien    }
321050615Sobrien
321152558Sobrien#ifndef OBJECT_FORMAT_ELF
321250615Sobrien  if (flag_function_sections && write_symbols != NO_DEBUG)
321350615Sobrien    warning ("-ffunction-sections may affect debugging on some targets.");
321452558Sobrien#endif
321550615Sobrien
321650615Sobrien  /* ??? Note: There used to be a conditional here
321750615Sobrien      to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
321850615Sobrien      This was to guarantee separation between gcc_compiled. and
321950615Sobrien      the first function, for the sake of dbx on Suns.
322050615Sobrien      However, having the extra zero here confused the Emacs
322150615Sobrien      code for unexec, and might confuse other programs too.
322250615Sobrien      Therefore, I took out that change.
322350615Sobrien      In future versions we should find another way to solve
322450615Sobrien      that dbx problem.  -- rms, 23 May 93.  */
322518334Speter
322650615Sobrien  /* Don't let the first function fall at the same address
322750615Sobrien     as gcc_compiled., if profiling.  */
322850615Sobrien  if (profile_flag || profile_block_flag)
322950615Sobrien    {
323050615Sobrien      /* It's best if we can write a nop here since some
323150615Sobrien	 assemblers don't tolerate zeros in the text section.  */
323250615Sobrien      if (insn_template[CODE_FOR_nop] != 0)
323350615Sobrien	output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
323450615Sobrien      else
323518334Speter	assemble_zeros (UNITS_PER_WORD);
323618334Speter    }
323718334Speter
323818334Speter  /* If dbx symbol table desired, initialize writing it
323918334Speter     and output the predefined types.  */
324018334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
324118334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
324218334Speter    TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
324318334Speter				       getdecls ()));
324418334Speter#endif
324518334Speter#ifdef SDB_DEBUGGING_INFO
324618334Speter  if (write_symbols == SDB_DEBUG)
324718334Speter    TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
324818334Speter				       getdecls ()));
324918334Speter#endif
325018334Speter#ifdef DWARF_DEBUGGING_INFO
325118334Speter  if (write_symbols == DWARF_DEBUG)
325218334Speter    TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
325318334Speter#endif
325450615Sobrien#ifdef DWARF2_UNWIND_INFO
325550615Sobrien  if (dwarf2out_do_frame ())
325650615Sobrien    dwarf2out_frame_init ();
325750615Sobrien#endif
325850615Sobrien#ifdef DWARF2_DEBUGGING_INFO
325950615Sobrien  if (write_symbols == DWARF2_DEBUG)
326050615Sobrien    TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
326150615Sobrien#endif
326218334Speter
326318334Speter  /* Initialize yet another pass.  */
326418334Speter
326550615Sobrien  init_final (main_input_filename);
326650615Sobrien  init_branch_prob (dump_base_name);
326718334Speter
326818334Speter  start_time = get_run_time ();
326918334Speter
327018334Speter  /* Call the parser, which parses the entire file
327118334Speter     (calling rest_of_compilation for each function).  */
327218334Speter
327318334Speter  if (yyparse () != 0)
327418334Speter    {
327518334Speter      if (errorcount == 0)
327652558Sobrien	notice ("Errors detected in input file (your bison.simple is out of date)\n");
327718334Speter
327818334Speter      /* In case there were missing closebraces,
327918334Speter	 get us back to the global binding level.  */
328018334Speter      while (! global_bindings_p ())
328118334Speter	poplevel (0, 0, 0);
328218334Speter    }
328318334Speter
328418334Speter  /* Compilation is now finished except for writing
328518334Speter     what's left of the symbol table output.  */
328618334Speter
328718334Speter  parse_time += get_run_time () - start_time;
328818334Speter
328918334Speter  parse_time -= integration_time;
329018334Speter  parse_time -= varconst_time;
329118334Speter
329252558Sobrien  if (flag_syntax_only)
329352558Sobrien    goto finish_syntax;
329452558Sobrien
329518334Speter  globals = getdecls ();
329618334Speter
329718334Speter  /* Really define vars that have had only a tentative definition.
329818334Speter     Really output inline functions that must actually be callable
329918334Speter     and have not been output so far.  */
330018334Speter
330118334Speter  {
330218334Speter    int len = list_length (globals);
330318334Speter    tree *vec = (tree *) alloca (sizeof (tree) * len);
330418334Speter    int i;
330518334Speter    tree decl;
330618334Speter
330718334Speter    /* Process the decls in reverse order--earliest first.
330818334Speter       Put them into VEC from back to front, then take out from front.  */
330918334Speter
331018334Speter    for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
331118334Speter      vec[len - i - 1] = decl;
331218334Speter
331352558Sobrien    wrapup_global_declarations (vec, len);
331418334Speter
331552558Sobrien    /* This must occur after the loop to output deferred functions.  Else
331652558Sobrien       the profiler initializer would not be emitted if all the functions
331752558Sobrien       in this compilation unit were deferred.
331818334Speter
331952558Sobrien       output_func_start_profiler can not cause any additional functions or
332052558Sobrien       data to need to be output, so it need not be in the deferred function
332152558Sobrien       loop above.  */
332252558Sobrien    output_func_start_profiler ();
332318334Speter
332450615Sobrien    /* Now that all possible functions have been output, we can dump
332550615Sobrien       the exception table.  */
332650615Sobrien
332750615Sobrien    output_exception_table ();
332850615Sobrien
332952558Sobrien    check_global_declarations (vec, len);
333018334Speter  }
333118334Speter
333218334Speter  /* Write out any pending weak symbol declarations.  */
333318334Speter
333418334Speter  weak_finish ();
333518334Speter
333618334Speter  /* Do dbx symbols */
333718334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
333818334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
333918334Speter    TIMEVAR (symout_time,
334018334Speter	     {
334118334Speter	       dbxout_finish (asm_out_file, main_input_filename);
334218334Speter	     });
334318334Speter#endif
334418334Speter
334518334Speter#ifdef DWARF_DEBUGGING_INFO
334618334Speter  if (write_symbols == DWARF_DEBUG)
334718334Speter    TIMEVAR (symout_time,
334818334Speter	     {
334918334Speter	       dwarfout_finish ();
335018334Speter	     });
335118334Speter#endif
335218334Speter
335350615Sobrien#ifdef DWARF2_UNWIND_INFO
335450615Sobrien  if (dwarf2out_do_frame ())
335550615Sobrien    dwarf2out_frame_finish ();
335650615Sobrien#endif
335750615Sobrien
335850615Sobrien#ifdef DWARF2_DEBUGGING_INFO
335950615Sobrien  if (write_symbols == DWARF2_DEBUG)
336050615Sobrien    TIMEVAR (symout_time,
336150615Sobrien	     {
336250615Sobrien	       dwarf2out_finish ();
336350615Sobrien	     });
336450615Sobrien#endif
336550615Sobrien
336618334Speter  /* Output some stuff at end of file if nec.  */
336718334Speter
336850615Sobrien  end_final (dump_base_name);
336950615Sobrien
337050615Sobrien  if (branch_prob_dump)
337150615Sobrien    open_dump_file (".bp", NULL);
337250615Sobrien
337350615Sobrien  TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
337450615Sobrien
337550615Sobrien  if (branch_prob_dump)
337650615Sobrien    close_dump_file (NULL, NULL_RTX);
337750615Sobrien
337818334Speter#ifdef ASM_FILE_END
337950615Sobrien  ASM_FILE_END (asm_out_file);
338018334Speter#endif
338118334Speter
338252558Sobrien
338318334Speter  /* Language-specific end of compilation actions.  */
338452558Sobrien finish_syntax:
338518334Speter  lang_finish ();
338618334Speter
338718334Speter  /* Close the dump files.  */
338818334Speter
338918334Speter  if (flag_gen_aux_info)
339018334Speter    {
339118334Speter      fclose (aux_info_file);
339218334Speter      if (errorcount)
339318334Speter	unlink (aux_info_file_name);
339418334Speter    }
339518334Speter
339618334Speter  if (combine_dump)
339718334Speter    {
339850615Sobrien      open_dump_file (".combine", NULL);
339950615Sobrien      TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
340050615Sobrien      close_dump_file (NULL, NULL_RTX);
340118334Speter    }
340218334Speter
340318334Speter  /* Close non-debugging input and output files.  Take special care to note
340418334Speter     whether fclose returns an error, since the pages might still be on the
340518334Speter     buffer chain while the file is open.  */
340618334Speter
340750615Sobrien  finish_parse ();
340850615Sobrien
340952558Sobrien  if (! flag_syntax_only
341052558Sobrien      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
341118334Speter    fatal_io_error (asm_file_name);
341218334Speter
341352558Sobrien  /* Do whatever is necessary to finish printing the graphs.  */
341452558Sobrien  if (graph_dump_format != no_graph)
341552558Sobrien    {
341652558Sobrien      if (jump_opt_dump)
341752558Sobrien	finish_graph_dump_file (dump_base_name, ".jump");
341852558Sobrien      if (addressof_dump)
341952558Sobrien	finish_graph_dump_file (dump_base_name, ".addressof");
342052558Sobrien      if (cse_dump)
342152558Sobrien	finish_graph_dump_file (dump_base_name, ".cse");
342252558Sobrien      if (loop_dump)
342352558Sobrien	finish_graph_dump_file (dump_base_name, ".loop");
342452558Sobrien      if (cse2_dump)
342552558Sobrien	finish_graph_dump_file (dump_base_name, ".cse2");
342652558Sobrien      if (branch_prob_dump)
342752558Sobrien	finish_graph_dump_file (dump_base_name, ".bp");
342852558Sobrien      if (flow_dump)
342952558Sobrien	finish_graph_dump_file (dump_base_name, ".flow");
343052558Sobrien      if (combine_dump)
343152558Sobrien	finish_graph_dump_file (dump_base_name, ".combine");
343252558Sobrien      if (regmove_dump)
343352558Sobrien	finish_graph_dump_file (dump_base_name, ".regmove");
343452558Sobrien      if (sched_dump)
343552558Sobrien	finish_graph_dump_file (dump_base_name, ".sched");
343652558Sobrien      if (local_reg_dump)
343752558Sobrien	finish_graph_dump_file (dump_base_name, ".lreg");
343852558Sobrien      if (global_reg_dump)
343952558Sobrien	finish_graph_dump_file (dump_base_name, ".greg");
344052558Sobrien      if (flow2_dump)
344152558Sobrien	finish_graph_dump_file (dump_base_name, ".flow2");
344252558Sobrien      if (sched2_dump)
344352558Sobrien	finish_graph_dump_file (dump_base_name, ".sched2");
344452558Sobrien      if (jump2_opt_dump)
344552558Sobrien	finish_graph_dump_file (dump_base_name, ".jump2");
344652558Sobrien#ifdef DELAY_SLOTS
344752558Sobrien      if (dbr_sched_dump)
344852558Sobrien	finish_graph_dump_file (dump_base_name, ".dbr");
344952558Sobrien#endif
345052558Sobrien      if (gcse_dump)
345152558Sobrien	finish_graph_dump_file (dump_base_name, ".gcse");
345252558Sobrien#ifdef STACK_REGS
345352558Sobrien      if (stack_reg_dump)
345452558Sobrien	finish_graph_dump_file (dump_base_name, ".stack");
345552558Sobrien#endif
345652558Sobrien#ifdef MACHINE_DEPENDENT_REORG
345752558Sobrien      if (mach_dep_reorg_dump)
345852558Sobrien	finish_graph_dump_file (dump_base_name, ".mach");
345952558Sobrien#endif
346052558Sobrien    }
346152558Sobrien
346252558Sobrien  /* Free up memory for the benefit of leak detectors.  */
346352558Sobrien  free_reg_info ();
346452558Sobrien
346518334Speter  /* Print the times.  */
346618334Speter
346718334Speter  if (! quiet_flag)
346818334Speter    {
346918334Speter      fprintf (stderr,"\n");
347018334Speter      print_time ("parse", parse_time);
347118334Speter
347250615Sobrien      print_time ("integration", integration_time);
347350615Sobrien      print_time ("jump", jump_time);
347450615Sobrien      print_time ("cse", cse_time);
347550615Sobrien      print_time ("gcse", gcse_time);
347650615Sobrien      print_time ("loop", loop_time);
347750615Sobrien      print_time ("cse2", cse2_time);
347850615Sobrien      print_time ("branch-prob", branch_prob_time);
347950615Sobrien      print_time ("flow", flow_time);
348050615Sobrien      print_time ("combine", combine_time);
348150615Sobrien      print_time ("regmove", regmove_time);
348250615Sobrien      print_time ("sched", sched_time);
348350615Sobrien      print_time ("local-alloc", local_alloc_time);
348450615Sobrien      print_time ("global-alloc", global_alloc_time);
348552558Sobrien      print_time ("flow2", flow2_time);
348650615Sobrien      print_time ("sched2", sched2_time);
348750615Sobrien#ifdef DELAY_SLOTS
348850615Sobrien      print_time ("dbranch", dbr_sched_time);
348950615Sobrien#endif
349050615Sobrien      print_time ("shorten-branch", shorten_branch_time);
349150615Sobrien      print_time ("stack-reg", stack_reg_time);
349250615Sobrien      print_time ("final", final_time);
349350615Sobrien      print_time ("varconst", varconst_time);
349450615Sobrien      print_time ("symout", symout_time);
349550615Sobrien      print_time ("dump", dump_time);
349618334Speter    }
349718334Speter}
349818334Speter
349918334Speter/* This is called from various places for FUNCTION_DECL, VAR_DECL,
350018334Speter   and TYPE_DECL nodes.
350118334Speter
350218334Speter   This does nothing for local (non-static) variables.
350318334Speter   Otherwise, it sets up the RTL and outputs any assembler code
350418334Speter   (label definition, storage allocation and initialization).
350518334Speter
350618334Speter   DECL is the declaration.  If ASMSPEC is nonzero, it specifies
350718334Speter   the assembler symbol name to be used.  TOP_LEVEL is nonzero
350818334Speter   if this declaration is not within a function.  */
350918334Speter
351018334Spetervoid
351118334Speterrest_of_decl_compilation (decl, asmspec, top_level, at_end)
351218334Speter     tree decl;
351352558Sobrien     const char *asmspec;
351418334Speter     int top_level;
351518334Speter     int at_end;
351618334Speter{
351718334Speter  /* Declarations of variables, and of functions defined elsewhere.  */
351818334Speter
351918334Speter/* The most obvious approach, to put an #ifndef around where
352018334Speter   this macro is used, doesn't work since it's inside a macro call.  */
352118334Speter#ifndef ASM_FINISH_DECLARE_OBJECT
352218334Speter#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
352318334Speter#endif
352418334Speter
352518334Speter  /* Forward declarations for nested functions are not "external",
352618334Speter     but we need to treat them as if they were.  */
352718334Speter  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
352818334Speter      || TREE_CODE (decl) == FUNCTION_DECL)
352918334Speter    TIMEVAR (varconst_time,
353018334Speter	     {
353118334Speter	       make_decl_rtl (decl, asmspec, top_level);
353218334Speter	       /* Initialized extern variable exists to be replaced
353318334Speter		  with its value, or represents something that will be
353418334Speter		  output in another file.  */
353518334Speter	       if (! (TREE_CODE (decl) == VAR_DECL
353618334Speter		      && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
353718334Speter		      && DECL_INITIAL (decl) != 0
353818334Speter		      && DECL_INITIAL (decl) != error_mark_node))
353918334Speter		 /* Don't output anything
354018334Speter		    when a tentative file-scope definition is seen.
354118334Speter		    But at end of compilation, do output code for them.  */
354218334Speter		 if (! (! at_end && top_level
354318334Speter			&& (DECL_INITIAL (decl) == 0
354418334Speter			    || DECL_INITIAL (decl) == error_mark_node)))
354518334Speter		   assemble_variable (decl, top_level, at_end, 0);
354618334Speter	       if (decl == last_assemble_variable_decl)
354718334Speter		 {
354818334Speter		   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
354918334Speter					      top_level, at_end);
355018334Speter		 }
355118334Speter	     });
355218334Speter  else if (DECL_REGISTER (decl) && asmspec != 0)
355318334Speter    {
355418334Speter      if (decode_reg_name (asmspec) >= 0)
355518334Speter	{
355618334Speter	  DECL_RTL (decl) = 0;
355718334Speter	  make_decl_rtl (decl, asmspec, top_level);
355818334Speter	}
355918334Speter      else
356018334Speter	error ("invalid register name `%s' for register variable", asmspec);
356118334Speter    }
356218334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
356318334Speter  else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
356418334Speter	   && TREE_CODE (decl) == TYPE_DECL)
356518334Speter    TIMEVAR (symout_time, dbxout_symbol (decl, 0));
356618334Speter#endif
356718334Speter#ifdef SDB_DEBUGGING_INFO
356818334Speter  else if (write_symbols == SDB_DEBUG && top_level
356918334Speter	   && TREE_CODE (decl) == TYPE_DECL)
357018334Speter    TIMEVAR (symout_time, sdbout_symbol (decl, 0));
357118334Speter#endif
357218334Speter}
357318334Speter
357418334Speter/* Called after finishing a record, union or enumeral type.  */
357518334Speter
357618334Spetervoid
357718334Speterrest_of_type_compilation (type, toplev)
357852558Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
357918334Speter     tree type;
358018334Speter     int toplev;
358152558Sobrien#else
358252558Sobrien     tree type ATTRIBUTE_UNUSED;
358352558Sobrien     int toplev ATTRIBUTE_UNUSED;
358452558Sobrien#endif
358518334Speter{
358618334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
358718334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
358818334Speter    TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
358918334Speter#endif
359018334Speter#ifdef SDB_DEBUGGING_INFO
359118334Speter  if (write_symbols == SDB_DEBUG)
359218334Speter    TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
359318334Speter#endif
359418334Speter}
359518334Speter
359618334Speter/* This is called from finish_function (within yyparse)
359718334Speter   after each top-level definition is parsed.
359818334Speter   It is supposed to compile that function or variable
359918334Speter   and output the assembler code for it.
360018334Speter   After we return, the tree storage is freed.  */
360118334Speter
360218334Spetervoid
360318334Speterrest_of_compilation (decl)
360418334Speter     tree decl;
360518334Speter{
360618334Speter  register rtx insns;
360718334Speter  int start_time = get_run_time ();
360818334Speter  int tem;
360918334Speter  /* Nonzero if we have saved the original DECL_INITIAL of the function,
361018334Speter     to be restored after we finish compiling the function
361118334Speter     (for use when compiling inline calls to this function).  */
361218334Speter  tree saved_block_tree = 0;
361318334Speter  /* Likewise, for DECL_ARGUMENTS.  */
361418334Speter  tree saved_arguments = 0;
361518334Speter  int failure = 0;
361652558Sobrien  int rebuild_label_notes_after_reload;
361718334Speter
361818334Speter  /* If we are reconsidering an inline function
361918334Speter     at the end of compilation, skip the stuff for making it inline.  */
362018334Speter
362118334Speter  if (DECL_SAVED_INSNS (decl) == 0)
362218334Speter    {
362350615Sobrien      int inlinable = 0;
362452558Sobrien      const char *lose;
362518334Speter
362618334Speter      /* If requested, consider whether to make this function inline.  */
362750615Sobrien      if (DECL_INLINE (decl) || flag_inline_functions)
362818334Speter	TIMEVAR (integration_time,
362918334Speter		 {
363018334Speter		   lose = function_cannot_inline_p (decl);
363118334Speter		   if (lose || ! optimize)
363218334Speter		     {
363350615Sobrien		       if (warn_inline && DECL_INLINE (decl))
363418334Speter			 warning_with_decl (decl, lose);
363518334Speter		       DECL_ABSTRACT_ORIGIN (decl) = 0;
363618334Speter		       /* Don't really compile an extern inline function.
363718334Speter			  If we can't make it inline, pretend
363818334Speter			  it was only declared.  */
363918334Speter		       if (DECL_EXTERNAL (decl))
364018334Speter			 {
364118334Speter			   DECL_INITIAL (decl) = 0;
364218334Speter			   goto exit_rest_of_compilation;
364318334Speter			 }
364418334Speter		     }
364518334Speter		   else
364650615Sobrien		     /* ??? Note that this has the effect of making it look
364750615Sobrien			like "inline" was specified for a function if we choose
364850615Sobrien			to inline it.  This isn't quite right, but it's
364950615Sobrien			probably not worth the trouble to fix.  */
365050615Sobrien		     inlinable = DECL_INLINE (decl) = 1;
365118334Speter		 });
365218334Speter
365318334Speter      insns = get_insns ();
365418334Speter
365518334Speter      /* Dump the rtl code if we are dumping rtl.  */
365618334Speter
365718334Speter      if (rtl_dump)
365850615Sobrien	{
365950615Sobrien	  open_dump_file (".rtl", decl_printable_name (decl, 2));
366050615Sobrien
366150615Sobrien	  if (DECL_SAVED_INSNS (decl))
366250615Sobrien	    fprintf (rtl_dump_file, ";; (integrable)\n\n");
366350615Sobrien
366450615Sobrien	  close_dump_file (print_rtl, insns);
366550615Sobrien	}
366618334Speter
366750615Sobrien      /* If we can, defer compiling inlines until EOF.
366850615Sobrien	 save_for_inline_copying can be extremely expensive.  */
366950615Sobrien      if (inlinable && ! decl_function_context (decl))
367050615Sobrien	DECL_DEFER_OUTPUT (decl) = 1;
367150615Sobrien
367218334Speter      /* If function is inline, and we don't yet know whether to
367318334Speter	 compile it by itself, defer decision till end of compilation.
367418334Speter	 finish_compilation will call rest_of_compilation again
367518334Speter	 for those functions that need to be output.  Also defer those
367650615Sobrien	 functions that we are supposed to defer.  We cannot defer
367750615Sobrien	 functions containing nested functions since the nested function
367850615Sobrien	 data is in our non-saved obstack.  We cannot defer nested
367950615Sobrien	 functions for the same reason.  */
368018334Speter
368150615Sobrien      /* If this is a nested inline, remove ADDRESSOF now so we can
368250615Sobrien	 finish compiling ourselves.  Otherwise, wait until EOF.
368350615Sobrien	 We have to do this because the purge_addressof transformation
368450615Sobrien	 changes the DECL_RTL for many variables, which confuses integrate.  */
368550615Sobrien      if (inlinable)
368618334Speter	{
368750615Sobrien	  if (decl_function_context (decl))
368850615Sobrien	    purge_addressof (insns);
368950615Sobrien	  else
369050615Sobrien	    DECL_DEFER_OUTPUT (decl) = 1;
369150615Sobrien	}
369250615Sobrien
369350615Sobrien      if (! current_function_contains_functions
369450615Sobrien	  && (DECL_DEFER_OUTPUT (decl)
369550615Sobrien	      || (DECL_INLINE (decl)
369650615Sobrien		  && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
369750615Sobrien		       && ! flag_keep_inline_functions)
369850615Sobrien		      || DECL_EXTERNAL (decl)))))
369950615Sobrien	{
370018334Speter	  DECL_DEFER_OUTPUT (decl) = 1;
370118334Speter
370250615Sobrien	  /* If -Wreturn-type, we have to do a bit of compilation.
370350615Sobrien	     However, if we just fall through we will call
370450615Sobrien	     save_for_inline_copying() which results in excessive
370550615Sobrien	     memory use.  Instead, we just want to call
370650615Sobrien	     jump_optimize() to figure out whether or not we can fall
370750615Sobrien	     off the end of the function; we do the minimum amount of
370850615Sobrien	     work necessary to make that safe.  And, we set optimize
370950615Sobrien	     to zero to keep jump_optimize from working too hard.  */
371050615Sobrien	  if (warn_return_type)
371118334Speter	    {
371250615Sobrien	      int saved_optimize = optimize;
371350615Sobrien	      optimize = 0;
371450615Sobrien	      find_exception_handler_labels ();
371550615Sobrien	      jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
371650615Sobrien			     !JUMP_AFTER_REGSCAN);
371750615Sobrien	      optimize = saved_optimize;
371850615Sobrien	    }
371950615Sobrien
372018334Speter#ifdef DWARF_DEBUGGING_INFO
372150615Sobrien	  /* Generate the DWARF info for the "abstract" instance
372250615Sobrien	     of a function which we may later generate inlined and/or
372350615Sobrien	     out-of-line instances of.  */
372450615Sobrien	  if (write_symbols == DWARF_DEBUG)
372550615Sobrien	    {
372650615Sobrien	      set_decl_abstract_flags (decl, 1);
372750615Sobrien	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
372850615Sobrien	      set_decl_abstract_flags (decl, 0);
372950615Sobrien	    }
373018334Speter#endif
373150615Sobrien#ifdef DWARF2_DEBUGGING_INFO
373250615Sobrien	  /* Generate the DWARF2 info for the "abstract" instance
373350615Sobrien	     of a function which we may later generate inlined and/or
373450615Sobrien	     out-of-line instances of.  */
373550615Sobrien	  if (write_symbols == DWARF2_DEBUG)
373650615Sobrien	    {
373750615Sobrien	      set_decl_abstract_flags (decl, 1);
373850615Sobrien	      TIMEVAR (symout_time, dwarf2out_decl (decl));
373950615Sobrien	      set_decl_abstract_flags (decl, 0);
374018334Speter	    }
374150615Sobrien#endif
374250615Sobrien	  TIMEVAR (integration_time, save_for_inline_nocopy (decl));
374350615Sobrien	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
374450615Sobrien	  goto exit_rest_of_compilation;
374518334Speter	}
374618334Speter
374718334Speter      /* If we have to compile the function now, save its rtl and subdecls
374818334Speter	 so that its compilation will not affect what others get.  */
374950615Sobrien      if (inlinable || DECL_DEFER_OUTPUT (decl))
375018334Speter	{
375118334Speter#ifdef DWARF_DEBUGGING_INFO
375218334Speter	  /* Generate the DWARF info for the "abstract" instance of
375318334Speter	     a function which we will generate an out-of-line instance
375418334Speter	     of almost immediately (and which we may also later generate
375518334Speter	     various inlined instances of).  */
375618334Speter	  if (write_symbols == DWARF_DEBUG)
375718334Speter	    {
375818334Speter	      set_decl_abstract_flags (decl, 1);
375918334Speter	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
376018334Speter	      set_decl_abstract_flags (decl, 0);
376118334Speter	    }
376218334Speter#endif
376350615Sobrien#ifdef DWARF2_DEBUGGING_INFO
376450615Sobrien	  /* Generate the DWARF2 info for the "abstract" instance of
376550615Sobrien	     a function which we will generate an out-of-line instance
376650615Sobrien	     of almost immediately (and which we may also later generate
376750615Sobrien	     various inlined instances of).  */
376850615Sobrien	  if (write_symbols == DWARF2_DEBUG)
376950615Sobrien	    {
377050615Sobrien	      set_decl_abstract_flags (decl, 1);
377150615Sobrien	      TIMEVAR (symout_time, dwarf2out_decl (decl));
377250615Sobrien	      set_decl_abstract_flags (decl, 0);
377350615Sobrien	    }
377450615Sobrien#endif
377518334Speter	  saved_block_tree = DECL_INITIAL (decl);
377618334Speter	  saved_arguments = DECL_ARGUMENTS (decl);
377718334Speter	  TIMEVAR (integration_time, save_for_inline_copying (decl));
377850615Sobrien	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
377918334Speter	}
378018334Speter
378118334Speter      /* If specified extern inline but we aren't inlining it, we are
378252558Sobrien	 done.  This goes for anything that gets here with DECL_EXTERNAL
378352558Sobrien	 set, not just things with DECL_INLINE.  */
378452558Sobrien      if (DECL_EXTERNAL (decl))
378518334Speter	goto exit_rest_of_compilation;
378618334Speter    }
378718334Speter
378818334Speter  if (! DECL_DEFER_OUTPUT (decl))
378918334Speter    TREE_ASM_WRITTEN (decl) = 1;
379018334Speter
379118334Speter  /* Now that integrate will no longer see our rtl, we need not distinguish
379218334Speter     between the return value of this function and the return value of called
379318334Speter     functions.  */
379418334Speter  rtx_equal_function_value_matters = 0;
379518334Speter
379618334Speter  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
379718334Speter  if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
379818334Speter    {
379918334Speter      goto exit_rest_of_compilation;
380018334Speter    }
380118334Speter
380250615Sobrien  /* Emit code to get eh context, if needed. */
380350615Sobrien  emit_eh_context ();
380418334Speter
380518334Speter#ifdef FINALIZE_PIC
380618334Speter  /* If we are doing position-independent code generation, now
380718334Speter     is the time to output special prologues and epilogues.
380818334Speter     We do not want to do this earlier, because it just clutters
380918334Speter     up inline functions with meaningless insns.  */
381018334Speter  if (flag_pic)
381118334Speter    FINALIZE_PIC;
381218334Speter#endif
381318334Speter
381450615Sobrien  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
381550615Sobrien     Note that that may have been done above, in save_for_inline_copying.
381650615Sobrien     The call to resume_temporary_allocation near the end of this function
381750615Sobrien     goes back to the usual state of affairs.  This must be done after
381850615Sobrien     we've built up any unwinders for exception handling, and done
381950615Sobrien     the FINALIZE_PIC work, if necessary.  */
382050615Sobrien
382150615Sobrien  rtl_in_current_obstack ();
382250615Sobrien
382318334Speter  insns = get_insns ();
382418334Speter
382518334Speter  /* Copy any shared structure that should not be shared.  */
382618334Speter
382772566Sobrien  unshare_all_rtl (current_function_decl, insns);
382818334Speter
382950615Sobrien#ifdef SETJMP_VIA_SAVE_AREA
383050615Sobrien  /* This must be performed before virutal register instantiation.  */
383150615Sobrien  if (current_function_calls_alloca)
383250615Sobrien    optimize_save_area_alloca (insns);
383350615Sobrien#endif
383450615Sobrien
383518334Speter  /* Instantiate all virtual registers.  */
383618334Speter
383718334Speter  instantiate_virtual_regs (current_function_decl, get_insns ());
383818334Speter
383918334Speter  /* See if we have allocated stack slots that are not directly addressable.
384018334Speter     If so, scan all the insns and create explicit address computation
384118334Speter     for all references to such slots.  */
384218334Speter/*   fixup_stack_slots (); */
384318334Speter
384450615Sobrien  /* Find all the EH handlers.  */
384550615Sobrien  find_exception_handler_labels ();
384618334Speter
384750615Sobrien  /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
384850615Sobrien     are initialized and to compute whether control can drop off the end
384950615Sobrien     of the function.  */
385050615Sobrien  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
385150615Sobrien  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
385250615Sobrien				     JUMP_AFTER_REGSCAN));
385318334Speter
385418334Speter  /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
385518334Speter  if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
385618334Speter    goto exit_rest_of_compilation;
385718334Speter
385818334Speter  /* Dump rtl code after jump, if we are doing that.  */
385918334Speter
386050615Sobrien    if (jump_opt_dump)
386150615Sobrien      dump_rtl (".jump", decl, print_rtl, insns);
386218334Speter
386318334Speter  /* Perform common subexpression elimination.
386418334Speter     Nonzero value from `cse_main' means that jumps were simplified
386518334Speter     and some code may now be unreachable, so do
386618334Speter     jump optimization again.  */
386718334Speter
386818334Speter  if (optimize > 0)
386918334Speter    {
387050615Sobrien      if (cse_dump)
387150615Sobrien	open_dump_file (".cse", decl_printable_name (decl, 2));
387250615Sobrien
387318334Speter      TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
387418334Speter
387518334Speter      if (flag_thread_jumps)
387618334Speter	/* Hacks by tiemann & kenner.  */
387718334Speter	TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
387818334Speter
387918334Speter      TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
388050615Sobrien					 0, rtl_dump_file));
388118334Speter      if (tem || optimize > 1)
388250615Sobrien	TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
388350615Sobrien					   !JUMP_NOOP_MOVES,
388450615Sobrien					   !JUMP_AFTER_REGSCAN));
388550615Sobrien
388656392Sobrien      /* Run this after jump optmizations remove all the unreachable code
388756392Sobrien	 so that unreachable code will not keep values live.  */
388856392Sobrien      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
388956392Sobrien
389050615Sobrien      /* Dump rtl code after cse, if we are doing that.  */
389152558Sobrien
389250615Sobrien      if (cse_dump)
389352558Sobrien	{
389452558Sobrien	  close_dump_file (print_rtl, insns);
389552558Sobrien	  if (graph_dump_format != no_graph)
389652558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
389752558Sobrien	}
389818334Speter    }
389918334Speter
390050615Sobrien  purge_addressof (insns);
390150615Sobrien  reg_scan (insns, max_reg_num (), 1);
390218334Speter
390350615Sobrien  if (addressof_dump)
390452558Sobrien    {
390552558Sobrien      dump_rtl (".addressof", decl, print_rtl, insns);
390652558Sobrien      if (graph_dump_format != no_graph)
390752558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
390852558Sobrien    }
390952558Sobrien
391050615Sobrien  /* Perform global cse.  */
391118334Speter
391250615Sobrien  if (optimize > 0 && flag_gcse)
391350615Sobrien    {
391450615Sobrien      if (gcse_dump)
391550615Sobrien	open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
391618334Speter
391752558Sobrien      TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
391852558Sobrien
391952558Sobrien      /* If gcse altered any jumps, rerun jump optimizations to clean
392052558Sobrien	 things up.  */
392152558Sobrien      if (tem)
392252558Sobrien	{
392352558Sobrien	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
392452558Sobrien					     !JUMP_NOOP_MOVES,
392552558Sobrien					     !JUMP_AFTER_REGSCAN));
392652558Sobrien        }
392752558Sobrien
392850615Sobrien      if (gcse_dump)
392952558Sobrien	{
393052558Sobrien	  close_dump_file (print_rtl, insns);
393152558Sobrien	  if (graph_dump_format != no_graph)
393252558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
393352558Sobrien	}
393450615Sobrien    }
393518334Speter  /* Move constant computations out of loops.  */
393618334Speter
393718334Speter  if (optimize > 0)
393818334Speter    {
393950615Sobrien      if (loop_dump)
394050615Sobrien	open_dump_file (".loop", decl_printable_name (decl, 2));
394150615Sobrien
394250615Sobrien      TIMEVAR
394350615Sobrien	(loop_time,
394450615Sobrien	 {
394550615Sobrien	   if (flag_rerun_loop_opt)
394618334Speter	     {
394750615Sobrien	       /* We only want to perform unrolling once.  */
394850615Sobrien
394952558Sobrien	       loop_optimize (insns, rtl_dump_file, 0, 0);
395050615Sobrien
395150615Sobrien
395250615Sobrien	       /* The first call to loop_optimize makes some instructions
395350615Sobrien		  trivially dead.  We delete those instructions now in the
395450615Sobrien		  hope that doing so will make the heuristics in loop work
395550615Sobrien		  better and possibly speed up compilation.  */
395650615Sobrien	       delete_trivially_dead_insns (insns, max_reg_num ());
395718334Speter
395850615Sobrien	       /* The regscan pass is currently necessary as the alias
395950615Sobrien		  analysis code depends on this information.  */
396050615Sobrien	       reg_scan (insns, max_reg_num (), 1);
396150615Sobrien	     }
396252558Sobrien	   loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
396350615Sobrien	 });
396452558Sobrien
396550615Sobrien      /* Dump rtl code after loop opt, if we are doing that.  */
396652558Sobrien
396750615Sobrien      if (loop_dump)
396852558Sobrien	{
396952558Sobrien	  close_dump_file (print_rtl, insns);
397052558Sobrien	  if (graph_dump_format != no_graph)
397152558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
397252558Sobrien	}
397350615Sobrien    }
397418334Speter
397550615Sobrien  if (optimize > 0)
397618334Speter    {
397750615Sobrien      if (cse2_dump)
397850615Sobrien	open_dump_file (".cse2", decl_printable_name (decl, 2));
397952558Sobrien
398050615Sobrien      if (flag_rerun_cse_after_loop)
398150615Sobrien	{
398250615Sobrien	  /* Running another jump optimization pass before the second
398350615Sobrien	     cse pass sometimes simplifies the RTL enough to allow
398450615Sobrien	     the second CSE pass to do a better job.  Jump_optimize can change
398550615Sobrien	     max_reg_num so we must rerun reg_scan afterwards.
398650615Sobrien	     ??? Rework to not call reg_scan so often.  */
398750615Sobrien	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
398850615Sobrien	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
398950615Sobrien					     !JUMP_NOOP_MOVES,
399050615Sobrien					     JUMP_AFTER_REGSCAN));
399150615Sobrien
399250615Sobrien	  TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
399350615Sobrien	  TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
399450615Sobrien					      1, rtl_dump_file));
399550615Sobrien	  if (tem)
399650615Sobrien	    TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
399750615Sobrien					       !JUMP_NOOP_MOVES,
399850615Sobrien					       !JUMP_AFTER_REGSCAN));
399950615Sobrien	}
400018334Speter
400150615Sobrien      if (flag_thread_jumps)
400250615Sobrien	{
400350615Sobrien	  /* This pass of jump threading straightens out code
400450615Sobrien	     that was kinked by loop optimization.  */
400550615Sobrien	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
400650615Sobrien	  TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
400750615Sobrien	}
400852558Sobrien
400950615Sobrien      /* Dump rtl code after cse, if we are doing that.  */
401052558Sobrien
401150615Sobrien      if (cse2_dump)
401252558Sobrien	{
401352558Sobrien	  close_dump_file (print_rtl, insns);
401452558Sobrien	  if (graph_dump_format != no_graph)
401552558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
401652558Sobrien	}
401718334Speter    }
401852558Sobrien
401950615Sobrien  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
402050615Sobrien    {
402150615Sobrien      if (branch_prob_dump)
402250615Sobrien	open_dump_file (".bp", decl_printable_name (decl, 2));
402352558Sobrien
402450615Sobrien      TIMEVAR
402550615Sobrien	(branch_prob_time,
402650615Sobrien	 {
402750615Sobrien	   branch_prob (insns, rtl_dump_file);
402850615Sobrien	 });
402952558Sobrien
403050615Sobrien      if (branch_prob_dump)
403152558Sobrien	{
403252558Sobrien	  close_dump_file (print_rtl, insns);
403352558Sobrien	  if (graph_dump_format != no_graph)
403452558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
403552558Sobrien	}
403650615Sobrien    }
403752558Sobrien
403818334Speter  /* We are no longer anticipating cse in this function, at least.  */
403918334Speter
404018334Speter  cse_not_expected = 1;
404118334Speter
404218334Speter  /* Now we choose between stupid (pcc-like) register allocation
404318334Speter     (if we got the -noreg switch and not -opt)
404418334Speter     and smart register allocation.  */
404518334Speter
404652558Sobrien  if (optimize > 0)		/* Stupid allocation probably won't work */
404718334Speter    obey_regdecls = 0;		/* if optimizations being done.  */
404818334Speter
404918334Speter  regclass_init ();
405018334Speter
405118334Speter  /* Print function header into flow dump now
405218334Speter     because doing the flow analysis makes some of the dump.  */
405318334Speter
405418334Speter  if (flow_dump)
405550615Sobrien    open_dump_file (".flow", decl_printable_name (decl, 2));
405650615Sobrien
405718334Speter  if (obey_regdecls)
405818334Speter    {
405918334Speter      TIMEVAR (flow_time,
406018334Speter	       {
406118334Speter		 regclass (insns, max_reg_num ());
406218334Speter		 stupid_life_analysis (insns, max_reg_num (),
406350615Sobrien				       rtl_dump_file);
406418334Speter	       });
406518334Speter    }
406618334Speter  else
406718334Speter    {
406818334Speter      /* Do control and data flow analysis,
406918334Speter	 and write some of the results to dump file.  */
407018334Speter
407150615Sobrien      TIMEVAR
407250615Sobrien	(flow_time,
407350615Sobrien	 {
407450615Sobrien	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
407552558Sobrien	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
407650615Sobrien	 });
407750615Sobrien
407818334Speter      if (warn_uninitialized)
407918334Speter	{
408018334Speter	  uninitialized_vars_warning (DECL_INITIAL (decl));
408118334Speter	  setjmp_args_warning ();
408218334Speter	}
408318334Speter    }
408418334Speter
408518334Speter  /* Dump rtl after flow analysis.  */
408618334Speter
408718334Speter  if (flow_dump)
408852558Sobrien    {
408952558Sobrien      close_dump_file (print_rtl_with_bb, insns);
409052558Sobrien      if (graph_dump_format != no_graph)
409152558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
409252558Sobrien    }
409352558Sobrien
409452558Sobrien  /* The first life analysis pass has finished.  From now on we can not
409552558Sobrien     generate any new pseudos.  */
409652558Sobrien  no_new_pseudos = 1;
409752558Sobrien
409818334Speter  /* If -opt, try combining insns through substitution.  */
409918334Speter
410018334Speter  if (optimize > 0)
410150615Sobrien    {
410250615Sobrien      TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
410352558Sobrien
410450615Sobrien      /* Dump rtl code after insn combination.  */
410552558Sobrien
410650615Sobrien      if (combine_dump)
410752558Sobrien	{
410852558Sobrien	  dump_rtl (".combine", decl, print_rtl_with_bb, insns);
410952558Sobrien	  if (graph_dump_format != no_graph)
411052558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
411152558Sobrien	}
411250615Sobrien    }
411318334Speter
411450615Sobrien  /* Register allocation pre-pass, to reduce number of moves
411550615Sobrien     necessary for two-address machines.  */
411650615Sobrien  if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
411750615Sobrien    {
411850615Sobrien      if (regmove_dump)
411950615Sobrien	open_dump_file (".regmove", decl_printable_name (decl, 2));
412052558Sobrien
412150615Sobrien      TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
412250615Sobrien					       rtl_dump_file));
412352558Sobrien
412450615Sobrien      if (regmove_dump)
412552558Sobrien	{
412652558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
412752558Sobrien	  if (graph_dump_format != no_graph)
412852558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
412952558Sobrien	}
413050615Sobrien    }
413118334Speter
413218334Speter  /* Print function header into sched dump now
413318334Speter     because doing the sched analysis makes some of the dump.  */
413418334Speter
413518334Speter  if (optimize > 0 && flag_schedule_insns)
413618334Speter    {
413750615Sobrien      if (sched_dump)
413850615Sobrien	open_dump_file (".sched", decl_printable_name (decl, 2));
413952558Sobrien
414018334Speter      /* Do control and data sched analysis,
414118334Speter	 and write some of the results to dump file.  */
414218334Speter
414350615Sobrien      TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
414452558Sobrien
414550615Sobrien      /* Dump rtl after instruction scheduling.  */
414652558Sobrien
414750615Sobrien      if (sched_dump)
414852558Sobrien	{
414952558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
415052558Sobrien	  if (graph_dump_format != no_graph)
415152558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
415252558Sobrien	}
415318334Speter    }
415418334Speter
415552558Sobrien  /* Determine if the current function is a leaf before running reload
415652558Sobrien     since this can impact optimizations done by the prologue and
415752558Sobrien     epilogue thus changing register elimination offsets.  */
415852558Sobrien  current_function_is_leaf = leaf_function_p ();
415952558Sobrien
416018334Speter  /* Unless we did stupid register allocation,
416152558Sobrien     allocate pseudo-regs that are used only within 1 basic block.
416218334Speter
416352558Sobrien     RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
416452558Sobrien     jump optimizer after register allocation and reloading are finished.  */
416552558Sobrien
416618334Speter  if (!obey_regdecls)
416718334Speter    TIMEVAR (local_alloc_time,
416818334Speter	     {
416952558Sobrien	       recompute_reg_usage (insns, ! optimize_size);
417018334Speter	       regclass (insns, max_reg_num ());
417152558Sobrien	       rebuild_label_notes_after_reload = local_alloc ();
417218334Speter	     });
417352558Sobrien  else
417452558Sobrien    rebuild_label_notes_after_reload = 0;
417518334Speter
417618334Speter  /* Dump rtl code after allocating regs within basic blocks.  */
417718334Speter
417818334Speter  if (local_reg_dump)
417950615Sobrien    {
418050615Sobrien      open_dump_file (".lreg", decl_printable_name (decl, 2));
418152558Sobrien
418250615Sobrien      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
418350615Sobrien      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
418452558Sobrien
418550615Sobrien      close_dump_file (print_rtl_with_bb, insns);
418652558Sobrien      if (graph_dump_format != no_graph)
418752558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
418850615Sobrien    }
418918334Speter
419018334Speter  if (global_reg_dump)
419150615Sobrien    open_dump_file (".greg", decl_printable_name (decl, 2));
419218334Speter
419318334Speter  /* Unless we did stupid register allocation,
419418334Speter     allocate remaining pseudo-regs, then do the reload pass
419518334Speter     fixing up any insns that are invalid.  */
419618334Speter
419718334Speter  TIMEVAR (global_alloc_time,
419818334Speter	   {
419918334Speter	     if (!obey_regdecls)
420050615Sobrien	       failure = global_alloc (rtl_dump_file);
420118334Speter	     else
420250615Sobrien	       failure = reload (insns, 0, rtl_dump_file);
420318334Speter	   });
420418334Speter
420518334Speter
420618334Speter  if (failure)
420718334Speter    goto exit_rest_of_compilation;
420818334Speter
420950615Sobrien  /* Do a very simple CSE pass over just the hard registers.  */
421050615Sobrien  if (optimize > 0)
421150615Sobrien    reload_cse_regs (insns);
421250615Sobrien
421352558Sobrien  /* Register allocation and reloading may have turned an indirect jump into
421452558Sobrien     a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
421552558Sobrien     jumping instructions.  */
421652558Sobrien  if (rebuild_label_notes_after_reload)
421752558Sobrien    TIMEVAR (jump_time, rebuild_jump_labels (insns));
421852558Sobrien
421952558Sobrien  /* If optimizing and we are performing instruction scheduling after
422052558Sobrien     reload, then go ahead and split insns now since we are about to
422152558Sobrien     recompute flow information anyway.
422252558Sobrien
422352558Sobrien     reload_cse_regs may expose more splitting opportunities, expecially
422452558Sobrien     for double-word operations.  */
422552558Sobrien  if (optimize > 0 && flag_schedule_insns_after_reload)
422652558Sobrien    {
422752558Sobrien      rtx insn;
422852558Sobrien
422952558Sobrien      for (insn = insns; insn; insn = NEXT_INSN (insn))
423052558Sobrien	{
423152558Sobrien	  rtx last;
423252558Sobrien
423352558Sobrien	  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
423452558Sobrien	    continue;
423552558Sobrien
423652558Sobrien	  last = try_split (PATTERN (insn), insn, 1);
423752558Sobrien
423852558Sobrien	  if (last != insn)
423952558Sobrien	    {
424052558Sobrien	      PUT_CODE (insn, NOTE);
424152558Sobrien	      NOTE_SOURCE_FILE (insn) = 0;
424252558Sobrien	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
424352558Sobrien	    }
424452558Sobrien	}
424552558Sobrien    }
424652558Sobrien
424752558Sobrien  if (global_reg_dump)
424852558Sobrien    {
424952558Sobrien      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
425052558Sobrien      close_dump_file (print_rtl_with_bb, insns);
425152558Sobrien      if (graph_dump_format != no_graph)
425252558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
425352558Sobrien    }
425452558Sobrien
425552558Sobrien  /* Re-create the death notes which were deleted during reload.  */
425652558Sobrien  if (flow2_dump)
425752558Sobrien    open_dump_file (".flow2", decl_printable_name (decl, 2));
425852558Sobrien
425952558Sobrien  if (optimize)
426052558Sobrien    {
426152558Sobrien      TIMEVAR
426252558Sobrien	(flow2_time,
426352558Sobrien	 {
426452558Sobrien	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
426552558Sobrien	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
426652558Sobrien	 });
426752558Sobrien    }
426852558Sobrien
426952558Sobrien  flow2_completed = 1;
427052558Sobrien
427118334Speter  /* On some machines, the prologue and epilogue code, or parts thereof,
427218334Speter     can be represented as RTL.  Doing so lets us schedule insns between
427318334Speter     it and the rest of the code and also allows delayed branch
427418334Speter     scheduling to operate in the epilogue.  */
427518334Speter
427618334Speter  thread_prologue_and_epilogue_insns (insns);
427718334Speter
427852558Sobrien  if (flow2_dump)
427950615Sobrien    {
428050615Sobrien      close_dump_file (print_rtl_with_bb, insns);
428152558Sobrien      if (graph_dump_format != no_graph)
428252558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
428350615Sobrien    }
428452558Sobrien
428518334Speter  if (optimize > 0 && flag_schedule_insns_after_reload)
428618334Speter    {
428718334Speter      if (sched2_dump)
428850615Sobrien	open_dump_file (".sched2", decl_printable_name (decl, 2));
428918334Speter
429018334Speter      /* Do control and data sched analysis again,
429118334Speter	 and write some more of the results to dump file.  */
429218334Speter
429350615Sobrien      TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
429418334Speter
429518334Speter      /* Dump rtl after post-reorder instruction scheduling.  */
429618334Speter
429718334Speter      if (sched2_dump)
429852558Sobrien	{
429952558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
430052558Sobrien	  if (graph_dump_format != no_graph)
430152558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
430252558Sobrien	}
430318334Speter    }
430418334Speter
430518334Speter#ifdef LEAF_REGISTERS
430652558Sobrien  current_function_uses_only_leaf_regs
430752558Sobrien    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
430818334Speter#endif
430918334Speter
431018334Speter  /* One more attempt to remove jumps to .+1
431118334Speter     left by dead-store-elimination.
431218334Speter     Also do cross-jumping this time
431318334Speter     and delete no-op move insns.  */
431418334Speter
431518334Speter  if (optimize > 0)
431618334Speter    {
431750615Sobrien      TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
431850615Sobrien					 JUMP_NOOP_MOVES,
431950615Sobrien					 !JUMP_AFTER_REGSCAN));
432052558Sobrien
432150615Sobrien      /* Dump rtl code after jump, if we are doing that.  */
432250615Sobrien
432350615Sobrien      if (jump2_opt_dump)
432452558Sobrien	{
432552558Sobrien	  dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
432652558Sobrien	  if (graph_dump_format != no_graph)
432752558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
432852558Sobrien	}
432918334Speter    }
433018334Speter
433118334Speter  /* If a machine dependent reorganization is needed, call it.  */
433218334Speter#ifdef MACHINE_DEPENDENT_REORG
433318334Speter   MACHINE_DEPENDENT_REORG (insns);
433450615Sobrien
433550615Sobrien   if (mach_dep_reorg_dump)
433652558Sobrien     {
433752558Sobrien       dump_rtl (".mach", decl, print_rtl_with_bb, insns);
433852558Sobrien       if (graph_dump_format != no_graph)
433952558Sobrien	 print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
434052558Sobrien     }
434118334Speter#endif
434218334Speter
434318334Speter  /* If a scheduling pass for delayed branches is to be done,
434450615Sobrien     call the scheduling code.  */
434518334Speter
434618334Speter#ifdef DELAY_SLOTS
434718334Speter  if (optimize > 0 && flag_delayed_branch)
434818334Speter    {
434952558Sobrien      if (dbr_sched_dump)
435052558Sobrien	open_dump_file (".dbr", decl_printable_name (decl, 2));
435152558Sobrien
435250615Sobrien      TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
435352558Sobrien
435418334Speter      if (dbr_sched_dump)
435552558Sobrien	{
435652558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
435752558Sobrien	  if (graph_dump_format != no_graph)
435852558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
435952558Sobrien	}
436018334Speter    }
436118334Speter#endif
436218334Speter
436318334Speter  /* Shorten branches.  */
436418334Speter  TIMEVAR (shorten_branch_time,
436518334Speter	   {
436618334Speter	     shorten_branches (get_insns ());
436718334Speter	   });
436818334Speter
436918334Speter#ifdef STACK_REGS
437052558Sobrien  if (stack_reg_dump)
437152558Sobrien    open_dump_file (".stack", decl_printable_name (decl, 2));
437252558Sobrien
437350615Sobrien  TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
437450615Sobrien
437518334Speter  if (stack_reg_dump)
437652558Sobrien    {
437752558Sobrien      dump_rtl (".stack", decl, print_rtl_with_bb, insns);
437852558Sobrien      if (graph_dump_format != no_graph)
437952558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
438052558Sobrien    }
438118334Speter#endif
438218334Speter
438318334Speter  /* Now turn the rtl into assembler code.  */
438418334Speter
438518334Speter  TIMEVAR (final_time,
438618334Speter	   {
438718334Speter	     rtx x;
438818334Speter	     char *fnname;
438918334Speter
439018334Speter	     /* Get the function's name, as described by its RTL.
439118334Speter		This may be different from the DECL_NAME name used
439218334Speter		in the source file.  */
439318334Speter
439418334Speter	     x = DECL_RTL (decl);
439518334Speter	     if (GET_CODE (x) != MEM)
439618334Speter	       abort ();
439718334Speter	     x = XEXP (x, 0);
439818334Speter	     if (GET_CODE (x) != SYMBOL_REF)
439918334Speter	       abort ();
440018334Speter	     fnname = XSTR (x, 0);
440118334Speter
440218334Speter	     assemble_start_function (decl, fnname);
440318334Speter	     final_start_function (insns, asm_out_file, optimize);
440418334Speter	     final (insns, asm_out_file, optimize, 0);
440518334Speter	     final_end_function (insns, asm_out_file, optimize);
440618334Speter	     assemble_end_function (decl, fnname);
440750615Sobrien	     if (! quiet_flag)
440850615Sobrien	       fflush (asm_out_file);
440950615Sobrien
441052558Sobrien	     /* Release all memory allocated by flow.  */
441152558Sobrien	     free_basic_block_vars (0);
441252558Sobrien
441350615Sobrien	     /* Release all memory held by regsets now */
441450615Sobrien	     regset_release_memory ();
441518334Speter	   });
441618334Speter
441718334Speter  /* Write DBX symbols if requested */
441818334Speter
441918334Speter  /* Note that for those inline functions where we don't initially
442018334Speter     know for certain that we will be generating an out-of-line copy,
442118334Speter     the first invocation of this routine (rest_of_compilation) will
442218334Speter     skip over this code by doing a `goto exit_rest_of_compilation;'.
442318334Speter     Later on, finish_compilation will call rest_of_compilation again
442418334Speter     for those inline functions that need to have out-of-line copies
442518334Speter     generated.  During that call, we *will* be routed past here.  */
442618334Speter
442718334Speter#ifdef DBX_DEBUGGING_INFO
442818334Speter  if (write_symbols == DBX_DEBUG)
442918334Speter    TIMEVAR (symout_time, dbxout_function (decl));
443018334Speter#endif
443118334Speter
443218334Speter#ifdef DWARF_DEBUGGING_INFO
443318334Speter  if (write_symbols == DWARF_DEBUG)
443418334Speter    TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
443518334Speter#endif
443618334Speter
443750615Sobrien#ifdef DWARF2_DEBUGGING_INFO
443850615Sobrien  if (write_symbols == DWARF2_DEBUG)
443950615Sobrien    TIMEVAR (symout_time, dwarf2out_decl (decl));
444050615Sobrien#endif
444150615Sobrien
444218334Speter exit_rest_of_compilation:
444318334Speter
444452558Sobrien  free_bb_mem ();
444552558Sobrien
444618334Speter  /* In case the function was not output,
444718334Speter     don't leave any temporary anonymous types
444818334Speter     queued up for sdb output.  */
444918334Speter#ifdef SDB_DEBUGGING_INFO
445018334Speter  if (write_symbols == SDB_DEBUG)
445118334Speter    sdbout_types (NULL_TREE);
445218334Speter#endif
445318334Speter
445418334Speter  /* Put back the tree of subblocks and list of arguments
445518334Speter     from before we copied them.
445618334Speter     Code generation and the output of debugging info may have modified
445718334Speter     the copy, but the original is unchanged.  */
445818334Speter
445918334Speter  if (saved_block_tree != 0)
446050615Sobrien    {
446150615Sobrien      DECL_INITIAL (decl) = saved_block_tree;
446250615Sobrien      DECL_ARGUMENTS (decl) = saved_arguments;
446350615Sobrien      DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
446450615Sobrien    }
446518334Speter
446618334Speter  reload_completed = 0;
446752558Sobrien  flow2_completed = 0;
446852558Sobrien  no_new_pseudos = 0;
446918334Speter
447050615Sobrien  TIMEVAR (final_time,
447150615Sobrien	   {
447250615Sobrien	      /* Clear out the insn_length contents now that they are no
447350615Sobrien		 longer valid.  */
447450615Sobrien	      init_insn_lengths ();
447518334Speter
447650615Sobrien	      /* Clear out the real_constant_chain before some of the rtx's
447750615Sobrien		 it runs through become garbage.  */
447850615Sobrien	      clear_const_double_mem ();
447918334Speter
448050615Sobrien	      /* Cancel the effect of rtl_in_current_obstack.  */
448150615Sobrien	      resume_temporary_allocation ();
448218334Speter
448350615Sobrien	      /* Show no temporary slots allocated.  */
448450615Sobrien	      init_temp_slots ();
448550615Sobrien	   });
448618334Speter
448750615Sobrien  /* Make sure volatile mem refs aren't considered valid operands for
448850615Sobrien     arithmetic insns.  We must call this here if this is a nested inline
448950615Sobrien     function, since the above code leaves us in the init_recog state
449050615Sobrien     (from final.c), and the function context push/pop code does not
449150615Sobrien     save/restore volatile_ok.
449218334Speter
449350615Sobrien     ??? Maybe it isn't necessary for expand_start_function to call this
449450615Sobrien     anymore if we do it here?  */
449550615Sobrien
449650615Sobrien  init_recog_no_volatile ();
449750615Sobrien
449818334Speter  /* The parsing time is all the time spent in yyparse
449918334Speter     *except* what is spent in this function.  */
450018334Speter
450118334Speter  parse_time -= get_run_time () - start_time;
450252558Sobrien
450352558Sobrien  /* Reset global variables.  */
450452558Sobrien  free_basic_block_vars (0);
450518334Speter}
450618334Speter
450750615Sobrienstatic void
450850615Sobriendisplay_help ()
450950615Sobrien{
451050615Sobrien  int    undoc;
451152558Sobrien  unsigned long	 i;
451252558Sobrien  const char * lang;
451352558Sobrien
451452558Sobrien#ifndef USE_CPPLIB
451550615Sobrien  printf ("Usage: %s input [switches]\n", progname);
451650615Sobrien  printf ("Switches:\n");
451750615Sobrien#endif
451850615Sobrien  printf ("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n");
451950615Sobrien  printf ("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n");
452050615Sobrien  printf ("  -fcall-saved-<register> Mark <register> as being preserved across functions\n");
452152558Sobrien  printf ("  -finline-limit-<number> Limits the size of inlined functions to <number>\n");
452250615Sobrien
452350615Sobrien  for (i = NUM_ELEM (f_options); i--;)
452450615Sobrien    {
452552558Sobrien      const char * description = f_options[i].description;
452650615Sobrien
452750615Sobrien      if (description != NULL && * description != 0)
452850615Sobrien	printf ("  -f%-21s %s\n",
452950615Sobrien		f_options[i].string, description);
453050615Sobrien    }
453150615Sobrien
453250615Sobrien  printf ("  -O[number]              Set optimisation level to [number]\n");
453350615Sobrien  printf ("  -Os                     Optimise for space rather than speed\n");
453450615Sobrien  printf ("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n");
453550615Sobrien  printf ("  -pedantic-errors        Like -pedantic except that errors are produced\n");
453650615Sobrien  printf ("  -w                      Suppress warnings\n");
453750615Sobrien  printf ("  -W                      Enable extra warnings\n");
453850615Sobrien
453950615Sobrien  for (i = NUM_ELEM (W_options); i--;)
454050615Sobrien    {
454152558Sobrien      const char * description = W_options[i].description;
454250615Sobrien
454350615Sobrien      if (description != NULL && * description != 0)
454450615Sobrien	printf ("  -W%-21s %s\n",
454550615Sobrien		W_options[i].string, description);
454650615Sobrien    }
454750615Sobrien
454850615Sobrien  printf ("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n");
454950615Sobrien  printf ("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n");
455050615Sobrien  printf ("  -p                      Enable function profiling\n");
455150615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
455250615Sobrien  printf ("  -a                      Enable block profiling \n");
455350615Sobrien#endif
455450615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
455550615Sobrien  printf ("  -ax                     Enable jump profiling \n");
455650615Sobrien#endif
455750615Sobrien  printf ("  -o <file>               Place output into <file> \n");
455850615Sobrien  printf ("  -G <number>             Put global and static data smaller than <number>\n");
455950615Sobrien  printf ("                           bytes into a special section (on some targets)\n");
456050615Sobrien
456150615Sobrien  for (i = NUM_ELEM (debug_args); i--;)
456250615Sobrien    {
456350615Sobrien      if (debug_args[i].description != NULL)
456450615Sobrien	printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
456550615Sobrien    }
456650615Sobrien
456750615Sobrien  printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
456850615Sobrien  printf ("  -quiet                  Do not display functions compiled or elapsed time\n");
456950615Sobrien  printf ("  -version                Display the compiler's version\n");
457050615Sobrien  printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
457150615Sobrien  printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
457250615Sobrien#if defined HAIFA || defined INSN_SCHEDULING
457350615Sobrien  printf ("  -sched-verbose-<number> Set the verbosity level of the scheduler\n");
457450615Sobrien#endif
457550615Sobrien  printf ("  --help                  Display this information\n");
457650615Sobrien
457750615Sobrien  undoc = 0;
457850615Sobrien  lang  = "language";
457950615Sobrien
458050615Sobrien  /* Display descriptions of language specific options.
458150615Sobrien     If there is no description, note that there is an undocumented option.
458250615Sobrien     If the description is empty, do not display anything.  (This allows
458350615Sobrien     options to be deliberately undocumented, for whatever reason).
458450615Sobrien     If the option string is missing, then this is a marker, indicating
458552558Sobrien     that the description string is in fact the name of a language, whose
458650615Sobrien     language specific options are to follow.  */
458750615Sobrien
458850615Sobrien  if (NUM_ELEM (documented_lang_options) > 1)
458950615Sobrien    {
459050615Sobrien      printf ("\nLanguage specific options:\n");
459150615Sobrien
459250615Sobrien      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
459350615Sobrien	{
459452558Sobrien	  const char * description = documented_lang_options[i].description;
459552558Sobrien	  const char * option      = documented_lang_options[i].option;
459650615Sobrien
459750615Sobrien	  if (description == NULL)
459852558Sobrien	    {
459952558Sobrien	      undoc = 1;
460052558Sobrien
460152558Sobrien	      if (extra_warnings)
460252558Sobrien		printf ("  %-23.23s [undocumented]\n", option);
460352558Sobrien	    }
460450615Sobrien	  else if (* description == 0)
460550615Sobrien	    continue;
460650615Sobrien	  else if (option == NULL)
460750615Sobrien	    {
460850615Sobrien	      if (undoc)
460950615Sobrien		printf
461050615Sobrien		  ("\nThere are undocumented %s specific options as well.\n",
461150615Sobrien			lang);
461250615Sobrien	      undoc = 0;
461350615Sobrien
461450615Sobrien	      printf ("\n Options for %s:\n", description);
461550615Sobrien
461650615Sobrien	      lang = description;
461750615Sobrien	    }
461850615Sobrien	  else
461950615Sobrien	    printf ("  %-23.23s %s\n", option, description);
462050615Sobrien	}
462150615Sobrien    }
462250615Sobrien
462350615Sobrien  if (undoc)
462450615Sobrien    printf ("\nThere are undocumented %s specific options as well.\n", lang);
462550615Sobrien
462650615Sobrien  if (NUM_ELEM (target_switches) > 1
462750615Sobrien#ifdef TARGET_OPTIONS
462850615Sobrien      || NUM_ELEM (target_options) > 1
462950615Sobrien#endif
463050615Sobrien      )
463150615Sobrien    {
463250615Sobrien      int doc = 0;
463350615Sobrien
463450615Sobrien      undoc = 0;
463550615Sobrien
463650615Sobrien      printf ("\nTarget specific options:\n");
463750615Sobrien
463850615Sobrien      for (i = NUM_ELEM (target_switches); i--;)
463950615Sobrien	{
464052558Sobrien	  const char * option      = target_switches[i].name;
464152558Sobrien	  const char * description = target_switches[i].description;
464250615Sobrien
464352558Sobrien	  if (option == NULL || * option == 0)
464450615Sobrien	    continue;
464550615Sobrien	  else if (description == NULL)
464652558Sobrien	    {
464752558Sobrien	      undoc = 1;
464852558Sobrien
464952558Sobrien	      if (extra_warnings)
465052558Sobrien		printf ("  -m%-21.21s [undocumented]\n", option);
465152558Sobrien	    }
465250615Sobrien	  else if (* description != 0)
465352558Sobrien	    doc += printf ("  -m%-21.21s %s\n", option, description);
465450615Sobrien	}
465550615Sobrien
465650615Sobrien#ifdef TARGET_OPTIONS
465750615Sobrien      for (i = NUM_ELEM (target_options); i--;)
465850615Sobrien	{
465952558Sobrien	  const char * option      = target_options[i].prefix;
466052558Sobrien	  const char * description = target_options[i].description;
466150615Sobrien
466252558Sobrien	  if (option == NULL || * option == 0)
466350615Sobrien	    continue;
466450615Sobrien	  else if (description == NULL)
466552558Sobrien	    {
466652558Sobrien	      undoc = 1;
466752558Sobrien
466852558Sobrien	      if (extra_warnings)
466952558Sobrien		printf ("  -m%-21.21s [undocumented]\n", option);
467052558Sobrien	    }
467150615Sobrien	  else if (* description != 0)
467252558Sobrien	    doc += printf ("  -m%-21.21s %s\n", option, description);
467350615Sobrien	}
467450615Sobrien#endif
467550615Sobrien      if (undoc)
467652558Sobrien	{
467752558Sobrien	  if (doc)
467852558Sobrien	    printf ("\nThere are undocumented target specific options as well.\n");
467952558Sobrien	  else
468052558Sobrien	    printf ("  They exist, but they are not documented.\n");
468152558Sobrien	}
468250615Sobrien    }
468350615Sobrien}
468450615Sobrien
468550615Sobrien/* Compare the user specified 'option' with the language
468650615Sobrien   specific 'lang_option'.  Return true if they match, or
468750615Sobrien   if 'option' is a viable prefix of 'lang_option'.  */
468850615Sobrien
468950615Sobrienstatic int
469050615Sobriencheck_lang_option (option, lang_option)
469150615Sobrien     char * option;
469250615Sobrien     char * lang_option;
469350615Sobrien{
469450615Sobrien  lang_independent_options * indep_options;
469550615Sobrien  int    len;
469670640Sobrien  int    numopts;
469770640Sobrien  long   k;
469852558Sobrien  char * space;
469952558Sobrien
470050615Sobrien  /* Ignore NULL entries.  */
470150615Sobrien  if (option == NULL || lang_option == NULL)
470250615Sobrien    return 0;
470350615Sobrien
470452558Sobrien  if ((space = strchr (lang_option, ' ')) != NULL)
470552558Sobrien    len = space - lang_option;
470652558Sobrien  else
470752558Sobrien    len = strlen (lang_option);
470852558Sobrien
470950615Sobrien  /* If they do not match to the first n characters then fail.  */
471050615Sobrien  if (strncmp (option, lang_option, len) != 0)
471150615Sobrien    return 0;
471252558Sobrien
471350615Sobrien  /* Do not accept a lang option, if it matches a normal -f or -W
471450615Sobrien     option.  Chill defines a -fpack, but we want to support
471550615Sobrien     -fpack-struct.  */
471652558Sobrien
471750615Sobrien  /* An exact match is OK  */
471852558Sobrien  if ((int) strlen (option) == len)
471950615Sobrien    return 1;
472052558Sobrien
472150615Sobrien  /* If it is not an -f or -W option allow the match */
472250615Sobrien  if (option[0] != '-')
472350615Sobrien    return 1;
472452558Sobrien
472550615Sobrien  switch (option[1])
472650615Sobrien    {
472770640Sobrien    case 'f':
472870640Sobrien      indep_options = f_options;
472970640Sobrien      numopts = NUM_ELEM (f_options);
473070640Sobrien      break;
473170640Sobrien    case 'W':
473270640Sobrien      indep_options = W_options;
473370640Sobrien      numopts = NUM_ELEM (W_options);
473470640Sobrien      break;
473550615Sobrien    default:  return 1;
473650615Sobrien    }
473752558Sobrien
473850615Sobrien  /* The option is a -f or -W option.
473950615Sobrien     Skip past the prefix and search for the remainder in the
474050615Sobrien     appropriate table of options.  */
474150615Sobrien  option += 2;
474252558Sobrien
474350615Sobrien  if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
474450615Sobrien    option += 3;
474552558Sobrien
474670640Sobrien  for (k = numopts; k--;)
474750615Sobrien    {
474850615Sobrien      if (!strcmp (option, indep_options[k].string))
474950615Sobrien	{
475050615Sobrien	  /* The option matched a language independent option,
475150615Sobrien	     do not allow the language specific match.  */
475252558Sobrien
475350615Sobrien	  return 0;
475450615Sobrien	}
475550615Sobrien    }
475652558Sobrien
475750615Sobrien  /* The option matches the start of the langauge specific option
475850615Sobrien     and it is not an exact match for a language independent option.  */
475950615Sobrien  return 1;
476050615Sobrien}
476150615Sobrien
476218334Speter/* Entry point of cc1/c++.  Decode command args, then call compile_file.
476318334Speter   Exit code is 35 if can't open files, 34 if fatal error,
476418334Speter   33 if had nonfatal errors, else success.  */
476518334Speter
476618334Speterint
476752558Sobrienmain (argc, argv)
476818334Speter     int argc;
476918334Speter     char **argv;
477018334Speter{
477118334Speter  register int i;
477218334Speter  char *filename = 0;
477318334Speter  int flag_print_mem = 0;
477418334Speter  int version_flag = 0;
477518334Speter  char *p;
477618334Speter
477718334Speter  /* save in case md file wants to emit args as a comment.  */
477818334Speter  save_argc = argc;
477918334Speter  save_argv = argv;
478018334Speter
478118334Speter  p = argv[0] + strlen (argv[0]);
478218334Speter  while (p != argv[0] && p[-1] != '/'
478318334Speter#ifdef DIR_SEPARATOR
478418334Speter	 && p[-1] != DIR_SEPARATOR
478518334Speter#endif
478618334Speter	 )
478718334Speter    --p;
478818334Speter  progname = p;
478918334Speter
479050615Sobrien#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
479118334Speter  /* Get rid of any avoidable limit on stack size.  */
479218334Speter  {
479318334Speter    struct rlimit rlim;
479418334Speter
479550615Sobrien    /* Set the stack limit huge so that alloca does not fail.  */
479618334Speter    getrlimit (RLIMIT_STACK, &rlim);
479718334Speter    rlim.rlim_cur = rlim.rlim_max;
479818334Speter    setrlimit (RLIMIT_STACK, &rlim);
479918334Speter  }
480050615Sobrien#endif
480118334Speter
480252558Sobrien#ifdef HAVE_LC_MESSAGES
480352558Sobrien  setlocale (LC_MESSAGES, "");
480452558Sobrien#endif
480552558Sobrien  (void) bindtextdomain (PACKAGE, localedir);
480652558Sobrien  (void) textdomain (PACKAGE);
480752558Sobrien
480818334Speter  signal (SIGFPE, float_signal);
480918334Speter
481018334Speter#ifdef SIGPIPE
481118334Speter  signal (SIGPIPE, pipe_closed);
481218334Speter#endif
481318334Speter
481418334Speter  decl_printable_name = decl_name;
481552558Sobrien  lang_expand_expr = (lang_expand_expr_t) do_abort;
481618334Speter
481718334Speter  /* Initialize whether `char' is signed.  */
481818334Speter  flag_signed_char = DEFAULT_SIGNED_CHAR;
481918334Speter#ifdef DEFAULT_SHORT_ENUMS
482018334Speter  /* Initialize how much space enums occupy, by default.  */
482118334Speter  flag_short_enums = DEFAULT_SHORT_ENUMS;
482218334Speter#endif
482318334Speter
482450615Sobrien  /* Perform language-specific options intialization.  */
482550615Sobrien  lang_init_options ();
482650615Sobrien
482718334Speter  /* Scan to see what optimization level has been specified.  That will
482818334Speter     determine the default value of many flags.  */
482918334Speter  for (i = 1; i < argc; i++)
483018334Speter    {
483118334Speter      if (!strcmp (argv[i], "-O"))
483218334Speter	{
483318334Speter	  optimize = 1;
483452558Sobrien	  optimize_size = 0;
483518334Speter	}
483618334Speter      else if (argv[i][0] == '-' && argv[i][1] == 'O')
483718334Speter	{
483850615Sobrien	  /* Handle -Os, -O2, -O3, -O69, ...  */
483918334Speter	  char *p = &argv[i][2];
484050615Sobrien
484150615Sobrien	  if ((p[0] == 's') && (p[1] == 0))
484252558Sobrien	    {
484352558Sobrien	      optimize_size = 1;
484452558Sobrien
484552558Sobrien	      /* Optimizing for size forces optimize to be 2. */
484652558Sobrien	      optimize = 2;
484752558Sobrien	    }
484850615Sobrien	  else
484950615Sobrien	    {
485052558Sobrien	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
485152558Sobrien	      if (optimize_val != -1)
485252558Sobrien		{
485352558Sobrien		  optimize = optimize_val;
485458599Sobrien#ifdef __alpha__
485558599Sobrien		  if (optimize > 1)
485658599Sobrien		    {
485758599Sobrien		      #ifdef FORCE_OPTIMIZATION_DOWNGRADE
485858599Sobrien		      optimize = 1;
485958599Sobrien		      warning ("\n***\n***\t-O%d converted to \"-O1\" due to optimizer bugs on this platform\n***\n",
486058599Sobrien			      optimize_val);
486158599Sobrien		      #else
486258599Sobrien		      warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n",
486358599Sobrien			      optimize_val);
486458599Sobrien		      #endif
486558599Sobrien		    }
486669460Sobrien#endif /*__alpha__*/
486752558Sobrien		  optimize_size = 0;
486852558Sobrien		}
486950615Sobrien	    }
487018334Speter	}
487118334Speter    }
487218334Speter
487318334Speter  obey_regdecls = (optimize == 0);
487418334Speter
487518334Speter  if (optimize >= 1)
487618334Speter    {
487718334Speter      flag_defer_pop = 1;
487818334Speter      flag_thread_jumps = 1;
487918334Speter#ifdef DELAY_SLOTS
488018334Speter      flag_delayed_branch = 1;
488118334Speter#endif
488218334Speter#ifdef CAN_DEBUG_WITHOUT_FP
488318334Speter      flag_omit_frame_pointer = 1;
488418334Speter#endif
488518334Speter    }
488618334Speter
488718334Speter  if (optimize >= 2)
488818334Speter    {
488918334Speter      flag_cse_follow_jumps = 1;
489018334Speter      flag_cse_skip_blocks = 1;
489150615Sobrien      flag_gcse = 1;
489218334Speter      flag_expensive_optimizations = 1;
489318334Speter      flag_strength_reduce = 1;
489418334Speter      flag_rerun_cse_after_loop = 1;
489550615Sobrien      flag_rerun_loop_opt = 1;
489618334Speter      flag_caller_saves = 1;
489718334Speter      flag_force_mem = 1;
489818334Speter#ifdef INSN_SCHEDULING
489918334Speter      flag_schedule_insns = 1;
490018334Speter      flag_schedule_insns_after_reload = 1;
490118334Speter#endif
490250615Sobrien      flag_regmove = 1;
490318334Speter    }
490418334Speter
490518334Speter  if (optimize >= 3)
490618334Speter    {
490718334Speter      flag_inline_functions = 1;
490818334Speter    }
490918334Speter
491050615Sobrien  /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
491150615Sobrien     modify it.  */
491250615Sobrien  target_flags = 0;
491350615Sobrien  set_target_switch ("");
491450615Sobrien
491518334Speter#ifdef OPTIMIZATION_OPTIONS
491618334Speter  /* Allow default optimizations to be specified on a per-machine basis.  */
491750615Sobrien  OPTIMIZATION_OPTIONS (optimize, optimize_size);
491818334Speter#endif
491918334Speter
492018334Speter  /* Initialize register usage now so switches may override.  */
492118334Speter  init_reg_sets ();
492218334Speter
492318334Speter  for (i = 1; i < argc; i++)
492418334Speter    {
492550615Sobrien      size_t j;
492650615Sobrien
492718334Speter      /* If this is a language-specific option,
492818334Speter	 decode it in a language-specific way.  */
492950615Sobrien      for (j = NUM_ELEM (documented_lang_options); j--;)
493050615Sobrien	if (check_lang_option (argv[i], documented_lang_options[j].option))
493118334Speter	  break;
493250615Sobrien
493352558Sobrien      if (j != (size_t)-1)
493450615Sobrien	{
493550615Sobrien	  /* If the option is valid for *some* language,
493650615Sobrien	     treat it as valid even if this language doesn't understand it.  */
493750615Sobrien	  int strings_processed = lang_decode_option (argc - i, argv + i);
493850615Sobrien
493950615Sobrien	  if (!strcmp (argv[i], "--help"))
494050615Sobrien	    {
494150615Sobrien	      display_help ();
494250615Sobrien	      exit (0);
494350615Sobrien	    }
494450615Sobrien
494550615Sobrien	  if (strings_processed != 0)
494650615Sobrien	    i += strings_processed - 1;
494750615Sobrien	}
494818334Speter      else if (argv[i][0] == '-' && argv[i][1] != 0)
494918334Speter	{
495018334Speter	  register char *str = argv[i] + 1;
495118334Speter	  if (str[0] == 'Y')
495218334Speter	    str++;
495318334Speter
495418334Speter	  if (str[0] == 'm')
495518334Speter	    set_target_switch (&str[1]);
495618334Speter	  else if (!strcmp (str, "dumpbase"))
495718334Speter	    {
495818334Speter	      dump_base_name = argv[++i];
495918334Speter	    }
496018334Speter	  else if (str[0] == 'd')
496118334Speter	    {
496218334Speter	      register char *p = &str[1];
496318334Speter	      while (*p)
496418334Speter		switch (*p++)
496518334Speter		  {
496618334Speter 		  case 'a':
496750615Sobrien		    branch_prob_dump = 1;
496818334Speter 		    combine_dump = 1;
496950615Sobrien#ifdef DELAY_SLOTS
497018334Speter 		    dbr_sched_dump = 1;
497150615Sobrien#endif
497218334Speter 		    flow_dump = 1;
497352558Sobrien 		    flow2_dump = 1;
497418334Speter 		    global_reg_dump = 1;
497518334Speter 		    jump_opt_dump = 1;
497650615Sobrien 		    addressof_dump = 1;
497718334Speter 		    jump2_opt_dump = 1;
497818334Speter 		    local_reg_dump = 1;
497918334Speter 		    loop_dump = 1;
498050615Sobrien		    regmove_dump = 1;
498118334Speter 		    rtl_dump = 1;
498218334Speter 		    cse_dump = 1, cse2_dump = 1;
498350615Sobrien		    gcse_dump = 1;
498418334Speter 		    sched_dump = 1;
498518334Speter 		    sched2_dump = 1;
498650615Sobrien#ifdef STACK_REGS
498718334Speter		    stack_reg_dump = 1;
498850615Sobrien#endif
498950615Sobrien#ifdef MACHINE_DEPENDENT_REORG
499050615Sobrien		    mach_dep_reorg_dump = 1;
499150615Sobrien#endif
499218334Speter		    break;
499350615Sobrien		  case 'A':
499450615Sobrien		    flag_debug_asm = 1;
499518334Speter		    break;
499650615Sobrien		  case 'b':
499750615Sobrien		    branch_prob_dump = 1;
499850615Sobrien		    break;
499918334Speter		  case 'c':
500018334Speter		    combine_dump = 1;
500118334Speter		    break;
500250615Sobrien#ifdef DELAY_SLOTS
500318334Speter		  case 'd':
500418334Speter		    dbr_sched_dump = 1;
500518334Speter		    break;
500650615Sobrien#endif
500718334Speter		  case 'f':
500818334Speter		    flow_dump = 1;
500918334Speter		    break;
501050615Sobrien		  case 'F':
501150615Sobrien		    addressof_dump = 1;
501250615Sobrien		    break;
501318334Speter		  case 'g':
501418334Speter		    global_reg_dump = 1;
501518334Speter		    break;
501650615Sobrien		  case 'G':
501750615Sobrien		    gcse_dump = 1;
501850615Sobrien		    break;
501918334Speter		  case 'j':
502018334Speter		    jump_opt_dump = 1;
502118334Speter		    break;
502218334Speter		  case 'J':
502318334Speter		    jump2_opt_dump = 1;
502418334Speter		    break;
502550615Sobrien#ifdef STACK_REGS
502650615Sobrien		  case 'k':
502750615Sobrien		    stack_reg_dump = 1;
502850615Sobrien		    break;
502950615Sobrien#endif
503018334Speter		  case 'l':
503118334Speter		    local_reg_dump = 1;
503218334Speter		    break;
503318334Speter		  case 'L':
503418334Speter		    loop_dump = 1;
503518334Speter		    break;
503618334Speter		  case 'm':
503718334Speter		    flag_print_mem = 1;
503818334Speter		    break;
503950615Sobrien#ifdef MACHINE_DEPENDENT_REORG
504050615Sobrien		  case 'M':
504150615Sobrien		    mach_dep_reorg_dump = 1;
504250615Sobrien		    break;
504350615Sobrien#endif
504418334Speter		  case 'p':
504518334Speter		    flag_print_asm_name = 1;
504618334Speter		    break;
504718334Speter		  case 'r':
504818334Speter		    rtl_dump = 1;
504918334Speter		    break;
505050615Sobrien		  case 'R':
505150615Sobrien		    sched2_dump = 1;
505250615Sobrien		    break;
505318334Speter		  case 's':
505418334Speter		    cse_dump = 1;
505518334Speter		    break;
505650615Sobrien		  case 'S':
505750615Sobrien		    sched_dump = 1;
505850615Sobrien		    break;
505918334Speter		  case 't':
506018334Speter		    cse2_dump = 1;
506118334Speter		    break;
506250615Sobrien		  case 'N':
506350615Sobrien		    regmove_dump = 1;
506418334Speter		    break;
506552558Sobrien		  case 'v':
506652558Sobrien		    graph_dump_format = vcg;
506752558Sobrien		    break;
506852558Sobrien		  case 'w':
506952558Sobrien		    flow2_dump = 1;
507052558Sobrien		    break;
507118334Speter		  case 'y':
507218334Speter		    set_yydebug (1);
507318334Speter		    break;
507418334Speter		  case 'x':
507518334Speter		    rtl_dump_and_exit = 1;
507618334Speter		    break;
507752558Sobrien		  case 'D':	/* these are handled by the preprocessor */
507852558Sobrien		  case 'I':
507952558Sobrien		    break;
508050615Sobrien		  default:
508150615Sobrien		    warning ("unrecognised gcc debugging option: %c", p[-1]);
508250615Sobrien		    break;
508318334Speter		  }
508418334Speter	    }
508518334Speter	  else if (str[0] == 'f')
508618334Speter	    {
508718334Speter	      register char *p = &str[1];
508818334Speter	      int found = 0;
508918334Speter
509018334Speter	      /* Some kind of -f option.
509118334Speter		 P's value is the option sans `-f'.
509218334Speter		 Search for it in the table of options.  */
509318334Speter
509418334Speter	      for (j = 0;
509518334Speter		   !found && j < sizeof (f_options) / sizeof (f_options[0]);
509618334Speter		   j++)
509718334Speter		{
509818334Speter		  if (!strcmp (p, f_options[j].string))
509918334Speter		    {
510018334Speter		      *f_options[j].variable = f_options[j].on_value;
510118334Speter		      /* A goto here would be cleaner,
510218334Speter			 but breaks the vax pcc.  */
510318334Speter		      found = 1;
510418334Speter		    }
510518334Speter		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
510618334Speter		      && ! strcmp (p+3, f_options[j].string))
510718334Speter		    {
510818334Speter		      *f_options[j].variable = ! f_options[j].on_value;
510918334Speter		      found = 1;
511018334Speter		    }
511118334Speter		}
511218334Speter
511318334Speter	      if (found)
511418334Speter		;
511552558Sobrien	      else if (!strncmp (p, "inline-limit-", 13))
511652558Sobrien	        inline_max_insns =
511752558Sobrien		  read_integral_parameter (p + 13, p - 2, inline_max_insns);
511850615Sobrien#ifdef HAIFA
511950615Sobrien#ifdef INSN_SCHEDULING
512050615Sobrien	      else if (!strncmp (p, "sched-verbose-",14))
512150615Sobrien		fix_sched_param("verbose",&p[14]);
512250615Sobrien#endif
512350615Sobrien#endif  /* HAIFA */
512418334Speter	      else if (!strncmp (p, "fixed-", 6))
512518334Speter		fix_register (&p[6], 1, 1);
512618334Speter	      else if (!strncmp (p, "call-used-", 10))
512718334Speter		fix_register (&p[10], 0, 1);
512818334Speter	      else if (!strncmp (p, "call-saved-", 11))
512918334Speter		fix_register (&p[11], 0, 0);
513018334Speter	      else
513118334Speter		error ("Invalid option `%s'", argv[i]);
513218334Speter	    }
513318334Speter	  else if (str[0] == 'O')
513418334Speter	    {
513552558Sobrien	      /* Already been treated above. Do nothing.  */
513618334Speter	    }
513718334Speter	  else if (!strcmp (str, "pedantic"))
513818334Speter	    pedantic = 1;
513918334Speter	  else if (!strcmp (str, "pedantic-errors"))
514018334Speter	    flag_pedantic_errors = pedantic = 1;
514118334Speter	  else if (!strcmp (str, "quiet"))
514218334Speter	    quiet_flag = 1;
514318334Speter	  else if (!strcmp (str, "version"))
514418334Speter	    version_flag = 1;
514518334Speter	  else if (!strcmp (str, "w"))
514618334Speter	    inhibit_warnings = 1;
514718334Speter	  else if (!strcmp (str, "W"))
514818334Speter	    {
514918334Speter	      extra_warnings = 1;
515018334Speter	      /* We save the value of warn_uninitialized, since if they put
515118334Speter		 -Wuninitialized on the command line, we need to generate a
515218334Speter		 warning about not using it without also specifying -O.  */
515318334Speter	      if (warn_uninitialized != 1)
515418334Speter		warn_uninitialized = 2;
515518334Speter	    }
515618334Speter	  else if (str[0] == 'W')
515718334Speter	    {
515818334Speter	      register char *p = &str[1];
515918334Speter	      int found = 0;
516018334Speter
516118334Speter	      /* Some kind of -W option.
516218334Speter		 P's value is the option sans `-W'.
516318334Speter		 Search for it in the table of options.  */
516418334Speter
516518334Speter	      for (j = 0;
516618334Speter		   !found && j < sizeof (W_options) / sizeof (W_options[0]);
516718334Speter		   j++)
516818334Speter		{
516918334Speter		  if (!strcmp (p, W_options[j].string))
517018334Speter		    {
517118334Speter		      *W_options[j].variable = W_options[j].on_value;
517218334Speter		      /* A goto here would be cleaner,
517318334Speter			 but breaks the vax pcc.  */
517418334Speter		      found = 1;
517518334Speter		    }
517618334Speter		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
517718334Speter		      && ! strcmp (p+3, W_options[j].string))
517818334Speter		    {
517918334Speter		      *W_options[j].variable = ! W_options[j].on_value;
518018334Speter		      found = 1;
518118334Speter		    }
518218334Speter		}
518318334Speter
518418334Speter	      if (found)
518518334Speter		;
518618334Speter	      else if (!strncmp (p, "id-clash-", 9))
518718334Speter		{
518852558Sobrien		  const int id_clash_val
518952558Sobrien		    = read_integral_parameter (p + 9, p - 2, -1);
519052558Sobrien		  if (id_clash_val != -1)
519118334Speter		    {
519252558Sobrien		      id_clash_len = id_clash_val;
519352558Sobrien		      warn_id_clash = 1;
519418334Speter		    }
519518334Speter		}
519618334Speter	      else if (!strncmp (p, "larger-than-", 12))
519718334Speter		{
519852558Sobrien		  const int larger_than_val
519952558Sobrien		    = read_integral_parameter (p + 12, p - 2, -1);
520052558Sobrien		  if (larger_than_val != -1)
520118334Speter		    {
520252558Sobrien		      larger_than_size = larger_than_val;
520352558Sobrien		      warn_larger_than = 1;
520418334Speter		    }
520518334Speter		}
520618334Speter	      else
520718334Speter		error ("Invalid option `%s'", argv[i]);
520818334Speter	    }
520918334Speter	  else if (!strcmp (str, "p"))
521018334Speter	    {
521150615Sobrien	      profile_flag = 1;
521218334Speter	    }
521318334Speter	  else if (!strcmp (str, "a"))
521418334Speter	    {
521518334Speter#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
521618334Speter	      warning ("`-a' option (basic block profile) not supported");
521718334Speter#else
521850615Sobrien              profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
521918334Speter#endif
522018334Speter	    }
522150615Sobrien	  else if (!strcmp (str, "ax"))
522250615Sobrien	    {
522350615Sobrien#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
522450615Sobrien	      warning ("`-ax' option (jump profiling) not supported");
522550615Sobrien#else
522650615Sobrien	      profile_block_flag = (!profile_block_flag
522750615Sobrien	                               || profile_block_flag == 2) ? 2 : 3;
522850615Sobrien#endif
522950615Sobrien	    }
523018334Speter	  else if (str[0] == 'g')
523118334Speter	    {
523218334Speter	      unsigned level;
523350615Sobrien	      /* A lot of code assumes write_symbols == NO_DEBUG if the
523450615Sobrien		 debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
523550615Sobrien		 of what debugging type has been selected).  This records the
523650615Sobrien		 selected type.  It is an error to specify more than one
523750615Sobrien		 debugging type.  */
523850615Sobrien	      static enum debug_info_type selected_debug_type = NO_DEBUG;
523950615Sobrien	      /* Non-zero if debugging format has been explicitly set.
524050615Sobrien		 -g and -ggdb don't explicitly set the debugging format so
524150615Sobrien		 -gdwarf -g3 is equivalent to -gdwarf3.  */
524250615Sobrien	      static int type_explicitly_set_p = 0;
524350615Sobrien	      /* Indexed by enum debug_info_type.  */
524452558Sobrien	      static const char *debug_type_names[] =
524550615Sobrien	      {
524650615Sobrien		"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
524750615Sobrien	      };
524818334Speter
524952558Sobrien	      /* The maximum admissible debug level value.  */
525052558Sobrien	      static const unsigned max_debug_level = 3;
525152558Sobrien
525250615Sobrien	      /* Look up STR in the table.  */
525350615Sobrien	      for (da = debug_args; da->arg; da++)
525418334Speter		{
525552558Sobrien		  const int da_len = strlen (da->arg);
525652558Sobrien
525752558Sobrien		  if (! strncmp (str, da->arg, da_len))
525850615Sobrien		    {
525950615Sobrien		      enum debug_info_type type = da->debug_type;
526052558Sobrien		      const char *p = str + da_len;
526118334Speter
526250615Sobrien		      if (*p && (*p < '0' || *p > '9'))
526350615Sobrien			continue;
526452558Sobrien
526552558Sobrien		      /* A debug flag without a level defaults to level 2.
526652558Sobrien			 Note we do not want to call read_integral_parameter
526752558Sobrien			 for that case since it will call atoi which
526852558Sobrien			 will return zero.
526952558Sobrien
527052558Sobrien			 ??? We may want to generalize the interface to
527152558Sobrien			 read_integral_parameter to better handle this case
527252558Sobrien			 if this case shows up often.  */
527350615Sobrien		      if (*p)
527452558Sobrien			level = read_integral_parameter (p, 0,
527552558Sobrien							 max_debug_level + 1);
527652558Sobrien		      else
527752558Sobrien			level = 2;
527852558Sobrien
527952558Sobrien		      if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
528050615Sobrien			{
528152558Sobrien			  error ("use -gdwarf -g%d for DWARF v1, level %d",
528252558Sobrien				 level, level);
528352558Sobrien			  if (level == 2)
528452558Sobrien			    error ("use -gdwarf-2   for DWARF v2");
528550615Sobrien			}
528652558Sobrien
528752558Sobrien		      if (level > max_debug_level)
528850615Sobrien			{
528952558Sobrien			  warning ("ignoring option `%s' due to invalid debug level specification",
529052558Sobrien				   str - 1);
529152558Sobrien			  level = debug_info_level;
529250615Sobrien			}
529350615Sobrien
529450615Sobrien		      if (type == NO_DEBUG)
529550615Sobrien			{
529650615Sobrien			  type = PREFERRED_DEBUGGING_TYPE;
529752558Sobrien			  if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
529850615Sobrien			    {
529950615Sobrien#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
530050615Sobrien			      type = DWARF2_DEBUG;
530150615Sobrien#else
530218334Speter#ifdef DBX_DEBUGGING_INFO
530350615Sobrien			      type = DBX_DEBUG;
530450615Sobrien#endif
530550615Sobrien#endif
530650615Sobrien			    }
530750615Sobrien			}
530818334Speter
530950615Sobrien		      if (type == NO_DEBUG)
531050615Sobrien			warning ("`-%s' not supported by this configuration of GCC",
531150615Sobrien				 str);
531218334Speter
531350615Sobrien		      /* Does it conflict with an already selected type?  */
531450615Sobrien		      if (type_explicitly_set_p
531550615Sobrien			  /* -g/-ggdb don't conflict with anything */
531650615Sobrien			  && da->debug_type != NO_DEBUG
531750615Sobrien			  && type != selected_debug_type)
531850615Sobrien			warning ("`-%s' ignored, conflicts with `-g%s'",
531950615Sobrien				 str, debug_type_names[(int) selected_debug_type]);
532050615Sobrien		      else
532150615Sobrien			{
532250615Sobrien			  /* If the format has already been set, -g/-ggdb
532350615Sobrien			     only change the debug level.  */
532450615Sobrien			  if (type_explicitly_set_p
532550615Sobrien			      && da->debug_type == NO_DEBUG)
532650615Sobrien			    ; /* don't change debugging type */
532750615Sobrien			  else
532850615Sobrien			    {
532950615Sobrien			      selected_debug_type = type;
533050615Sobrien			      type_explicitly_set_p = da->debug_type != NO_DEBUG;
533150615Sobrien			    }
533250615Sobrien			  write_symbols = (level == 0
533350615Sobrien					   ? NO_DEBUG
533450615Sobrien					   : selected_debug_type);
533550615Sobrien			  use_gnu_debug_info_extensions = da->use_extensions_p;
533650615Sobrien			  debug_info_level = (enum debug_info_level) level;
533750615Sobrien			}
533850615Sobrien		      break;
533950615Sobrien		    }
534050615Sobrien		}
534150615Sobrien	      if (! da->arg)
534218334Speter		warning ("`-%s' not supported by this configuration of GCC",
534318334Speter			 str);
534418334Speter	    }
534518334Speter	  else if (!strcmp (str, "o"))
534618334Speter	    {
534718334Speter	      asm_file_name = argv[++i];
534818334Speter	    }
534918334Speter	  else if (str[0] == 'G')
535018334Speter	    {
535152558Sobrien	      const int g_switch_val = (str[1] != '\0') ?
535252558Sobrien	                               read_integral_parameter(str + 1, 0, -1) :
535352558Sobrien			               read_integral_parameter(argv[++i], 0, -1);
535452558Sobrien
535552558Sobrien	      if (g_switch_val != -1)
535652558Sobrien	        {
535752558Sobrien		  g_switch_set = TRUE;
535852558Sobrien		  g_switch_value = g_switch_val;
535952558Sobrien		}
536052558Sobrien	      else
536152558Sobrien	        {
536252558Sobrien		  error("Invalid option `-%s'",str);
536352558Sobrien		}
536418334Speter	    }
536518334Speter	  else if (!strncmp (str, "aux-info", 8))
536618334Speter	    {
536718334Speter	      flag_gen_aux_info = 1;
536818334Speter	      aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
536918334Speter	    }
537050615Sobrien	  else if (!strcmp (str, "-help"))
537150615Sobrien	    {
537250615Sobrien	      display_help ();
537350615Sobrien	      exit (0);
537450615Sobrien	    }
537518334Speter	  else
537618334Speter	    error ("Invalid option `%s'", argv[i]);
537718334Speter	}
537818334Speter      else if (argv[i][0] == '+')
537918334Speter	error ("Invalid option `%s'", argv[i]);
538018334Speter      else
538118334Speter	filename = argv[i];
538218334Speter    }
538318334Speter
538450615Sobrien  /* Checker uses the frame pointer.  */
538550615Sobrien  if (flag_check_memory_usage)
538650615Sobrien    flag_omit_frame_pointer = 0;
538718334Speter
538818334Speter  if (optimize == 0)
538918334Speter    {
539018334Speter      /* Inlining does not work if not optimizing,
539118334Speter	 so force it not to be done.  */
539218334Speter      flag_no_inline = 1;
539318334Speter      warn_inline = 0;
539418334Speter
539518334Speter      /* The c_decode_option and lang_decode_option functions set
539618334Speter	 this to `2' if -Wall is used, so we can avoid giving out
539718334Speter	 lots of errors for people who don't realize what -Wall does.  */
539818334Speter      if (warn_uninitialized == 1)
539918334Speter	warning ("-Wuninitialized is not supported without -O");
540018334Speter    }
540118334Speter
540218334Speter#ifdef OVERRIDE_OPTIONS
540318334Speter  /* Some machines may reject certain combinations of options.  */
540418334Speter  OVERRIDE_OPTIONS;
540518334Speter#endif
540618334Speter
540750615Sobrien  if (exceptions_via_longjmp == 2)
540850615Sobrien    {
540950615Sobrien#ifdef DWARF2_UNWIND_INFO
541050615Sobrien      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
541150615Sobrien#else
541250615Sobrien      exceptions_via_longjmp = 1;
541350615Sobrien#endif
541450615Sobrien    }
541550615Sobrien
541650615Sobrien  if (profile_block_flag == 3)
541750615Sobrien    {
541850615Sobrien      warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
541950615Sobrien      profile_block_flag = 2;
542050615Sobrien    }
542150615Sobrien
542218334Speter  /* Unrolling all loops implies that standard loop unrolling must also
542318334Speter     be done.  */
542418334Speter  if (flag_unroll_all_loops)
542518334Speter    flag_unroll_loops = 1;
542618334Speter  /* Loop unrolling requires that strength_reduction be on also.  Silently
542718334Speter     turn on strength reduction here if it isn't already on.  Also, the loop
542818334Speter     unrolling code assumes that cse will be run after loop, so that must
542918334Speter     be turned on also.  */
543018334Speter  if (flag_unroll_loops)
543118334Speter    {
543218334Speter      flag_strength_reduce = 1;
543318334Speter      flag_rerun_cse_after_loop = 1;
543418334Speter    }
543518334Speter
543618334Speter  /* Warn about options that are not supported on this machine.  */
543718334Speter#ifndef INSN_SCHEDULING
543818334Speter  if (flag_schedule_insns || flag_schedule_insns_after_reload)
543918334Speter    warning ("instruction scheduling not supported on this target machine");
544018334Speter#endif
544118334Speter#ifndef DELAY_SLOTS
544218334Speter  if (flag_delayed_branch)
544318334Speter    warning ("this target machine does not have delayed branches");
544418334Speter#endif
544518334Speter
544652558Sobrien  user_label_prefix = USER_LABEL_PREFIX;
544752558Sobrien  if (flag_leading_underscore != -1)
544852558Sobrien    {
544952558Sobrien      /* If the default prefix is more complicated than "" or "_",
545052558Sobrien	 issue a warning and ignore this option.  */
545152558Sobrien      if (user_label_prefix[0] == 0 ||
545252558Sobrien	  (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
545352558Sobrien	{
545452558Sobrien	  user_label_prefix = flag_leading_underscore ? "_" : "";
545552558Sobrien	}
545652558Sobrien      else
545752558Sobrien	warning ("-f%sleading-underscore not supported on this target machine",
545852558Sobrien		 flag_leading_underscore ? "" : "no-");
545952558Sobrien    }
546052558Sobrien
546118334Speter  /* If we are in verbose mode, write out the version and maybe all the
546218334Speter     option flags in use.  */
546318334Speter  if (version_flag)
546418334Speter    {
546550615Sobrien      print_version (stderr, "");
546618334Speter      if (! quiet_flag)
546750615Sobrien	print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
546818334Speter    }
546918334Speter
547018334Speter  compile_file (filename);
547118334Speter
547252558Sobrien#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
547318334Speter  if (flag_print_mem)
547418334Speter    {
547518334Speter      char *lim = (char *) sbrk (0);
547618334Speter
547752558Sobrien      notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
547818334Speter      fflush (stderr);
547918334Speter
548050615Sobrien#ifndef __MSDOS__
548118334Speter#ifdef USG
548218334Speter      system ("ps -l 1>&2");
548318334Speter#else /* not USG */
548418334Speter      system ("ps v");
548518334Speter#endif /* not USG */
548650615Sobrien#endif
548718334Speter    }
548852558Sobrien#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
548918334Speter
549018334Speter  if (errorcount)
549118334Speter    exit (FATAL_EXIT_CODE);
549218334Speter  if (sorrycount)
549318334Speter    exit (FATAL_EXIT_CODE);
549418334Speter  exit (SUCCESS_EXIT_CODE);
549518334Speter  return 0;
549618334Speter}
549718334Speter
549818334Speter/* Decode -m switches.  */
549918334Speter/* Decode the switch -mNAME.  */
550018334Speter
550152558Sobrienstatic void
550218334Speterset_target_switch (name)
550352558Sobrien  const char *name;
550418334Speter{
550550615Sobrien  register size_t j;
550652558Sobrien  int valid_target_option = 0;
550718334Speter
550818334Speter  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
550918334Speter    if (!strcmp (target_switches[j].name, name))
551018334Speter      {
551118334Speter	if (target_switches[j].value < 0)
551218334Speter	  target_flags &= ~-target_switches[j].value;
551318334Speter	else
551418334Speter	  target_flags |= target_switches[j].value;
551552558Sobrien	valid_target_option = 1;
551618334Speter      }
551718334Speter
551818334Speter#ifdef TARGET_OPTIONS
551952558Sobrien  if (!valid_target_option)
552018334Speter    for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
552118334Speter      {
552218334Speter	int len = strlen (target_options[j].prefix);
552318334Speter	if (!strncmp (target_options[j].prefix, name, len))
552418334Speter	  {
552518334Speter	    *target_options[j].variable = name + len;
552652558Sobrien	    valid_target_option = 1;
552718334Speter	  }
552818334Speter      }
552918334Speter#endif
553018334Speter
553152558Sobrien  if (!valid_target_option)
553218334Speter    error ("Invalid option `%s'", name);
553318334Speter}
553418334Speter
553550615Sobrien/* Print version information to FILE.
553650615Sobrien   Each line begins with INDENT (for the case where FILE is the
553750615Sobrien   assembler output file).  */
553818334Speter
553952558Sobrienstatic void
554050615Sobrienprint_version (file, indent)
554150615Sobrien     FILE *file;
554252558Sobrien     const char *indent;
554350615Sobrien{
554450615Sobrien#ifndef __VERSION__
554552558Sobrien#define __VERSION__ "[?]"
554650615Sobrien#endif
554752558Sobrien  fnotice (file,
554852558Sobrien#ifdef __GNUC__
554952558Sobrien	   "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
555050615Sobrien#else
555152558Sobrien	   "%s%s%s version %s (%s) compiled by CC.\n"
555250615Sobrien#endif
555352558Sobrien	   , indent, *indent != 0 ? " " : "",
555452558Sobrien	   language_string, version_string, TARGET_NAME, __VERSION__);
555550615Sobrien}
555618334Speter
555750615Sobrien/* Print an option value and return the adjusted position in the line.
555850615Sobrien   ??? We don't handle error returns from fprintf (disk full); presumably
555950615Sobrien   other code will catch a disk full though.  */
556018334Speter
556152558Sobrienstatic int
556250615Sobrienprint_single_switch (file, pos, max, indent, sep, term, type, name)
556350615Sobrien     FILE *file;
556450615Sobrien     int pos, max;
556552558Sobrien     const char *indent, *sep, *term, *type, *name;
556618334Speter{
556750615Sobrien  /* The ultrix fprintf returns 0 on success, so compute the result we want
556850615Sobrien     here since we need it for the following test.  */
556950615Sobrien  int len = strlen (sep) + strlen (type) + strlen (name);
557018334Speter
557150615Sobrien  if (pos != 0
557250615Sobrien      && pos + len > max)
557318334Speter    {
557450615Sobrien      fprintf (file, "%s", term);
557550615Sobrien      pos = 0;
557618334Speter    }
557750615Sobrien  if (pos == 0)
557850615Sobrien    {
557950615Sobrien      fprintf (file, "%s", indent);
558050615Sobrien      pos = strlen (indent);
558150615Sobrien    }
558250615Sobrien  fprintf (file, "%s%s%s", sep, type, name);
558350615Sobrien  pos += len;
558450615Sobrien  return pos;
558518334Speter}
558618334Speter
558750615Sobrien/* Print active target switches to FILE.
558850615Sobrien   POS is the current cursor position and MAX is the size of a "line".
558950615Sobrien   Each line begins with INDENT and ends with TERM.
559050615Sobrien   Each switch is separated from the next by SEP.  */
559118334Speter
559252558Sobrienstatic void
559350615Sobrienprint_switch_values (file, pos, max, indent, sep, term)
559450615Sobrien     FILE *file;
559550615Sobrien     int pos, max;
559652558Sobrien     const char *indent, *sep, *term;
559718334Speter{
559850615Sobrien  size_t j;
559950615Sobrien  char **p;
560018334Speter
560150615Sobrien  /* Print the options as passed.  */
560218334Speter
560350615Sobrien  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
560452558Sobrien			     _("options passed: "), "");
560550615Sobrien
560650615Sobrien  for (p = &save_argv[1]; *p != NULL; p++)
560750615Sobrien    if (**p == '-')
560850615Sobrien      {
560950615Sobrien	/* Ignore these.  */
561050615Sobrien	if (strcmp (*p, "-o") == 0)
561150615Sobrien	  {
561250615Sobrien	    if (p[1] != NULL)
561350615Sobrien	      p++;
561450615Sobrien	    continue;
561550615Sobrien	  }
561650615Sobrien	if (strcmp (*p, "-quiet") == 0)
561750615Sobrien	  continue;
561850615Sobrien	if (strcmp (*p, "-version") == 0)
561950615Sobrien	  continue;
562050615Sobrien	if ((*p)[1] == 'd')
562150615Sobrien	  continue;
562250615Sobrien
562350615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
562450615Sobrien      }
562550615Sobrien  if (pos > 0)
562650615Sobrien    fprintf (file, "%s", term);
562750615Sobrien
562850615Sobrien  /* Print the -f and -m options that have been enabled.
562950615Sobrien     We don't handle language specific options but printing argv
563050615Sobrien     should suffice.  */
563150615Sobrien
563250615Sobrien  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
563352558Sobrien			     _("options enabled: "), "");
563450615Sobrien
563518334Speter  for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
563618334Speter    if (*f_options[j].variable == f_options[j].on_value)
563750615Sobrien      pos = print_single_switch (file, pos, max, indent, sep, term,
563850615Sobrien				 "-f", f_options[j].string);
563918334Speter
564050615Sobrien  /* Print target specific options.  */
564118334Speter
564218334Speter  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
564318334Speter    if (target_switches[j].name[0] != '\0'
564418334Speter	&& target_switches[j].value > 0
564518334Speter	&& ((target_switches[j].value & target_flags)
564618334Speter	    == target_switches[j].value))
564750615Sobrien      {
564850615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term,
564950615Sobrien				   "-m", target_switches[j].name);
565050615Sobrien      }
565118334Speter
565250615Sobrien#ifdef TARGET_OPTIONS
565350615Sobrien  for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
565450615Sobrien    if (*target_options[j].variable != NULL)
565550615Sobrien      {
565650615Sobrien	char prefix[256];
565750615Sobrien	sprintf (prefix, "-m%s", target_options[j].prefix);
565850615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term,
565950615Sobrien				   prefix, *target_options[j].variable);
566050615Sobrien      }
566150615Sobrien#endif
566250615Sobrien
566350615Sobrien  fprintf (file, "%s", term);
566418334Speter}
566550615Sobrien
566650615Sobrien/* Record the beginning of a new source file, named FILENAME.  */
566750615Sobrien
566850615Sobrienvoid
566950615Sobriendebug_start_source_file (filename)
567052558Sobrien     register char *filename ATTRIBUTE_UNUSED;
567150615Sobrien{
567250615Sobrien#ifdef DBX_DEBUGGING_INFO
567350615Sobrien  if (write_symbols == DBX_DEBUG)
567450615Sobrien    dbxout_start_new_source_file (filename);
567550615Sobrien#endif
567650615Sobrien#ifdef DWARF_DEBUGGING_INFO
567750615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
567850615Sobrien      && write_symbols == DWARF_DEBUG)
567950615Sobrien    dwarfout_start_new_source_file (filename);
568050615Sobrien#endif /* DWARF_DEBUGGING_INFO */
568150615Sobrien#ifdef DWARF2_DEBUGGING_INFO
568250615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
568350615Sobrien      && write_symbols == DWARF2_DEBUG)
568450615Sobrien    dwarf2out_start_source_file (filename);
568550615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
568650615Sobrien#ifdef SDB_DEBUGGING_INFO
568750615Sobrien  if (write_symbols == SDB_DEBUG)
568850615Sobrien    sdbout_start_new_source_file (filename);
568950615Sobrien#endif
569050615Sobrien}
569150615Sobrien
569250615Sobrien/* Record the resumption of a source file.  LINENO is the line number in
569350615Sobrien   the source file we are returning to.  */
569450615Sobrien
569550615Sobrienvoid
569650615Sobriendebug_end_source_file (lineno)
569752558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
569850615Sobrien{
569950615Sobrien#ifdef DBX_DEBUGGING_INFO
570050615Sobrien  if (write_symbols == DBX_DEBUG)
570150615Sobrien    dbxout_resume_previous_source_file ();
570250615Sobrien#endif
570350615Sobrien#ifdef DWARF_DEBUGGING_INFO
570450615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
570550615Sobrien      && write_symbols == DWARF_DEBUG)
570650615Sobrien    dwarfout_resume_previous_source_file (lineno);
570750615Sobrien#endif /* DWARF_DEBUGGING_INFO */
570850615Sobrien#ifdef DWARF2_DEBUGGING_INFO
570950615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
571050615Sobrien      && write_symbols == DWARF2_DEBUG)
571150615Sobrien    dwarf2out_end_source_file ();
571250615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
571350615Sobrien#ifdef SDB_DEBUGGING_INFO
571450615Sobrien  if (write_symbols == SDB_DEBUG)
571550615Sobrien    sdbout_resume_previous_source_file ();
571650615Sobrien#endif
571750615Sobrien}
571850615Sobrien
571950615Sobrien/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
572050615Sobrien   the tail part of the directive line, i.e. the part which is past the
572150615Sobrien   initial whitespace, #, whitespace, directive-name, whitespace part.  */
572250615Sobrien
572350615Sobrienvoid
572450615Sobriendebug_define (lineno, buffer)
572552558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
572652558Sobrien     register char *buffer ATTRIBUTE_UNUSED;
572750615Sobrien{
572850615Sobrien#ifdef DWARF_DEBUGGING_INFO
572950615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
573050615Sobrien      && write_symbols == DWARF_DEBUG)
573150615Sobrien    dwarfout_define (lineno, buffer);
573250615Sobrien#endif /* DWARF_DEBUGGING_INFO */
573350615Sobrien#ifdef DWARF2_DEBUGGING_INFO
573450615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
573550615Sobrien      && write_symbols == DWARF2_DEBUG)
573650615Sobrien    dwarf2out_define (lineno, buffer);
573750615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
573850615Sobrien}
573950615Sobrien
574050615Sobrien/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
574150615Sobrien   the tail part of the directive line, i.e. the part which is past the
574250615Sobrien   initial whitespace, #, whitespace, directive-name, whitespace part.  */
574350615Sobrien
574450615Sobrienvoid
574550615Sobriendebug_undef (lineno, buffer)
574652558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
574752558Sobrien     register char *buffer ATTRIBUTE_UNUSED;
574850615Sobrien{
574950615Sobrien#ifdef DWARF_DEBUGGING_INFO
575050615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
575150615Sobrien      && write_symbols == DWARF_DEBUG)
575250615Sobrien    dwarfout_undef (lineno, buffer);
575350615Sobrien#endif /* DWARF_DEBUGGING_INFO */
575450615Sobrien#ifdef DWARF2_DEBUGGING_INFO
575550615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
575650615Sobrien      && write_symbols == DWARF2_DEBUG)
575750615Sobrien    dwarf2out_undef (lineno, buffer);
575850615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
575950615Sobrien}
5760