toplev.c revision 52558
118334Speter/* Top level of GNU C compiler
252558Sobrien   Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2152558Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 52558 1999-10-27 09:31:52Z obrien $ */
2252558Sobrien
2318334Speter/* This is the top level of cc1/c++.
2418334Speter   It parses command args, opens files, invokes the various passes
2518334Speter   in the proper order, and counts the time used by each.
2618334Speter   Error messages and low-level interface to malloc also handled here.  */
2718334Speter
2818334Speter#include "config.h"
2950615Sobrien#undef FLOAT /* This is for hpux. They should change hpux.  */
3050615Sobrien#undef FFS  /* Some systems define this in param.h.  */
3150615Sobrien#include "system.h"
3218334Speter#include <signal.h>
3318334Speter#include <setjmp.h>
3418334Speter
3550615Sobrien#ifdef HAVE_SYS_RESOURCE_H
3650615Sobrien# include <sys/resource.h>
3718334Speter#endif
3850615Sobrien
3950615Sobrien#ifdef HAVE_SYS_TIMES_H
4050615Sobrien# include <sys/times.h>
4118334Speter#endif
4218334Speter
4318334Speter#include "input.h"
4418334Speter#include "tree.h"
4518334Speter#include "rtl.h"
4618334Speter#include "flags.h"
4718334Speter#include "insn-attr.h"
4850615Sobrien#include "insn-codes.h"
4950615Sobrien#include "insn-config.h"
5050615Sobrien#include "recog.h"
5118334Speter#include "defaults.h"
5218334Speter#include "output.h"
5350615Sobrien#include "except.h"
5450615Sobrien#include "toplev.h"
5552558Sobrien#include "expr.h"
5652558Sobrien#include "basic-block.h"
5752558Sobrien#include "intl.h"
5818334Speter
5950615Sobrien#ifdef DWARF_DEBUGGING_INFO
6050615Sobrien#include "dwarfout.h"
6150615Sobrien#endif
6250615Sobrien
6350615Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
6450615Sobrien#include "dwarf2out.h"
6550615Sobrien#endif
6650615Sobrien
6750615Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
6850615Sobrien#include "dbxout.h"
6950615Sobrien#endif
7050615Sobrien
7150615Sobrien#ifdef SDB_DEBUGGING_INFO
7250615Sobrien#include "sdbout.h"
7350615Sobrien#endif
7450615Sobrien
7518334Speter#ifdef XCOFF_DEBUGGING_INFO
7618334Speter#include "xcoffout.h"
7718334Speter#endif
7818334Speter
7918334Speter#ifdef VMS
8018334Speter/* The extra parameters substantially improve the I/O performance.  */
8118334Speterstatic FILE *
8218334Spetervms_fopen (fname, type)
8318334Speter     char * fname;
8418334Speter     char * type;
8518334Speter{
8618334Speter  /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
8718334Speter     fixed arguments, which matches ANSI's specification but not VAXCRTL's
8818334Speter     pre-ANSI implementation.  This hack circumvents the mismatch problem.  */
8918334Speter  FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
9018334Speter
9118334Speter  if (*type == 'w')
9218334Speter    return (*vmslib_fopen) (fname, type, "mbc=32",
9318334Speter			    "deq=64", "fop=tef", "shr=nil");
9418334Speter  else
9518334Speter    return (*vmslib_fopen) (fname, type, "mbc=32");
9618334Speter}
9718334Speter#define fopen vms_fopen
9818334Speter#endif	/* VMS */
9918334Speter
10018334Speter#ifndef DEFAULT_GDB_EXTENSIONS
10118334Speter#define DEFAULT_GDB_EXTENSIONS 1
10218334Speter#endif
10318334Speter
10450615Sobrien/* If more than one debugging type is supported, you must define
10550615Sobrien   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way.
10650615Sobrien
10750615Sobrien   This is one long line cause VAXC can't handle a \-newline.  */
10850615Sobrien#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
10950615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE
11050615SobrienYou Lose!  You must define PREFERRED_DEBUGGING_TYPE!
11150615Sobrien#endif /* no PREFERRED_DEBUGGING_TYPE */
11250615Sobrien#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
11350615Sobrien	 so the following code needn't care.  */
11450615Sobrien#ifdef DBX_DEBUGGING_INFO
11550615Sobrien#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
11650615Sobrien#endif
11750615Sobrien#ifdef SDB_DEBUGGING_INFO
11850615Sobrien#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
11950615Sobrien#endif
12050615Sobrien#ifdef DWARF_DEBUGGING_INFO
12150615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
12250615Sobrien#endif
12350615Sobrien#ifdef DWARF2_DEBUGGING_INFO
12450615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
12550615Sobrien#endif
12650615Sobrien#ifdef XCOFF_DEBUGGING_INFO
12750615Sobrien#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
12850615Sobrien#endif
12950615Sobrien#endif /* More than one debugger format enabled.  */
13050615Sobrien
13150615Sobrien/* If still not defined, must have been because no debugging formats
13250615Sobrien   are supported.  */
13350615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE
13450615Sobrien#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
13550615Sobrien#endif
13650615Sobrien
13752558Sobrien#ifndef DIR_SEPARATOR
13852558Sobrien#define DIR_SEPARATOR '/'
13952558Sobrien#endif
14052558Sobrien
14118334Speterextern int rtx_equal_function_value_matters;
14218334Speter
14318334Speter#if ! (defined (VMS) || defined (OS2))
14418334Speterextern char **environ;
14518334Speter#endif
14618334Speterextern char *version_string, *language_string;
14718334Speter
14818334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME
14918334Speter   to ASM_FINISH_DECLARE_OBJECT.  */
15018334Speter
15118334Speterextern int size_directive_output;
15218334Speterextern tree last_assemble_variable_decl;
15318334Speter
15450615Sobrienextern char *init_parse PVPROTO((char *));
15550615Sobrienextern void finish_parse ();
15618334Speterextern void init_decl_processing ();
15718334Speterextern void init_obstacks ();
15818334Speterextern void init_tree_codes ();
15918334Speterextern void init_rtl ();
16018334Speterextern void init_regs ();
16118334Speterextern void init_optabs ();
16218334Speterextern void init_stmt ();
16318334Speterextern void init_reg_sets ();
16418334Speterextern void dump_flow_info ();
16518334Speterextern void dump_sched_info ();
16618334Speterextern void dump_local_alloc ();
16750615Sobrienextern void regset_release_memory ();
16818334Speter
16950615Sobrienextern void print_rtl ();
17050615Sobrienextern void print_rtl_with_bb ();
17150615Sobrien
17218334Spetervoid rest_of_decl_compilation ();
17352558Sobrienvoid error_with_file_and_line PVPROTO((const char *file,
17452558Sobrien				       int line, const char *s, ...));
17552558Sobrienvoid error_with_decl PVPROTO((tree decl, const char *s, ...));
17652558Sobrienvoid error_for_asm PVPROTO((rtx insn, const char *s, ...));
17752558Sobrienvoid notice PVPROTO((const char *s, ...));
17852558Sobrienvoid error PVPROTO((const char *s, ...));
17952558Sobrienvoid fatal PVPROTO((const char *s, ...));
18052558Sobrienvoid warning_with_file_and_line PVPROTO((const char *file,
18152558Sobrien					 int line, const char *s, ...));
18252558Sobrienvoid warning_with_decl PVPROTO((tree decl, const char *s, ...));
18352558Sobrienvoid warning PVPROTO((const char *s, ...));
18452558Sobrienvoid pedwarn PVPROTO((const char *s, ...));
18552558Sobrienvoid pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
18652558Sobrienvoid pedwarn_with_file_and_line PVPROTO((const char *file,
18752558Sobrien					 int line, const char *s, ...));
18852558Sobrienvoid sorry PVPROTO((const char *s, ...));
18952558Sobrienstatic void set_target_switch PROTO((const char *));
19050615Sobrienstatic char *decl_name PROTO((tree, int));
19152558Sobrienstatic void vmessage PROTO((const char *, const char *, va_list));
19252558Sobrienstatic void v_message_with_file_and_line PROTO((const char *, int, int,
19352558Sobrien						const char *, va_list));
19452558Sobrienstatic void v_message_with_decl PROTO((tree, int, const char *, va_list));
19550615Sobrienstatic void file_and_line_for_asm PROTO((rtx, char **, int *));
19652558Sobrienstatic void v_error_with_file_and_line PROTO((const char *, int,
19752558Sobrien					      const char *, va_list));
19852558Sobrienstatic void v_error_with_decl PROTO((tree, const char *, va_list));
19952558Sobrienstatic void v_error_for_asm PROTO((rtx, const char *, va_list));
20052558Sobrienstatic void verror PROTO((const char *, va_list));
20152558Sobrienstatic void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
20252558Sobrienstatic void v_warning_with_file_and_line PROTO ((const char *, int,
20352558Sobrien						 const char *, va_list));
20452558Sobrienstatic void v_warning_with_decl PROTO((tree, const char *, va_list));
20552558Sobrienstatic void v_warning_for_asm PROTO((rtx, const char *, va_list));
20652558Sobrienstatic void vwarning PROTO((const char *, va_list));
20752558Sobrienstatic void vpedwarn PROTO((const char *, va_list));
20852558Sobrienstatic void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
20952558Sobrienstatic void v_pedwarn_with_file_and_line PROTO((const char *, int,
21052558Sobrien						const char *, va_list));
21152558Sobrienstatic void vsorry PROTO((const char *, va_list));
21252558Sobrienstatic void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
21352558Sobrienstatic void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
21452558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE
21552558Sobrien/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
21652558Sobrienstatic void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
21752558Sobrien#endif
21852558Sobrienstatic void open_dump_file PROTO((const char *, const char *));
21950615Sobrienstatic void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
22052558Sobrienstatic void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
22152558Sobrienstatic void clean_dump_file PROTO((const char *));
22250615Sobrienstatic void compile_file PROTO((char *));
22350615Sobrienstatic void display_help PROTO ((void));
22418334Speter
22552558Sobrienstatic void print_version PROTO((FILE *, const char *));
22652558Sobrienstatic int print_single_switch PROTO((FILE *, int, int, const char *,
22752558Sobrien				      const char *, const char *,
22852558Sobrien				      const char *, const char *));
22952558Sobrienstatic void print_switch_values PROTO((FILE *, int, int, const char *,
23052558Sobrien				       const char *, const char *));
23152558Sobrien
23252558Sobrienvoid print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
23352558Sobrienvoid clean_graph_dump_file PROTO ((const char *, const char *));
23452558Sobrienvoid finish_graph_dump_file PROTO ((const char *, const char *));
23550615Sobrien/* Length of line when printing switch values.  */
23650615Sobrien#define MAX_LINE 75
23718334Speter
23818334Speter/* Name of program invoked, sans directories.  */
23918334Speter
24018334Speterchar *progname;
24118334Speter
24218334Speter/* Copy of arguments to main.  */
24318334Speterint save_argc;
24418334Speterchar **save_argv;
24518334Speter
24618334Speter/* Name of current original source file (what was input to cpp).
24718334Speter   This comes from each #-command in the actual input.  */
24818334Speter
24918334Speterchar *input_filename;
25018334Speter
25118334Speter/* Name of top-level original source file (what was input to cpp).
25218334Speter   This comes from the #-command at the beginning of the actual input.
25318334Speter   If there isn't any there, then this is the cc1 input file name.  */
25418334Speter
25518334Speterchar *main_input_filename;
25618334Speter
25718334Speter/* Current line number in real source file.  */
25818334Speter
25918334Speterint lineno;
26018334Speter
26152558Sobrien/* Nonzero if it is unsafe to create any new pseudo registers.  */
26252558Sobrienint no_new_pseudos;
26352558Sobrien
26418334Speter/* Stack of currently pending input files.  */
26518334Speter
26618334Speterstruct file_stack *input_file_stack;
26718334Speter
26818334Speter/* Incremented on each change to input_file_stack.  */
26918334Speterint input_file_stack_tick;
27018334Speter
27118334Speter/* FUNCTION_DECL for function now being parsed or compiled.  */
27218334Speter
27318334Speterextern tree current_function_decl;
27418334Speter
27518334Speter/* Name to use as base of names for dump output files.  */
27618334Speter
27752558Sobrienconst char *dump_base_name;
27818334Speter
27918334Speter/* Bit flags that specify the machine subtype we are compiling for.
28018334Speter   Bits are tested using macros TARGET_... defined in the tm.h file
28118334Speter   and set by `-m...' switches.  Must be defined in rtlanal.c.  */
28218334Speter
28318334Speterextern int target_flags;
28418334Speter
28518334Speter/* Flags saying which kinds of debugging dump have been requested.  */
28618334Speter
28718334Speterint rtl_dump = 0;
28818334Speterint rtl_dump_and_exit = 0;
28918334Speterint jump_opt_dump = 0;
29050615Sobrienint addressof_dump = 0;
29118334Speterint cse_dump = 0;
29250615Sobrienint gcse_dump = 0;
29318334Speterint loop_dump = 0;
29418334Speterint cse2_dump = 0;
29550615Sobrienint branch_prob_dump = 0;
29618334Speterint flow_dump = 0;
29718334Speterint combine_dump = 0;
29850615Sobrienint regmove_dump = 0;
29918334Speterint sched_dump = 0;
30018334Speterint local_reg_dump = 0;
30118334Speterint global_reg_dump = 0;
30252558Sobrienint flow2_dump = 0;
30318334Speterint sched2_dump = 0;
30418334Speterint jump2_opt_dump = 0;
30550615Sobrien#ifdef DELAY_SLOTS
30618334Speterint dbr_sched_dump = 0;
30750615Sobrien#endif
30818334Speterint flag_print_asm_name = 0;
30950615Sobrien#ifdef STACK_REGS
31018334Speterint stack_reg_dump = 0;
31150615Sobrien#endif
31250615Sobrien#ifdef MACHINE_DEPENDENT_REORG
31350615Sobrienint mach_dep_reorg_dump = 0;
31450615Sobrien#endif
31552558Sobrienenum graph_dump_types graph_dump_format;
31618334Speter
31718334Speter/* Name for output file of assembly code, specified with -o.  */
31818334Speter
31918334Speterchar *asm_file_name;
32018334Speter
32118334Speter/* Value of the -G xx switch, and whether it was passed or not.  */
32218334Speterint g_switch_value;
32318334Speterint g_switch_set;
32418334Speter
32518334Speter/* Type(s) of debugging information we are producing (if any).
32618334Speter   See flags.h for the definitions of the different possible
32718334Speter   types of debugging information.  */
32818334Speterenum debug_info_type write_symbols = NO_DEBUG;
32918334Speter
33018334Speter/* Level of debugging information we are producing.  See flags.h
33118334Speter   for the definitions of the different possible levels.  */
33218334Speterenum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
33318334Speter
33418334Speter/* Nonzero means use GNU-only extensions in the generated symbolic
33518334Speter   debugging information.  */
33618334Speter/* Currently, this only has an effect when write_symbols is set to
33718334Speter   DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
33818334Speterint use_gnu_debug_info_extensions = 0;
33918334Speter
34018334Speter/* Nonzero means do optimizations.  -O.
34118334Speter   Particular numeric values stand for particular amounts of optimization;
34218334Speter   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
34318334Speter   ones are not controlled directly by this variable.  Instead, they are
34418334Speter   controlled by individual `flag_...' variables that are defaulted
34518334Speter   based on this variable.  */
34618334Speter
34718334Speterint optimize = 0;
34818334Speter
34950615Sobrien/* Nonzero means optimize for size.  -Os.
35050615Sobrien   The only valid values are zero and non-zero. When optimize_size is
35150615Sobrien   non-zero, optimize defaults to 2, but certain individual code
35250615Sobrien   bloating optimizations are disabled.  */
35350615Sobrien
35450615Sobrienint optimize_size = 0;
35550615Sobrien
35618334Speter/* Number of error messages and warning messages so far.  */
35718334Speter
35818334Speterint errorcount = 0;
35918334Speterint warningcount = 0;
36018334Speterint sorrycount = 0;
36118334Speter
36250615Sobrien/* Pointer to function to compute the name to use to print a declaration.
36350615Sobrien   DECL is the declaration in question.
36450615Sobrien   VERBOSITY determines what information will be printed:
36550615Sobrien     0: DECL_NAME, demangled as necessary.
36650615Sobrien     1: and scope information.
36750615Sobrien     2: and any other information that might be interesting, such as function
36850615Sobrien        parameter types in C++.  */
36918334Speter
37052558Sobrienchar *(*decl_printable_name)		PROTO ((tree, int));
37118334Speter
37218334Speter/* Pointer to function to compute rtl for a language-specific tree code.  */
37318334Speter
37452558Sobrientypedef rtx (*lang_expand_expr_t)
37552558Sobrien  PROTO ((union tree_node *, rtx, enum machine_mode,
37652558Sobrien	  enum expand_modifier modifier));
37718334Speter
37852558Sobrienlang_expand_expr_t lang_expand_expr = 0;
37952558Sobrien
38052558Sobrientree (*lang_expand_constant) PROTO((tree)) = 0;
38152558Sobrien
38218334Speter/* Pointer to function to finish handling an incomplete decl at the
38318334Speter   end of compilation.  */
38418334Speter
38552558Sobrienvoid (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
38618334Speter
38718334Speter/* Nonzero if generating code to do profiling.  */
38818334Speter
38918334Speterint profile_flag = 0;
39018334Speter
39118334Speter/* Nonzero if generating code to do profiling on a line-by-line basis.  */
39218334Speter
39318334Speterint profile_block_flag;
39418334Speter
39550615Sobrien/* Nonzero if generating code to profile program flow graph arcs.  */
39650615Sobrien
39750615Sobrienint profile_arc_flag = 0;
39850615Sobrien
39950615Sobrien/* Nonzero if generating info for gcov to calculate line test coverage.  */
40050615Sobrien
40150615Sobrienint flag_test_coverage = 0;
40250615Sobrien
40350615Sobrien/* Nonzero indicates that branch taken probabilities should be calculated.  */
40450615Sobrien
40550615Sobrienint flag_branch_probabilities = 0;
40650615Sobrien
40718334Speter/* Nonzero for -pedantic switch: warn about anything
40818334Speter   that standard spec forbids.  */
40918334Speter
41018334Speterint pedantic = 0;
41118334Speter
41218334Speter/* Temporarily suppress certain warnings.
41318334Speter   This is set while reading code from a system header file.  */
41418334Speter
41518334Speterint in_system_header = 0;
41618334Speter
41718334Speter/* Nonzero means do stupid register allocation.
41818334Speter   Currently, this is 1 if `optimize' is 0.  */
41918334Speter
42018334Speterint obey_regdecls = 0;
42118334Speter
42218334Speter/* Don't print functions as they are compiled and don't print
42318334Speter   times taken by the various passes.  -quiet.  */
42418334Speter
42518334Speterint quiet_flag = 0;
42618334Speter
42718334Speter/* -f flags.  */
42818334Speter
42918334Speter/* Nonzero means `char' should be signed.  */
43018334Speter
43118334Speterint flag_signed_char;
43218334Speter
43318334Speter/* Nonzero means give an enum type only as many bytes as it needs.  */
43418334Speter
43518334Speterint flag_short_enums;
43618334Speter
43718334Speter/* Nonzero for -fcaller-saves: allocate values in regs that need to
43818334Speter   be saved across function calls, if that produces overall better code.
43918334Speter   Optional now, so people can test it.  */
44018334Speter
44118334Speter#ifdef DEFAULT_CALLER_SAVES
44218334Speterint flag_caller_saves = 1;
44318334Speter#else
44418334Speterint flag_caller_saves = 0;
44518334Speter#endif
44618334Speter
44718334Speter/* Nonzero if structures and unions should be returned in memory.
44818334Speter
44918334Speter   This should only be defined if compatibility with another compiler or
45018334Speter   with an ABI is needed, because it results in slower code.  */
45118334Speter
45218334Speter#ifndef DEFAULT_PCC_STRUCT_RETURN
45318334Speter#define DEFAULT_PCC_STRUCT_RETURN 1
45418334Speter#endif
45518334Speter
45618334Speter/* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */
45718334Speter
45818334Speterint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
45918334Speter
46018334Speter/* Nonzero for -fforce-mem: load memory value into a register
46118334Speter   before arithmetic on it.  This makes better cse but slower compilation.  */
46218334Speter
46318334Speterint flag_force_mem = 0;
46418334Speter
46518334Speter/* Nonzero for -fforce-addr: load memory address into a register before
46618334Speter   reference to memory.  This makes better cse but slower compilation.  */
46718334Speter
46818334Speterint flag_force_addr = 0;
46918334Speter
47018334Speter/* Nonzero for -fdefer-pop: don't pop args after each function call;
47118334Speter   instead save them up to pop many calls' args with one insns.  */
47218334Speter
47318334Speterint flag_defer_pop = 0;
47418334Speter
47518334Speter/* Nonzero for -ffloat-store: don't allocate floats and doubles
47618334Speter   in extended-precision registers.  */
47718334Speter
47818334Speterint flag_float_store = 0;
47918334Speter
48018334Speter/* Nonzero for -fcse-follow-jumps:
48118334Speter   have cse follow jumps to do a more extensive job.  */
48218334Speter
48318334Speterint flag_cse_follow_jumps;
48418334Speter
48518334Speter/* Nonzero for -fcse-skip-blocks:
48618334Speter   have cse follow a branch around a block.  */
48718334Speterint flag_cse_skip_blocks;
48818334Speter
48918334Speter/* Nonzero for -fexpensive-optimizations:
49018334Speter   perform miscellaneous relatively-expensive optimizations.  */
49118334Speterint flag_expensive_optimizations;
49218334Speter
49318334Speter/* Nonzero for -fthread-jumps:
49418334Speter   have jump optimize output of loop.  */
49518334Speter
49618334Speterint flag_thread_jumps;
49718334Speter
49818334Speter/* Nonzero enables strength-reduction in loop.c.  */
49918334Speter
50018334Speterint flag_strength_reduce = 0;
50118334Speter
50218334Speter/* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
50318334Speter   number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
50418334Speter   UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
50518334Speter   unrolled.  */
50618334Speter
50718334Speterint flag_unroll_loops;
50818334Speter
50918334Speter/* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
51018334Speter   This is generally not a win.  */
51118334Speter
51218334Speterint flag_unroll_all_loops;
51318334Speter
51450615Sobrien/* Nonzero forces all invariant computations in loops to be moved
51550615Sobrien   outside the loop. */
51650615Sobrien
51750615Sobrienint flag_move_all_movables = 0;
51850615Sobrien
51950615Sobrien/* Nonzero forces all general induction variables in loops to be
52050615Sobrien   strength reduced. */
52150615Sobrien
52250615Sobrienint flag_reduce_all_givs = 0;
52350615Sobrien
52450615Sobrien/* Nonzero to perform full register move optimization passes.  This is the
52550615Sobrien   default for -O2.  */
52650615Sobrien
52750615Sobrienint flag_regmove = 0;
52850615Sobrien
52918334Speter/* Nonzero for -fwritable-strings:
53018334Speter   store string constants in data segment and don't uniquize them.  */
53118334Speter
53218334Speterint flag_writable_strings = 0;
53318334Speter
53418334Speter/* Nonzero means don't put addresses of constant functions in registers.
53518334Speter   Used for compiling the Unix kernel, where strange substitutions are
53618334Speter   done on the assembly output.  */
53718334Speter
53818334Speterint flag_no_function_cse = 0;
53918334Speter
54018334Speter/* Nonzero for -fomit-frame-pointer:
54118334Speter   don't make a frame pointer in simple functions that don't require one.  */
54218334Speter
54318334Speterint flag_omit_frame_pointer = 0;
54418334Speter
54550615Sobrien/* Nonzero means place each function into its own section on those platforms
54650615Sobrien   which support arbitrary section names and unlimited numbers of sections.  */
54750615Sobrien
54850615Sobrienint flag_function_sections = 0;
54950615Sobrien
55052558Sobrien/* ... and similar for data.  */
55152558Sobrien
55252558Sobrienint flag_data_sections = 0;
55352558Sobrien
55418334Speter/* Nonzero to inhibit use of define_optimization peephole opts.  */
55518334Speter
55618334Speterint flag_no_peephole = 0;
55718334Speter
55818334Speter/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
55918334Speter   operations in the interest of optimization.  For example it allows
56018334Speter   GCC to assume arguments to sqrt are nonnegative numbers, allowing
56150615Sobrien   faster code for sqrt to be generated.  */
56218334Speter
56318334Speterint flag_fast_math = 0;
56418334Speter
56552558Sobrien/* Nonzero means the front end generally wants `errno' maintained by math
56652558Sobrien   operations, like built-in SQRT, unless overridden by flag_fast_math.  */
56752558Sobrien
56852558Sobrienint flag_errno_math = 1;
56952558Sobrien
57052558Sobrien/* 0 means straightforward implementation of complex divide acceptable.
57152558Sobrien   1 means wide ranges of inputs must work for complex divide.
57252558Sobrien   2 means C9X-like requirements for complex divide (not yet implemented).  */
57352558Sobrien
57452558Sobrienint flag_complex_divide_method = 0;
57552558Sobrien
57618334Speter/* Nonzero means all references through pointers are volatile.  */
57718334Speter
57818334Speterint flag_volatile;
57918334Speter
58052558Sobrien/* Nonzero means treat all global and extern variables as volatile.  */
58118334Speter
58218334Speterint flag_volatile_global;
58318334Speter
58452558Sobrien/* Nonzero means treat all static variables as volatile.  */
58552558Sobrien
58652558Sobrienint flag_volatile_static;
58752558Sobrien
58818334Speter/* Nonzero means just do syntax checking; don't output anything.  */
58918334Speter
59018334Speterint flag_syntax_only = 0;
59118334Speter
59250615Sobrien/* Nonzero means perform global cse.  */
59350615Sobrien
59450615Sobrienstatic int flag_gcse;
59550615Sobrien
59618334Speter/* Nonzero means to rerun cse after loop optimization.  This increases
59718334Speter   compilation time about 20% and picks up a few more common expressions.  */
59818334Speter
59918334Speterstatic int flag_rerun_cse_after_loop;
60018334Speter
60150615Sobrien/* Nonzero means to run loop optimizations twice.  */
60250615Sobrien
60350615Sobrienint flag_rerun_loop_opt;
60450615Sobrien
60518334Speter/* Nonzero for -finline-functions: ok to inline functions that look like
60618334Speter   good inline candidates.  */
60718334Speter
60818334Speterint flag_inline_functions;
60918334Speter
61018334Speter/* Nonzero for -fkeep-inline-functions: even if we make a function
61118334Speter   go inline everywhere, keep its definition around for debugging
61218334Speter   purposes.  */
61318334Speter
61418334Speterint flag_keep_inline_functions;
61518334Speter
61618334Speter/* Nonzero means that functions will not be inlined.  */
61718334Speter
61818334Speterint flag_no_inline;
61918334Speter
62050615Sobrien/* Nonzero means that we should emit static const variables
62150615Sobrien   regardless of whether or not optimization is turned on.  */
62250615Sobrien
62350615Sobrienint flag_keep_static_consts = 1;
62450615Sobrien
62518334Speter/* Nonzero means we should be saving declaration info into a .X file.  */
62618334Speter
62718334Speterint flag_gen_aux_info = 0;
62818334Speter
62918334Speter/* Specified name of aux-info file.  */
63018334Speter
63118334Speterstatic char *aux_info_file_name;
63218334Speter
63318334Speter/* Nonzero means make the text shared if supported.  */
63418334Speter
63518334Speterint flag_shared_data;
63618334Speter
63718334Speter/* Nonzero means schedule into delayed branch slots if supported.  */
63818334Speter
63918334Speterint flag_delayed_branch;
64018334Speter
64118334Speter/* Nonzero if we are compiling pure (sharable) code.
64218334Speter   Value is 1 if we are doing reasonable (i.e. simple
64318334Speter   offset into offset table) pic.  Value is 2 if we can
64418334Speter   only perform register offsets.  */
64518334Speter
64618334Speterint flag_pic;
64718334Speter
64850615Sobrien/* Nonzero means generate extra code for exception handling and enable
64950615Sobrien   exception handling.  */
65018334Speter
65150615Sobrienint flag_exceptions;
65250615Sobrien
65350615Sobrien/* Nonzero means use the new model for exception handling. Replaces
65450615Sobrien   -DNEW_EH_MODEL as a compile option. */
65550615Sobrien
65650615Sobrienint flag_new_exceptions = 0;
65750615Sobrien
65850615Sobrien/* Nonzero means don't place uninitialized global data in common storage
65950615Sobrien   by default.  */
66050615Sobrien
66118334Speterint flag_no_common;
66218334Speter
66318334Speter/* Nonzero means pretend it is OK to examine bits of target floats,
66418334Speter   even if that isn't true.  The resulting code will have incorrect constants,
66518334Speter   but the same series of instructions that the native compiler would make.  */
66618334Speter
66718334Speterint flag_pretend_float;
66818334Speter
66918334Speter/* Nonzero means change certain warnings into errors.
67018334Speter   Usually these are warnings about failure to conform to some standard.  */
67118334Speter
67218334Speterint flag_pedantic_errors = 0;
67318334Speter
67418334Speter/* flag_schedule_insns means schedule insns within basic blocks (before
67518334Speter   local_alloc).
67618334Speter   flag_schedule_insns_after_reload means schedule insns after
67718334Speter   global_alloc.  */
67818334Speter
67918334Speterint flag_schedule_insns = 0;
68018334Speterint flag_schedule_insns_after_reload = 0;
68118334Speter
68250615Sobrien#ifdef HAIFA
68350615Sobrien/* The following flags have effect only for scheduling before register
68450615Sobrien   allocation:
68550615Sobrien
68650615Sobrien   flag_schedule_interblock means schedule insns accross basic blocks.
68750615Sobrien   flag_schedule_speculative means allow speculative motion of non-load insns.
68850615Sobrien   flag_schedule_speculative_load means allow speculative motion of some
68950615Sobrien   load insns.
69050615Sobrien   flag_schedule_speculative_load_dangerous allows speculative motion of more
69150615Sobrien   load insns.  */
69250615Sobrien
69350615Sobrienint flag_schedule_interblock = 1;
69450615Sobrienint flag_schedule_speculative = 1;
69550615Sobrienint flag_schedule_speculative_load = 0;
69650615Sobrienint flag_schedule_speculative_load_dangerous = 0;
69752558Sobrien#endif  /* HAIFA */
69850615Sobrien
69950615Sobrien/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
70050615Sobrien   by a cheaper branch, on a count register. */
70150615Sobrienint flag_branch_on_count_reg;
70250615Sobrien
70318334Speter/* -finhibit-size-directive inhibits output of .size for ELF.
70418334Speter   This is used only for compiling crtstuff.c,
70518334Speter   and it may be extended to other effects
70618334Speter   needed for crtstuff.c on other systems.  */
70718334Speterint flag_inhibit_size_directive = 0;
70818334Speter
70918334Speter/* -fverbose-asm causes extra commentary information to be produced in
71018334Speter   the generated assembly code (to make it more readable).  This option
71118334Speter   is generally only of use to those who actually need to read the
71250615Sobrien   generated assembly code (perhaps while debugging the compiler itself).
71350615Sobrien   -fno-verbose-asm, the default, causes the extra information
71450615Sobrien   to be omitted and is useful when comparing two assembler files.  */
71518334Speter
71618334Speterint flag_verbose_asm = 0;
71718334Speter
71850615Sobrien/* -dA causes debug commentary information to be produced in
71950615Sobrien   the generated assembly code (to make it more readable).  This option
72050615Sobrien   is generally only of use to those who actually need to read the
72150615Sobrien   generated assembly code (perhaps while debugging the compiler itself).
72250615Sobrien   Currently, this switch is only used by dwarfout.c; however, it is intended
72350615Sobrien   to be a catchall for printing debug information in the assembler file.  */
72450615Sobrien
72550615Sobrienint flag_debug_asm = 0;
72650615Sobrien
72718334Speter/* -fgnu-linker specifies use of the GNU linker for initializations.
72818334Speter   (Or, more generally, a linker that handles initializations.)
72918334Speter   -fno-gnu-linker says that collect2 will be used.  */
73018334Speter#ifdef USE_COLLECT2
73118334Speterint flag_gnu_linker = 0;
73218334Speter#else
73318334Speterint flag_gnu_linker = 1;
73418334Speter#endif
73518334Speter
73618334Speter/* Tag all structures with __attribute__(packed) */
73718334Speterint flag_pack_struct = 0;
73818334Speter
73938510Sbde/* Nonzero means that -Wformat accepts certain system-dependent formats.  */
74038510Sbdeint flag_format_extensions = 0;
74138510Sbde
74250615Sobrien/* Emit code to check for stack overflow; also may cause large objects
74350615Sobrien   to be allocated dynamically.  */
74450615Sobrienint flag_stack_check;
74550615Sobrien
74650615Sobrien/* -fcheck-memory-usage causes extra code to be generated in order to check
74750615Sobrien   memory accesses.  This is used by a detector of bad memory accesses such
74850615Sobrien   as Checker.  */
74950615Sobrienint flag_check_memory_usage = 0;
75050615Sobrien
75150615Sobrien/* -fprefix-function-name causes function name to be prefixed.  This
75250615Sobrien   can be used with -fcheck-memory-usage to isolate code compiled with
75350615Sobrien   -fcheck-memory-usage.  */
75450615Sobrienint flag_prefix_function_name = 0;
75550615Sobrien
75650615Sobrien/* 0 if pointer arguments may alias each other.  True in C.
75750615Sobrien   1 if pointer arguments may not alias each other but may alias
75850615Sobrien   global variables.
75950615Sobrien   2 if pointer arguments may not alias each other and may not
76050615Sobrien   alias global variables.  True in Fortran.
76150615Sobrien   This defaults to 0 for C.  */
76250615Sobrienint flag_argument_noalias = 0;
76350615Sobrien
76450615Sobrien/* Nonzero if we should do (language-dependent) alias analysis.
76550615Sobrien   Typically, this analysis will assume that expressions of certain
76650615Sobrien   types do not alias expressions of certain other types.  Only used
76750615Sobrien   if alias analysis (in general) is enabled.  */
76850615Sobrienint flag_strict_aliasing = 0;
76950615Sobrien
77052558Sobrien/* Instrument functions with calls at entry and exit, for profiling.  */
77152558Sobrienint flag_instrument_function_entry_exit = 0;
77250615Sobrien
77352558Sobrien/* Nonzero means ignore `#ident' directives.  0 means handle them.
77452558Sobrien   On SVR4 targets, it also controls whether or not to emit a
77552558Sobrien   string identifying the compiler.  */
77650615Sobrien
77752558Sobrienint flag_no_ident = 0;
77852558Sobrien
77950615Sobrien/* Table of supported debugging formats.  */
78050615Sobrienstatic struct
78150615Sobrien{
78252558Sobrien  const char * arg;
78350615Sobrien  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
78450615Sobrien     constant expression, we use NO_DEBUG in its place.  */
78550615Sobrien  enum debug_info_type debug_type;
78650615Sobrien  int use_extensions_p;
78752558Sobrien  const char * description;
78850615Sobrien} *da,
78950615Sobriendebug_args[] =
79050615Sobrien{
79150615Sobrien  { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
79250615Sobrien    "Generate default debug format output" },
79350615Sobrien  { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
79450615Sobrien#ifdef DBX_DEBUGGING_INFO
79550615Sobrien  { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
79650615Sobrien  { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
79750615Sobrien#endif
79850615Sobrien#ifdef DWARF_DEBUGGING_INFO
79950615Sobrien  { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
80050615Sobrien  { "gdwarf+", DWARF_DEBUG, 1,
80150615Sobrien    "Generated extended DWARF-1 format debug output" },
80250615Sobrien#endif
80350615Sobrien#ifdef DWARF2_DEBUGGING_INFO
80450615Sobrien  { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
80550615Sobrien#endif
80650615Sobrien#ifdef XCOFF_DEBUGGING_INFO
80750615Sobrien  { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
80850615Sobrien  { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
80950615Sobrien#endif
81050615Sobrien#ifdef SDB_DEBUGGING_INFO
81150615Sobrien  { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
81250615Sobrien#endif
81352558Sobrien  { 0, 0, 0, 0 }
81450615Sobrien};
81550615Sobrien
81650615Sobrientypedef struct
81750615Sobrien{
81852558Sobrien  const char * string;
81950615Sobrien  int *  variable;
82050615Sobrien  int    on_value;
82152558Sobrien  const char * description;
82250615Sobrien}
82350615Sobrienlang_independent_options;
82450615Sobrien
82552558Sobrien/* Add or remove a leading underscore from user symbols.  */
82652558Sobrienint flag_leading_underscore = -1;
82752558Sobrien
82852558Sobrien/* The user symbol prefix after having resolved same.  */
82952558Sobrienconst char *user_label_prefix;
83052558Sobrien
83152558Sobrien/* A default for same.  */
83252558Sobrien#ifndef USER_LABEL_PREFIX
83352558Sobrien#define USER_LABEL_PREFIX ""
83452558Sobrien#endif
83552558Sobrien
83618334Speter/* Table of language-independent -f options.
83718334Speter   STRING is the option name.  VARIABLE is the address of the variable.
83818334Speter   ON_VALUE is the value to store in VARIABLE
83918334Speter    if `-fSTRING' is seen as an option.
84018334Speter   (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
84118334Speter
84250615Sobrienlang_independent_options f_options[] =
84318334Speter{
84450615Sobrien  {"float-store", &flag_float_store, 1,
84550615Sobrien   "Do not store floats in registers" },
84650615Sobrien  {"volatile", &flag_volatile, 1,
84750615Sobrien   "Consider all mem refs through pointers as volatile"},
84850615Sobrien  {"volatile-global", &flag_volatile_global, 1,
84950615Sobrien   "Consider all mem refs to global data to be volatile" },
85052558Sobrien  {"volatile-static", &flag_volatile_static, 1,
85152558Sobrien   "Consider all mem refs to static data to be volatile" },
85250615Sobrien  {"defer-pop", &flag_defer_pop, 1,
85350615Sobrien   "Defer popping functions args from stack until later" },
85450615Sobrien  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
85550615Sobrien   "When possible do not generate stack frames"},
85650615Sobrien  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
85750615Sobrien   "When running CSE, follow jumps to their targets" },
85850615Sobrien  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
85950615Sobrien   "When running CSE, follow conditional jumps" },
86050615Sobrien  {"expensive-optimizations", &flag_expensive_optimizations, 1,
86150615Sobrien   "Perform a number of minor, expensive optimisations" },
86250615Sobrien  {"thread-jumps", &flag_thread_jumps, 1,
86350615Sobrien   "Perform jump threading optimisations"},
86450615Sobrien  {"strength-reduce", &flag_strength_reduce, 1,
86550615Sobrien   "Perform strength reduction optimisations" },
86650615Sobrien  {"unroll-loops", &flag_unroll_loops, 1,
86752558Sobrien   "Perform loop unrolling when iteration count is known" },
86850615Sobrien  {"unroll-all-loops", &flag_unroll_all_loops, 1,
86952558Sobrien   "Perform loop unrolling for all loops" },
87050615Sobrien  {"move-all-movables", &flag_move_all_movables, 1,
87150615Sobrien   "Force all loop invariant computations out of loops" },
87250615Sobrien  {"reduce-all-givs", &flag_reduce_all_givs, 1,
87350615Sobrien   "Strength reduce all loop general induction variables" },
87450615Sobrien  {"writable-strings", &flag_writable_strings, 1,
87550615Sobrien   "Store strings in writable data section" },
87650615Sobrien  {"peephole", &flag_no_peephole, 0,
87750615Sobrien   "Enable machine specific peephole optimisations" },
87850615Sobrien  {"force-mem", &flag_force_mem, 1,
87950615Sobrien   "Copy memory operands into registers before using" },
88050615Sobrien  {"force-addr", &flag_force_addr, 1,
88150615Sobrien   "Copy memory address constants into regs before using" },
88250615Sobrien  {"function-cse", &flag_no_function_cse, 0,
88350615Sobrien   "Allow function addresses to be held in registers" },
88450615Sobrien  {"inline-functions", &flag_inline_functions, 1,
88550615Sobrien   "Integrate simple functions into their callers" },
88650615Sobrien  {"keep-inline-functions", &flag_keep_inline_functions, 1,
88750615Sobrien   "Generate code for funcs even if they are fully inlined" },
88850615Sobrien  {"inline", &flag_no_inline, 0,
88950615Sobrien   "Pay attention to the 'inline' keyword"},
89050615Sobrien  {"keep-static-consts", &flag_keep_static_consts, 1,
89150615Sobrien   "Emit static const variables even if they are not used" },
89250615Sobrien  {"syntax-only", &flag_syntax_only, 1,
89350615Sobrien   "Check for syntax errors, then stop" },
89450615Sobrien  {"shared-data", &flag_shared_data, 1,
89550615Sobrien   "Mark data as shared rather than private" },
89650615Sobrien  {"caller-saves", &flag_caller_saves, 1,
89750615Sobrien   "Enable saving registers around function calls" },
89850615Sobrien  {"pcc-struct-return", &flag_pcc_struct_return, 1,
89950615Sobrien   "Return 'short' aggregates in memory, not registers" },
90050615Sobrien  {"reg-struct-return", &flag_pcc_struct_return, 0,
90150615Sobrien   "Return 'short' aggregates in registers" },
90250615Sobrien  {"delayed-branch", &flag_delayed_branch, 1,
90350615Sobrien   "Attempt to fill delay slots of branch instructions" },
90450615Sobrien  {"gcse", &flag_gcse, 1,
90550615Sobrien   "Perform the global common subexpression elimination" },
90650615Sobrien  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
90750615Sobrien   "Run CSE pass after loop optimisations"},
90850615Sobrien  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
90950615Sobrien   "Run the loop optimiser twice"},
91050615Sobrien  {"pretend-float", &flag_pretend_float, 1,
91150615Sobrien   "Pretend that host and target use the same FP format"},
91250615Sobrien  {"schedule-insns", &flag_schedule_insns, 1,
91350615Sobrien   "Reschedule instructions to avoid pipeline stalls"},
91450615Sobrien  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
91550615Sobrien  "Run two passes of the instruction scheduler"},
91650615Sobrien#ifdef HAIFA
91750615Sobrien  {"sched-interblock",&flag_schedule_interblock, 1,
91850615Sobrien   "Enable scheduling across basic blocks" },
91950615Sobrien  {"sched-spec",&flag_schedule_speculative, 1,
92050615Sobrien   "Allow speculative motion of non-loads" },
92150615Sobrien  {"sched-spec-load",&flag_schedule_speculative_load, 1,
92250615Sobrien   "Allow speculative motion of some loads" },
92350615Sobrien  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
92450615Sobrien   "Allow speculative motion of more loads" },
92552558Sobrien#endif  /* HAIFA */
92650615Sobrien  {"branch-count-reg",&flag_branch_on_count_reg, 1,
92750615Sobrien   "Replace add,compare,branch with branch on count reg"},
92850615Sobrien  {"pic", &flag_pic, 1,
92950615Sobrien   "Generate position independent code, if possible"},
93050615Sobrien  {"PIC", &flag_pic, 2, ""},
93150615Sobrien  {"exceptions", &flag_exceptions, 1,
93250615Sobrien   "Enable exception handling" },
93350615Sobrien  {"new-exceptions", &flag_new_exceptions, 1,
93450615Sobrien   "Use the new model for exception handling" },
93550615Sobrien  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
93650615Sobrien   "Use setjmp/longjmp to handle exceptions" },
93750615Sobrien  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
93850615Sobrien   "Support asynchronous exceptions" },
93950615Sobrien  {"profile-arcs", &profile_arc_flag, 1,
94050615Sobrien   "Insert arc based program profiling code" },
94150615Sobrien  {"test-coverage", &flag_test_coverage, 1,
94250615Sobrien   "Create data files needed by gcov" },
94350615Sobrien  {"branch-probabilities", &flag_branch_probabilities, 1,
94452558Sobrien   "Use profiling information for branch probabilities" },
94550615Sobrien  {"fast-math", &flag_fast_math, 1,
94650615Sobrien   "Improve FP speed by violating ANSI & IEEE rules" },
94750615Sobrien  {"common", &flag_no_common, 0,
94850615Sobrien   "Do not put unitialised globals in the common section" },
94950615Sobrien  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
95050615Sobrien   "Do not generate .size directives" },
95150615Sobrien  {"function-sections", &flag_function_sections, 1,
95250615Sobrien   "place each function into its own section" },
95352558Sobrien  {"data-sections", &flag_data_sections, 1,
95452558Sobrien   "place data items into their own section" },
95550615Sobrien  {"verbose-asm", &flag_verbose_asm, 1,
95650615Sobrien   "Add extra commentry to assembler output"},
95750615Sobrien  {"gnu-linker", &flag_gnu_linker, 1,
95850615Sobrien   "Output GNU ld formatted global initialisers"},
95950615Sobrien  {"regmove", &flag_regmove, 1,
96052558Sobrien   "Enables a register move optimisation"},
96152558Sobrien  {"optimize-register-move", &flag_regmove, 1,
96252558Sobrien   "Do the full regmove optimization pass"},
96350615Sobrien  {"pack-struct", &flag_pack_struct, 1,
96450615Sobrien   "Pack structure members together without holes" },
96550615Sobrien  {"format-extensions", &flag_format_extensions, 1,
96650615Sobrien   "-Wformat accepts certain FreeBSD system-dependent formats" },
96750615Sobrien  {"stack-check", &flag_stack_check, 1,
96850615Sobrien   "Insert stack checking code into the program" },
96950615Sobrien  {"argument-alias", &flag_argument_noalias, 0,
97050615Sobrien   "Specify that arguments may alias each other & globals"},
97150615Sobrien  {"argument-noalias", &flag_argument_noalias, 1,
97250615Sobrien   "Assume arguments may alias globals but not each other"},
97350615Sobrien  {"argument-noalias-global", &flag_argument_noalias, 2,
97450615Sobrien   "Assume arguments do not alias each other or globals" },
97550615Sobrien  {"strict-aliasing", &flag_strict_aliasing, 1,
97650615Sobrien   "Assume strict aliasing rules apply" },
97750615Sobrien  {"check-memory-usage", &flag_check_memory_usage, 1,
97850615Sobrien   "Generate code to check every memory access" },
97950615Sobrien  {"prefix-function-name", &flag_prefix_function_name, 1,
98050615Sobrien   "Add a prefix to all function names" },
98152558Sobrien  {"dump-unnumbered", &flag_dump_unnumbered, 1,
98252558Sobrien   "Suppress output of instruction numbers and line number notes in debugging dumps"},
98352558Sobrien  {"instrument-functions", &flag_instrument_function_entry_exit, 1,
98452558Sobrien   "Instrument function entry/exit with profiling calls"},
98552558Sobrien  {"leading-underscore", &flag_leading_underscore, 1,
98652558Sobrien   "External symbols have a leading underscore" },
98752558Sobrien  {"ident", &flag_no_ident, 0,
98852558Sobrien   "Process #ident directives"}
98918334Speter};
99018334Speter
99150615Sobrien#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
99250615Sobrien
99318334Speter/* Table of language-specific options.  */
99418334Speter
99550615Sobrienstatic struct lang_opt
99618334Speter{
99752558Sobrien  const char * option;
99852558Sobrien  const char * description;
99950615Sobrien}
100050615Sobriendocumented_lang_options[] =
100150615Sobrien{
100250615Sobrien  /* In order not to overload the --help output, the convention
100350615Sobrien     used here is to only describe those options which are not
100450615Sobrien     enabled by default.  */
100518334Speter
100650615Sobrien  { "-ansi", "Compile just for ANSI C" },
100750615Sobrien  { "-fallow-single-precision",
100850615Sobrien    "Do not promote floats to double if using -traditional" },
100952558Sobrien  { "-std= ", "Determine language standard"},
101018334Speter
101150615Sobrien  { "-fsigned-bitfields", "" },
101250615Sobrien  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
101350615Sobrien  { "-fno-signed-bitfields", "" },
101450615Sobrien  { "-fno-unsigned-bitfields","" },
101550615Sobrien  { "-fsigned-char", "Make 'char' be signed by default"},
101650615Sobrien  { "-funsigned-char", "Make 'char' be unsigned by default"},
101750615Sobrien  { "-fno-signed-char", "" },
101850615Sobrien  { "-fno-unsigned-char", "" },
101918334Speter
102050615Sobrien  { "-ftraditional", "" },
102150615Sobrien  { "-traditional", "Attempt to support traditional K&R style C"},
102250615Sobrien  { "-fnotraditional", "" },
102350615Sobrien  { "-fno-traditional", "" },
102418334Speter
102550615Sobrien  { "-fasm", "" },
102650615Sobrien  { "-fno-asm", "Do not recognise the 'asm' keyword" },
102750615Sobrien  { "-fbuiltin", "" },
102850615Sobrien  { "-fno-builtin", "Do not recognise any built in functions" },
102950615Sobrien  { "-fhosted", "Assume normal C execution environment" },
103050615Sobrien  { "-fno-hosted", "" },
103150615Sobrien  { "-ffreestanding",
103250615Sobrien    "Assume that standard libraries & main might not exist" },
103350615Sobrien  { "-fno-freestanding", "" },
103450615Sobrien  { "-fcond-mismatch", "Allow different types as args of ? operator"},
103550615Sobrien  { "-fno-cond-mismatch", "" },
103652558Sobrien  { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
103750615Sobrien  { "-fno-dollars-in-identifiers", "" },
103850615Sobrien  { "-fshort-double", "Use the same size for double as for float" },
103950615Sobrien  { "-fno-short-double", "" },
104050615Sobrien  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
104150615Sobrien  { "-fno-short-enums", "" },
104218334Speter
104350615Sobrien  { "-Wall", "Enable most warning messages" },
104450615Sobrien  { "-Wbad-function-cast",
104550615Sobrien    "Warn about casting functions to incompatible types" },
104650615Sobrien  { "-Wno-bad-function-cast", "" },
104752558Sobrien  { "-Wmissing-noreturn",
104852558Sobrien    "Warn about functions which might be candidates for attribute noreturn" },
104952558Sobrien  { "-Wno-missing-noreturn", "" },
105050615Sobrien  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
105150615Sobrien  { "-Wno-cast-qual", "" },
105252558Sobrien  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
105350615Sobrien  { "-Wno-char-subscripts", "" },
105450615Sobrien  { "-Wcomment", "Warn if nested comments are detected" },
105552558Sobrien  { "-Wno-comment", "" },
105652558Sobrien  { "-Wcomments", "Warn if nested comments are detected" },
105752558Sobrien  { "-Wno-comments", "" },
105850615Sobrien  { "-Wconversion", "Warn about possibly confusing type conversions" },
105950615Sobrien  { "-Wno-conversion", "" },
106050615Sobrien  { "-Wformat", "Warn about printf format anomalies" },
106150615Sobrien  { "-Wno-format", "" },
106250615Sobrien  { "-Wimplicit-function-declaration",
106350615Sobrien    "Warn about implicit function declarations" },
106450615Sobrien  { "-Wno-implicit-function-declaration", "" },
106550615Sobrien  { "-Werror-implicit-function-declaration", "" },
106650615Sobrien  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
106750615Sobrien  { "-Wno-implicit-int", "" },
106850615Sobrien  { "-Wimplicit", "" },
106950615Sobrien  { "-Wno-implicit", "" },
107050615Sobrien  { "-Wimport", "Warn about the use of the #import directive" },
107150615Sobrien  { "-Wno-import", "" },
107250615Sobrien  { "-Wlong-long","" },
107350615Sobrien  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
107450615Sobrien  { "-Wmain", "Warn about suspicious declarations of main" },
107550615Sobrien  { "-Wno-main", "" },
107650615Sobrien  { "-Wmissing-braces",
107750615Sobrien    "Warn about possibly missing braces around initialisers" },
107850615Sobrien  { "-Wno-missing-braces", "" },
107950615Sobrien  { "-Wmissing-declarations",
108050615Sobrien    "Warn about global funcs without previous declarations"},
108150615Sobrien  { "-Wno-missing-declarations", "" },
108250615Sobrien  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
108350615Sobrien  { "-Wno-missing-prototypes", "" },
108450615Sobrien  { "-Wmultichar", "Warn about use of multicharacter literals"},
108550615Sobrien  { "-Wno-multichar", "" },
108650615Sobrien  { "-Wnested-externs", "Warn about externs not at file scope level" },
108750615Sobrien  { "-Wno-nested-externs", "" },
108850615Sobrien  { "-Wparentheses", "Warn about possible missing parentheses" },
108950615Sobrien  { "-Wno-parentheses", "" },
109050615Sobrien  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
109150615Sobrien  { "-Wno-pointer-arith", "" },
109250615Sobrien  { "-Wredundant-decls",
109350615Sobrien    "Warn about multiple declarations of the same object" },
109450615Sobrien  { "-Wno-redundant-decls", "" },
109550615Sobrien  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
109650615Sobrien  { "-Wno-sign-compare", "" },
109750615Sobrien  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
109850615Sobrien  { "-Wno-unknown-pragmas", "" },
109950615Sobrien  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
110050615Sobrien  { "-Wno-strict-prototypes", "" },
110152558Sobrien  { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
110250615Sobrien  { "-Wno-traditional", "" },
110350615Sobrien  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
110450615Sobrien  { "-Wno-trigraphs", "" },
110550615Sobrien  { "-Wundef", "" },
110650615Sobrien  { "-Wno-undef", "" },
110750615Sobrien  { "-Wwrite-strings", "Mark strings as 'const char *'"},
110850615Sobrien  { "-Wno-write-strings", "" },
110918334Speter
111050615Sobrien  /* These are for languages with USE_CPPLIB.  */
111150615Sobrien  /* These options are already documented in cpplib.c */
111250615Sobrien  { "--help", "" },
111350615Sobrien  { "-A", "" },
111450615Sobrien  { "-D", "" },
111550615Sobrien  { "-I", "" },
111652558Sobrien#if USE_CPPLIB
111752558Sobrien  { "-MD", "Print dependencies to FILE.d" },
111852558Sobrien  { "-MMD", "Print dependencies to FILE.d" },
111952558Sobrien  { "-M", "Print dependencies to stdout" },
112052558Sobrien  { "-MM", "Print dependencies to stdout" },
112152558Sobrien#endif /* USE_CPPLIB */
112250615Sobrien  { "-U", "" },
112352558Sobrien  { "-H", "" },
112450615Sobrien  { "-idirafter", "" },
112552558Sobrien  { "-imacros", "" },
112652558Sobrien  { "-include", "" },
112750615Sobrien  { "-iprefix", "" },
112850615Sobrien  { "-isystem", "" },
112952558Sobrien  { "-iwithprefix", "" },
113052558Sobrien  { "-iwithprefixbefore", "" },
113150615Sobrien  { "-lang-c", "" },
113250615Sobrien  { "-lang-c89", "" },
113350615Sobrien  { "-lang-c++", "" },
113452558Sobrien  { "-remap", "" },
113550615Sobrien  { "-nostdinc", "" },
113650615Sobrien  { "-nostdinc++", "" },
113750615Sobrien  { "-trigraphs", "" },
113850615Sobrien  { "-undef", "" },
113950615Sobrien
114050615Sobrien#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
114150615Sobrien
114250615Sobrien  /* These are for obj c.  */
114350615Sobrien  DEFINE_LANG_NAME ("Objective C")
114450615Sobrien
114550615Sobrien  { "-lang-objc", "" },
114650615Sobrien  { "-gen-decls", "Dump decls to a .decl file" },
114752558Sobrien  { "-fgnu-runtime", "Generate code for GNU runtime environment" },
114850615Sobrien  { "-fno-gnu-runtime", "" },
114950615Sobrien  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
115050615Sobrien  { "-fno-next-runtime", "" },
115150615Sobrien  { "-Wselector", "Warn if a selector has multiple methods" },
115250615Sobrien  { "-Wno-selector", "" },
115350615Sobrien  { "-Wprotocol", "" },
115450615Sobrien  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
115550615Sobrien  { "-print-objc-runtime-info",
115650615Sobrien    "Generate C header of platform specific features" },
115750615Sobrien
115818334Speter#include "options.h"
115950615Sobrien
116018334Speter};
116150615Sobrien
116250615Sobrien/* Here is a table, controlled by the tm.h file, listing each -m switch
116350615Sobrien   and which bits in `target_switches' it should set or clear.
116450615Sobrien   If VALUE is positive, it is bits to set.
116550615Sobrien   If VALUE is negative, -VALUE is bits to clear.
116650615Sobrien   (The sign bit is not used so there is no confusion.)  */
116750615Sobrien
116850615Sobrienstruct
116950615Sobrien{
117052558Sobrien  const char * name;
117150615Sobrien  int    value;
117252558Sobrien  const char * description;
117350615Sobrien}
117450615Sobrientarget_switches [] = TARGET_SWITCHES;
117550615Sobrien
117650615Sobrien/* This table is similar, but allows the switch to have a value.  */
117750615Sobrien
117850615Sobrien#ifdef TARGET_OPTIONS
117950615Sobrienstruct
118050615Sobrien{
118152558Sobrien  const char *  prefix;
118252558Sobrien  const char ** variable;
118352558Sobrien  const char *  description;
118450615Sobrien}
118550615Sobrientarget_options [] = TARGET_OPTIONS;
118650615Sobrien#endif
118718334Speter
118818334Speter/* Options controlling warnings */
118918334Speter
119018334Speter/* Don't print warning messages.  -w.  */
119118334Speter
119218334Speterint inhibit_warnings = 0;
119318334Speter
119418334Speter/* Print various extra warnings.  -W.  */
119518334Speter
119618334Speterint extra_warnings = 0;
119718334Speter
119818334Speter/* Treat warnings as errors.  -Werror.  */
119918334Speter
120018334Speterint warnings_are_errors = 0;
120118334Speter
120218334Speter/* Nonzero to warn about unused local variables.  */
120318334Speter
120418334Speterint warn_unused;
120518334Speter
120618334Speter/* Nonzero to warn about variables used before they are initialized.  */
120718334Speter
120818334Speterint warn_uninitialized;
120918334Speter
121018334Speter/* Nonzero means warn about all declarations which shadow others.   */
121118334Speter
121218334Speterint warn_shadow;
121318334Speter
121418334Speter/* Warn if a switch on an enum fails to have a case for every enum value.  */
121518334Speter
121618334Speterint warn_switch;
121718334Speter
121818334Speter/* Nonzero means warn about function definitions that default the return type
121918334Speter   or that use a null return and have a return-type other than void.  */
122018334Speter
122118334Speterint warn_return_type;
122218334Speter
122318334Speter/* Nonzero means warn about pointer casts that increase the required
122418334Speter   alignment of the target type (and might therefore lead to a crash
122518334Speter   due to a misaligned access).  */
122618334Speter
122718334Speterint warn_cast_align;
122818334Speter
122918334Speter/* Nonzero means warn about any identifiers that match in the first N
123018334Speter   characters.  The value N is in `id_clash_len'.  */
123118334Speter
123218334Speterint warn_id_clash;
123318334Speterunsigned id_clash_len;
123418334Speter
123518334Speter/* Nonzero means warn about any objects definitions whose size is larger
123618334Speter   than N bytes.  Also want about function definitions whose returned
123718334Speter   values are larger than N bytes. The value N is in `larger_than_size'.  */
123818334Speter
123918334Speterint warn_larger_than;
124018334Speterunsigned larger_than_size;
124118334Speter
124218334Speter/* Nonzero means warn if inline function is too large.  */
124318334Speter
124418334Speterint warn_inline;
124518334Speter
124618334Speter/* Warn if a function returns an aggregate,
124718334Speter   since there are often incompatible calling conventions for doing this.  */
124818334Speter
124918334Speterint warn_aggregate_return;
125018334Speter
125118334Speter/* Likewise for -W.  */
125218334Speter
125350615Sobrienlang_independent_options W_options[] =
125418334Speter{
125550615Sobrien  {"unused", &warn_unused, 1, "Warn when a variable is unused" },
125650615Sobrien  {"error", &warnings_are_errors, 1, ""},
125750615Sobrien  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
125850615Sobrien  {"switch", &warn_switch, 1,
125950615Sobrien   "Warn about enumerated switches missing a specific case" },
126050615Sobrien  {"aggregate-return", &warn_aggregate_return, 1,
126150615Sobrien   "Warn about returning structures, unions or arrays" },
126250615Sobrien  {"cast-align", &warn_cast_align, 1,
126350615Sobrien   "Warn about pointer casts which increase alignment" },
126450615Sobrien  {"uninitialized", &warn_uninitialized, 1,
126550615Sobrien   "Warn about unitialized automatic variables"},
126650615Sobrien  {"inline", &warn_inline, 1,
126750615Sobrien   "Warn when an inlined function cannot be inlined"}
126818334Speter};
126918334Speter
127018334Speter/* Output files for assembler code (real compiler output)
127118334Speter   and debugging dumps.  */
127218334Speter
127318334SpeterFILE *asm_out_file;
127418334SpeterFILE *aux_info_file;
127550615SobrienFILE *rtl_dump_file = NULL;
127618334Speter
127752558Sobrien/* Decode the string P as an integral parameter.
127852558Sobrien   If the string is indeed an integer return its numeric value else
127952558Sobrien   issue an Invalid Option error for the option PNAME and return DEFVAL.
128052558Sobrien   If PNAME is zero just return DEFVAL, do not call error.               */
128152558Sobrien
128252558Sobrienint
128352558Sobrienread_integral_parameter (p, pname, defval)
128452558Sobrien     const char *p;
128552558Sobrien     const char *pname;
128652558Sobrien     const int  defval;
128752558Sobrien{
128852558Sobrien  const char *endp = p;
128952558Sobrien
129052558Sobrien  while (*endp)
129152558Sobrien    {
129252558Sobrien      if (*endp >= '0' && *endp <= '9')
129352558Sobrien	endp++;
129452558Sobrien      else
129552558Sobrien	break;
129652558Sobrien    }
129752558Sobrien
129852558Sobrien  if (*endp != 0)
129952558Sobrien    {
130052558Sobrien      if (pname != 0)
130152558Sobrien	error ("Invalid option `%s'", pname);
130252558Sobrien      return defval;
130352558Sobrien    }
130452558Sobrien
130552558Sobrien  return atoi (p);
130652558Sobrien}
130752558Sobrien
130852558Sobrien
130918334Speter/* Time accumulators, to count the total time spent in various passes.  */
131018334Speter
131118334Speterint parse_time;
131218334Speterint varconst_time;
131318334Speterint integration_time;
131418334Speterint jump_time;
131518334Speterint cse_time;
131650615Sobrienint gcse_time;
131718334Speterint loop_time;
131818334Speterint cse2_time;
131950615Sobrienint branch_prob_time;
132018334Speterint flow_time;
132118334Speterint combine_time;
132250615Sobrienint regmove_time;
132318334Speterint sched_time;
132418334Speterint local_alloc_time;
132518334Speterint global_alloc_time;
132652558Sobrienint flow2_time;
132718334Speterint sched2_time;
132850615Sobrien#ifdef DELAY_SLOTS
132918334Speterint dbr_sched_time;
133050615Sobrien#endif
133118334Speterint shorten_branch_time;
133218334Speterint stack_reg_time;
133318334Speterint final_time;
133418334Speterint symout_time;
133518334Speterint dump_time;
133618334Speter
133718334Speter/* Return time used so far, in microseconds.  */
133818334Speter
133952558Sobrienlong
134018334Speterget_run_time ()
134118334Speter{
134218334Speter  if (quiet_flag)
134318334Speter    return 0;
134450615Sobrien
134550615Sobrien#ifdef __BEOS__
134650615Sobrien  return 0;
134750615Sobrien#else /* not BeOS */
134852558Sobrien#if defined (_WIN32) && !defined (__CYGWIN__)
134918334Speter  if (clock() < 0)
135018334Speter    return 0;
135118334Speter  else
135218334Speter    return (clock() * 1000);
135318334Speter#else /* not _WIN32 */
135450615Sobrien#ifdef _SC_CLK_TCK
135550615Sobrien  {
135650615Sobrien    static int tick;
135750615Sobrien    struct tms tms;
135850615Sobrien    if (tick == 0)
135950615Sobrien      tick = 1000000 / sysconf(_SC_CLK_TCK);
136050615Sobrien    times (&tms);
136150615Sobrien    return (tms.tms_utime + tms.tms_stime) * tick;
136250615Sobrien  }
136350615Sobrien#else
136418334Speter#ifdef USG
136550615Sobrien  {
136650615Sobrien    struct tms tms;
136750615Sobrien#   if HAVE_SYSCONF && defined _SC_CLK_TCK
136850615Sobrien#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
136950615Sobrien#   else
137050615Sobrien#    ifdef CLK_TCK
137150615Sobrien#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
137250615Sobrien#    else
137350615Sobrien#     define TICKS_PER_SECOND HZ /* traditional UNIX */
137450615Sobrien#    endif
137550615Sobrien#   endif
137650615Sobrien    times (&tms);
137750615Sobrien    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
137850615Sobrien  }
137918334Speter#else
138018334Speter#ifndef VMS
138150615Sobrien  {
138250615Sobrien    struct rusage rusage;
138350615Sobrien    getrusage (0, &rusage);
138450615Sobrien    return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
138550615Sobrien	    + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
138650615Sobrien  }
138718334Speter#else /* VMS */
138850615Sobrien  {
138950615Sobrien    struct
139050615Sobrien      {
139150615Sobrien        int proc_user_time;
139250615Sobrien        int proc_system_time;
139350615Sobrien        int child_user_time;
139450615Sobrien        int child_system_time;
139550615Sobrien      } vms_times;
139650615Sobrien    times ((void *) &vms_times);
139750615Sobrien    return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
139850615Sobrien  }
139950615Sobrien#endif	/* VMS */
140050615Sobrien#endif	/* USG */
140150615Sobrien#endif  /* _SC_CLK_TCK */
140250615Sobrien#endif	/* _WIN32 */
140350615Sobrien#endif	/* __BEOS__ */
140418334Speter}
140518334Speter
140618334Speter#define TIMEVAR(VAR, BODY)    \
140718334Speterdo { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
140818334Speter
140918334Spetervoid
141018334Speterprint_time (str, total)
141152558Sobrien     const char *str;
141218334Speter     int total;
141318334Speter{
141418334Speter  fprintf (stderr,
141518334Speter	   "time in %s: %d.%06d\n",
141618334Speter	   str, total / 1000000, total % 1000000);
141718334Speter}
141818334Speter
141918334Speter/* Count an error or warning.  Return 1 if the message should be printed.  */
142018334Speter
142118334Speterint
142218334Spetercount_error (warningp)
142318334Speter     int warningp;
142418334Speter{
142518334Speter  if (warningp && inhibit_warnings)
142618334Speter    return 0;
142718334Speter
142818334Speter  if (warningp && !warnings_are_errors)
142918334Speter    warningcount++;
143018334Speter  else
143118334Speter    {
143218334Speter      static int warning_message = 0;
143318334Speter
143418334Speter      if (warningp && !warning_message)
143518334Speter	{
143652558Sobrien	  notice ("%s: warnings being treated as errors\n", progname);
143718334Speter	  warning_message = 1;
143818334Speter	}
143918334Speter      errorcount++;
144018334Speter    }
144118334Speter
144218334Speter  return 1;
144318334Speter}
144418334Speter
144518334Speter/* Print a fatal error message.  NAME is the text.
144618334Speter   Also include a system error message based on `errno'.  */
144718334Speter
144818334Spetervoid
144918334Speterpfatal_with_name (name)
145052558Sobrien  const char *name;
145118334Speter{
145218334Speter  fprintf (stderr, "%s: ", progname);
145318334Speter  perror (name);
145418334Speter  exit (FATAL_EXIT_CODE);
145518334Speter}
145618334Speter
145718334Spetervoid
145818334Speterfatal_io_error (name)
145952558Sobrien  const char *name;
146018334Speter{
146152558Sobrien  notice ("%s: %s: I/O error\n", progname, name);
146218334Speter  exit (FATAL_EXIT_CODE);
146318334Speter}
146418334Speter
146518334Speter/* Called to give a better error message for a bad insn rather than
146618334Speter   just calling abort().  */
146718334Speter
146818334Spetervoid
146952558Sobrienfatal_insn VPROTO((const char *msgid, rtx insn, ...))
147018334Speter{
147152558Sobrien#ifndef ANSI_PROTOTYPES
147252558Sobrien  const char *msgid;
147352558Sobrien  rtx insn;
147452558Sobrien#endif
147552558Sobrien  va_list ap;
147652558Sobrien
147752558Sobrien  VA_START (ap, insn);
147852558Sobrien
147952558Sobrien#ifndef ANSI_PROTOTYPES
148052558Sobrien  msgid = va_arg (ap, const char *);
148152558Sobrien  insn = va_arg (ap, rtx);
148252558Sobrien#endif
148352558Sobrien
148452558Sobrien  verror (msgid, ap);
148550615Sobrien  debug_rtx (insn);
148652558Sobrien  exit (FATAL_EXIT_CODE);
148718334Speter}
148818334Speter
148918334Speter/* Called to give a better error message when we don't have an insn to match
149018334Speter   what we are looking for or if the insn's constraints aren't satisfied,
149118334Speter   rather than just calling abort().  */
149218334Speter
149318334Spetervoid
149418334Speterfatal_insn_not_found (insn)
149518334Speter     rtx insn;
149618334Speter{
149718334Speter  if (INSN_CODE (insn) < 0)
149818334Speter    fatal_insn ("internal error--unrecognizable insn:", insn);
149918334Speter  else
150018334Speter    fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
150118334Speter}
150218334Speter
150318334Speter/* This is the default decl_printable_name function.  */
150418334Speter
150518334Speterstatic char *
150650615Sobriendecl_name (decl, verbosity)
150718334Speter     tree decl;
150852558Sobrien     int verbosity ATTRIBUTE_UNUSED;
150918334Speter{
151018334Speter  return IDENTIFIER_POINTER (DECL_NAME (decl));
151118334Speter}
151218334Speter
151318334Speterstatic int need_error_newline;
151418334Speter
151518334Speter/* Function of last error message;
151618334Speter   more generally, function such that if next error message is in it
151718334Speter   then we don't have to mention the function name.  */
151818334Speterstatic tree last_error_function = NULL;
151918334Speter
152018334Speter/* Used to detect when input_file_stack has changed since last described.  */
152118334Speterstatic int last_error_tick;
152218334Speter
152318334Speter/* Called when the start of a function definition is parsed,
152418334Speter   this function prints on stderr the name of the function.  */
152518334Speter
152618334Spetervoid
152718334Speterannounce_function (decl)
152818334Speter     tree decl;
152918334Speter{
153018334Speter  if (! quiet_flag)
153118334Speter    {
153218334Speter      if (rtl_dump_and_exit)
153318334Speter	fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
153418334Speter      else
153550615Sobrien	fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
153618334Speter      fflush (stderr);
153718334Speter      need_error_newline = 1;
153818334Speter      last_error_function = current_function_decl;
153918334Speter    }
154018334Speter}
154118334Speter
154218334Speter/* The default function to print out name of current function that caused
154318334Speter   an error.  */
154418334Speter
154518334Spetervoid
154618334Speterdefault_print_error_function (file)
154752558Sobrien  const char *file;
154818334Speter{
154918334Speter  if (last_error_function != current_function_decl)
155018334Speter    {
155118334Speter      if (file)
155218334Speter	fprintf (stderr, "%s: ", file);
155318334Speter
155418334Speter      if (current_function_decl == NULL)
155552558Sobrien	notice ("At top level:\n");
155618334Speter      else
155752558Sobrien	notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
155852558Sobrien		 ? "In method `%s':\n"
155952558Sobrien		 : "In function `%s':\n"),
156052558Sobrien		(*decl_printable_name) (current_function_decl, 2));
156118334Speter
156218334Speter      last_error_function = current_function_decl;
156318334Speter    }
156418334Speter}
156518334Speter
156618334Speter/* Called by report_error_function to print out function name.
156750615Sobrien * Default may be overridden by language front-ends.  */
156818334Speter
156952558Sobrienvoid (*print_error_function) PROTO((const char *)) =
157052558Sobrien  default_print_error_function;
157118334Speter
157218334Speter/* Prints out, if necessary, the name of the current function
157352558Sobrien  that caused an error.  Called from all error and warning functions.
157452558Sobrien  We ignore the FILE parameter, as it cannot be relied upon.  */
157518334Speter
157618334Spetervoid
157718334Speterreport_error_function (file)
157852558Sobrien  const char *file ATTRIBUTE_UNUSED;
157918334Speter{
158018334Speter  struct file_stack *p;
158118334Speter
158218334Speter  if (need_error_newline)
158318334Speter    {
158418334Speter      fprintf (stderr, "\n");
158518334Speter      need_error_newline = 0;
158618334Speter    }
158718334Speter
158818334Speter  if (input_file_stack && input_file_stack->next != 0
158952558Sobrien      && input_file_stack_tick != last_error_tick)
159018334Speter    {
159118334Speter      for (p = input_file_stack->next; p; p = p->next)
159252558Sobrien	notice ((p == input_file_stack->next
159352558Sobrien		 ?    "In file included from %s:%d"
159452558Sobrien		 : ",\n                 from %s:%d"),
159552558Sobrien		p->name, p->line);
159618334Speter      fprintf (stderr, ":\n");
159718334Speter      last_error_tick = input_file_stack_tick;
159818334Speter    }
159952558Sobrien
160052558Sobrien  (*print_error_function) (input_filename);
160118334Speter}
160218334Speter
160318334Speter/* Print a message.  */
160418334Speter
160518334Speterstatic void
160652558Sobrienvnotice (file, msgid, ap)
160752558Sobrien     FILE *file;
160852558Sobrien     char *msgid;
160918334Speter     va_list ap;
161018334Speter{
161152558Sobrien  vfprintf (file, _(msgid), ap);
161252558Sobrien}
161318334Speter
161452558Sobrienvoid
161552558Sobriennotice VPROTO((const char *msgid, ...))
161652558Sobrien{
161752558Sobrien#ifndef ANSI_PROTOTYPES
161852558Sobrien  char *msgid;
161952558Sobrien#endif
162052558Sobrien  va_list ap;
162152558Sobrien
162252558Sobrien  VA_START (ap, msgid);
162352558Sobrien
162452558Sobrien#ifndef ANSI_PROTOTYPES
162552558Sobrien  msgid = va_arg (ap, char *);
162652558Sobrien#endif
162752558Sobrien
162852558Sobrien  vnotice (stderr, msgid, ap);
162952558Sobrien  va_end (ap);
163018334Speter}
163118334Speter
163252558Sobrienvoid
163352558Sobrienfnotice VPROTO((FILE *file, const char *msgid, ...))
163452558Sobrien{
163552558Sobrien#ifndef ANSI_PROTOTYPES
163652558Sobrien  FILE *file;
163752558Sobrien  const char *msgid;
163852558Sobrien#endif
163952558Sobrien  va_list ap;
164018334Speter
164152558Sobrien  VA_START (ap, msgid);
164252558Sobrien
164352558Sobrien#ifndef ANSI_PROTOTYPES
164452558Sobrien  file = va_arg (ap, FILE *);
164552558Sobrien  msgid = va_arg (ap, const char *);
164652558Sobrien#endif
164752558Sobrien
164852558Sobrien  vnotice (file, msgid, ap);
164952558Sobrien  va_end (ap);
165052558Sobrien}
165152558Sobrien
165252558Sobrien/* Report FILE and LINE (or program name), and optionally just WARN.  */
165352558Sobrien
165418334Speterstatic void
165552558Sobrienreport_file_and_line (file, line, warn)
165618334Speter     char *file;
165718334Speter     int line;
165852558Sobrien     int warn;
165918334Speter{
166018334Speter  if (file)
166118334Speter    fprintf (stderr, "%s:%d: ", file, line);
166218334Speter  else
166318334Speter    fprintf (stderr, "%s: ", progname);
166418334Speter
166552558Sobrien  if (warn)
166652558Sobrien    notice ("warning: ");
166752558Sobrien}
166852558Sobrien
166952558Sobrien/* Print a message.  */
167052558Sobrien
167152558Sobrienstatic void
167252558Sobrienvmessage (prefix, msgid, ap)
167352558Sobrien     const char *prefix;
167452558Sobrien     const char *msgid;
167552558Sobrien     va_list ap;
167652558Sobrien{
167752558Sobrien  if (prefix)
167852558Sobrien    fprintf (stderr, "%s: ", prefix);
167952558Sobrien
168052558Sobrien  vfprintf (stderr, msgid, ap);
168152558Sobrien}
168252558Sobrien
168352558Sobrien/* Print a message relevant to line LINE of file FILE.  */
168452558Sobrien
168552558Sobrienstatic void
168652558Sobrienv_message_with_file_and_line (file, line, warn, msgid, ap)
168752558Sobrien     const char *file;
168852558Sobrien     int line;
168952558Sobrien     int warn;
169052558Sobrien     const char *msgid;
169152558Sobrien     va_list ap;
169252558Sobrien{
169352558Sobrien  report_file_and_line (file, line, warn);
169452558Sobrien  vnotice (stderr, msgid, ap);
169518334Speter  fputc ('\n', stderr);
169618334Speter}
169718334Speter
169818334Speter/* Print a message relevant to the given DECL.  */
169918334Speter
170018334Speterstatic void
170152558Sobrienv_message_with_decl (decl, warn, msgid, ap)
170218334Speter     tree decl;
170352558Sobrien     int warn;
170452558Sobrien     const char *msgid;
170518334Speter     va_list ap;
170618334Speter{
170752558Sobrien  const char *p;
170818334Speter
170952558Sobrien  report_file_and_line (DECL_SOURCE_FILE (decl),
171052558Sobrien			DECL_SOURCE_LINE (decl), warn);
171118334Speter
171218334Speter  /* Do magic to get around lack of varargs support for insertion
171318334Speter     of arguments into existing list.  We know that the decl is first;
171418334Speter     we ass_u_me that it will be printed with "%s".  */
171518334Speter
171652558Sobrien  for (p = _(msgid); *p; ++p)
171718334Speter    {
171818334Speter      if (*p == '%')
171918334Speter	{
172018334Speter	  if (*(p + 1) == '%')
172118334Speter	    ++p;
172252558Sobrien	  else if (*(p + 1) != 's')
172352558Sobrien	    abort ();
172418334Speter	  else
172518334Speter	    break;
172618334Speter	}
172718334Speter    }
172818334Speter
172952558Sobrien  if (p > _(msgid))			/* Print the left-hand substring.  */
173018334Speter    {
173118334Speter      char fmt[sizeof "%.255s"];
173252558Sobrien      long width = p - _(msgid);
173318334Speter
173418334Speter      if (width > 255L) width = 255L;	/* arbitrary */
173518334Speter      sprintf (fmt, "%%.%lds", width);
173652558Sobrien      fprintf (stderr, fmt, _(msgid));
173718334Speter    }
173818334Speter
173918334Speter  if (*p == '%')		/* Print the name.  */
174018334Speter    {
174152558Sobrien      const char *n = (DECL_NAME (decl)
174250615Sobrien		 ? (*decl_printable_name) (decl, 2)
174318334Speter		 : "((anonymous))");
174418334Speter      fputs (n, stderr);
174518334Speter      while (*p)
174618334Speter	{
174718334Speter	  ++p;
174850615Sobrien	  if (ISALPHA (*(p - 1) & 0xFF))
174918334Speter	    break;
175018334Speter	}
175118334Speter    }
175218334Speter
175318334Speter  if (*p)			/* Print the rest of the message.  */
175418334Speter    vmessage ((char *)NULL, p, ap);
175518334Speter
175618334Speter  fputc ('\n', stderr);
175718334Speter}
175818334Speter
175918334Speter/* Figure file and line of the given INSN.  */
176018334Speter
176118334Speterstatic void
176218334Speterfile_and_line_for_asm (insn, pfile, pline)
176318334Speter     rtx insn;
176418334Speter     char **pfile;
176518334Speter     int *pline;
176618334Speter{
176718334Speter  rtx body = PATTERN (insn);
176818334Speter  rtx asmop;
176918334Speter
177018334Speter  /* Find the (or one of the) ASM_OPERANDS in the insn.  */
177118334Speter  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
177218334Speter    asmop = SET_SRC (body);
177318334Speter  else if (GET_CODE (body) == ASM_OPERANDS)
177418334Speter    asmop = body;
177518334Speter  else if (GET_CODE (body) == PARALLEL
177618334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
177718334Speter    asmop = SET_SRC (XVECEXP (body, 0, 0));
177818334Speter  else if (GET_CODE (body) == PARALLEL
177918334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
178018334Speter    asmop = XVECEXP (body, 0, 0);
178118334Speter  else
178218334Speter    asmop = NULL;
178318334Speter
178418334Speter  if (asmop)
178518334Speter    {
178618334Speter      *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
178718334Speter      *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
178818334Speter    }
178918334Speter  else
179018334Speter    {
179118334Speter      *pfile = input_filename;
179218334Speter      *pline = lineno;
179318334Speter    }
179418334Speter}
179518334Speter
179618334Speter/* Report an error at line LINE of file FILE.  */
179718334Speter
179818334Speterstatic void
179952558Sobrienv_error_with_file_and_line (file, line, msgid, ap)
180052558Sobrien     const char *file;
180118334Speter     int line;
180252558Sobrien     const char *msgid;
180318334Speter     va_list ap;
180418334Speter{
180518334Speter  count_error (0);
180618334Speter  report_error_function (file);
180752558Sobrien  v_message_with_file_and_line (file, line, 0, msgid, ap);
180818334Speter}
180918334Speter
181018334Spetervoid
181152558Sobrienerror_with_file_and_line VPROTO((const char *file, int line,
181252558Sobrien				 const char *msgid, ...))
181318334Speter{
181452558Sobrien#ifndef ANSI_PROTOTYPES
181552558Sobrien  const char *file;
181618334Speter  int line;
181752558Sobrien  const char *msgid;
181818334Speter#endif
181918334Speter  va_list ap;
182018334Speter
182152558Sobrien  VA_START (ap, msgid);
182218334Speter
182352558Sobrien#ifndef ANSI_PROTOTYPES
182452558Sobrien  file = va_arg (ap, const char *);
182518334Speter  line = va_arg (ap, int);
182652558Sobrien  msgid = va_arg (ap, const char *);
182718334Speter#endif
182818334Speter
182952558Sobrien  v_error_with_file_and_line (file, line, msgid, ap);
183018334Speter  va_end (ap);
183118334Speter}
183218334Speter
183318334Speter/* Report an error at the declaration DECL.
183452558Sobrien   MSGID is a format string which uses %s to substitute the declaration
183518334Speter   name; subsequent substitutions are a la printf.  */
183618334Speter
183718334Speterstatic void
183852558Sobrienv_error_with_decl (decl, msgid, ap)
183918334Speter     tree decl;
184052558Sobrien     const char *msgid;
184118334Speter     va_list ap;
184218334Speter{
184318334Speter  count_error (0);
184418334Speter  report_error_function (DECL_SOURCE_FILE (decl));
184552558Sobrien  v_message_with_decl (decl, 0, msgid, ap);
184618334Speter}
184718334Speter
184818334Spetervoid
184952558Sobrienerror_with_decl VPROTO((tree decl, const char *msgid, ...))
185018334Speter{
185152558Sobrien#ifndef ANSI_PROTOTYPES
185218334Speter  tree decl;
185352558Sobrien  const char *msgid;
185418334Speter#endif
185518334Speter  va_list ap;
185618334Speter
185752558Sobrien  VA_START (ap, msgid);
185818334Speter
185952558Sobrien#ifndef ANSI_PROTOTYPES
186018334Speter  decl = va_arg (ap, tree);
186152558Sobrien  msgid = va_arg (ap, const char *);
186218334Speter#endif
186318334Speter
186452558Sobrien  v_error_with_decl (decl, msgid, ap);
186518334Speter  va_end (ap);
186618334Speter}
186718334Speter
186818334Speter/* Report an error at the line number of the insn INSN.
186918334Speter   This is used only when INSN is an `asm' with operands,
187018334Speter   and each ASM_OPERANDS records its own source file and line.  */
187118334Speter
187218334Speterstatic void
187352558Sobrienv_error_for_asm (insn, msgid, ap)
187418334Speter     rtx insn;
187552558Sobrien     const char *msgid;
187618334Speter     va_list ap;
187718334Speter{
187818334Speter  char *file;
187918334Speter  int line;
188018334Speter
188118334Speter  count_error (0);
188218334Speter  file_and_line_for_asm (insn, &file, &line);
188318334Speter  report_error_function (file);
188452558Sobrien  v_message_with_file_and_line (file, line, 0, msgid, ap);
188518334Speter}
188618334Speter
188718334Spetervoid
188852558Sobrienerror_for_asm VPROTO((rtx insn, const char *msgid, ...))
188918334Speter{
189052558Sobrien#ifndef ANSI_PROTOTYPES
189118334Speter  rtx insn;
189252558Sobrien  const char *msgid;
189318334Speter#endif
189418334Speter  va_list ap;
189518334Speter
189652558Sobrien  VA_START (ap, msgid);
189718334Speter
189852558Sobrien#ifndef ANSI_PROTOTYPES
189918334Speter  insn = va_arg (ap, rtx);
190052558Sobrien  msgid = va_arg (ap, const char *);
190118334Speter#endif
190218334Speter
190352558Sobrien  v_error_for_asm (insn, msgid, ap);
190418334Speter  va_end (ap);
190518334Speter}
190618334Speter
190718334Speter/* Report an error at the current line number.  */
190818334Speter
190918334Speterstatic void
191052558Sobrienverror (msgid, ap)
191152558Sobrien     const char *msgid;
191218334Speter     va_list ap;
191318334Speter{
191452558Sobrien  v_error_with_file_and_line (input_filename, lineno, msgid, ap);
191518334Speter}
191618334Speter
191718334Spetervoid
191852558Sobrienerror VPROTO((const char *msgid, ...))
191918334Speter{
192052558Sobrien#ifndef ANSI_PROTOTYPES
192152558Sobrien  const char *msgid;
192218334Speter#endif
192318334Speter  va_list ap;
192418334Speter
192552558Sobrien  VA_START (ap, msgid);
192618334Speter
192752558Sobrien#ifndef ANSI_PROTOTYPES
192852558Sobrien  msgid = va_arg (ap, const char *);
192918334Speter#endif
193018334Speter
193152558Sobrien  verror (msgid, ap);
193218334Speter  va_end (ap);
193318334Speter}
193418334Speter
193518334Speter/* Report a fatal error at the current line number.  */
193618334Speter
193718334Speterstatic void
193852558Sobrienvfatal (msgid, ap)
193952558Sobrien     const char *msgid;
194018334Speter     va_list ap;
194118334Speter{
194252558Sobrien  verror (msgid, ap);
194318334Speter  exit (FATAL_EXIT_CODE);
194418334Speter}
194518334Speter
194618334Spetervoid
194752558Sobrienfatal VPROTO((const char *msgid, ...))
194818334Speter{
194952558Sobrien#ifndef ANSI_PROTOTYPES
195052558Sobrien  const char *msgid;
195118334Speter#endif
195218334Speter  va_list ap;
195318334Speter
195452558Sobrien  VA_START (ap, msgid);
195518334Speter
195652558Sobrien#ifndef ANSI_PROTOTYPES
195752558Sobrien  msgid = va_arg (ap, const char *);
195818334Speter#endif
195918334Speter
196052558Sobrien  vfatal (msgid, ap);
196118334Speter  va_end (ap);
196218334Speter}
196318334Speter
196418334Speter/* Report a warning at line LINE of file FILE.  */
196518334Speter
196618334Speterstatic void
196752558Sobrienv_warning_with_file_and_line (file, line, msgid, ap)
196852558Sobrien     const char *file;
196918334Speter     int line;
197052558Sobrien     const char *msgid;
197118334Speter     va_list ap;
197218334Speter{
197318334Speter  if (count_error (1))
197418334Speter    {
197518334Speter      report_error_function (file);
197652558Sobrien      v_message_with_file_and_line (file, line, 1, msgid, ap);
197718334Speter    }
197818334Speter}
197918334Speter
198018334Spetervoid
198152558Sobrienwarning_with_file_and_line VPROTO((const char *file, int line,
198252558Sobrien				   const char *msgid, ...))
198318334Speter{
198452558Sobrien#ifndef ANSI_PROTOTYPES
198552558Sobrien  const char *file;
198618334Speter  int line;
198752558Sobrien  const char *msgid;
198818334Speter#endif
198918334Speter  va_list ap;
199018334Speter
199152558Sobrien  VA_START (ap, msgid);
199218334Speter
199352558Sobrien#ifndef ANSI_PROTOTYPES
199452558Sobrien  file = va_arg (ap, const char *);
199518334Speter  line = va_arg (ap, int);
199652558Sobrien  msgid = va_arg (ap, const char *);
199718334Speter#endif
199818334Speter
199952558Sobrien  v_warning_with_file_and_line (file, line, msgid, ap);
200018334Speter  va_end (ap);
200118334Speter}
200218334Speter
200318334Speter/* Report a warning at the declaration DECL.
200452558Sobrien   MSGID is a format string which uses %s to substitute the declaration
200518334Speter   name; subsequent substitutions are a la printf.  */
200618334Speter
200718334Speterstatic void
200852558Sobrienv_warning_with_decl (decl, msgid, ap)
200918334Speter     tree decl;
201052558Sobrien     const char *msgid;
201118334Speter     va_list ap;
201218334Speter{
201318334Speter  if (count_error (1))
201418334Speter    {
201518334Speter      report_error_function (DECL_SOURCE_FILE (decl));
201652558Sobrien      v_message_with_decl (decl, 1, msgid, ap);
201718334Speter    }
201818334Speter}
201918334Speter
202018334Spetervoid
202152558Sobrienwarning_with_decl VPROTO((tree decl, const char *msgid, ...))
202218334Speter{
202352558Sobrien#ifndef ANSI_PROTOTYPES
202418334Speter  tree decl;
202552558Sobrien  const char *msgid;
202618334Speter#endif
202718334Speter  va_list ap;
202818334Speter
202952558Sobrien  VA_START (ap, msgid);
203018334Speter
203152558Sobrien#ifndef ANSI_PROTOTYPES
203218334Speter  decl = va_arg (ap, tree);
203352558Sobrien  msgid = va_arg (ap, const char *);
203418334Speter#endif
203518334Speter
203652558Sobrien  v_warning_with_decl (decl, msgid, ap);
203718334Speter  va_end (ap);
203818334Speter}
203918334Speter
204018334Speter/* Report a warning at the line number of the insn INSN.
204118334Speter   This is used only when INSN is an `asm' with operands,
204218334Speter   and each ASM_OPERANDS records its own source file and line.  */
204318334Speter
204418334Speterstatic void
204552558Sobrienv_warning_for_asm (insn, msgid, ap)
204618334Speter     rtx insn;
204752558Sobrien     const char *msgid;
204818334Speter     va_list ap;
204918334Speter{
205018334Speter  if (count_error (1))
205118334Speter    {
205218334Speter      char *file;
205318334Speter      int line;
205418334Speter
205518334Speter      file_and_line_for_asm (insn, &file, &line);
205618334Speter      report_error_function (file);
205752558Sobrien      v_message_with_file_and_line (file, line, 1, msgid, ap);
205818334Speter    }
205918334Speter}
206018334Speter
206118334Spetervoid
206252558Sobrienwarning_for_asm VPROTO((rtx insn, const char *msgid, ...))
206318334Speter{
206452558Sobrien#ifndef ANSI_PROTOTYPES
206518334Speter  rtx insn;
206652558Sobrien  const char *msgid;
206718334Speter#endif
206818334Speter  va_list ap;
206918334Speter
207052558Sobrien  VA_START (ap, msgid);
207118334Speter
207252558Sobrien#ifndef ANSI_PROTOTYPES
207318334Speter  insn = va_arg (ap, rtx);
207452558Sobrien  msgid = va_arg (ap, const char *);
207518334Speter#endif
207618334Speter
207752558Sobrien  v_warning_for_asm (insn, msgid, ap);
207818334Speter  va_end (ap);
207918334Speter}
208018334Speter
208118334Speter/* Report a warning at the current line number.  */
208218334Speter
208318334Speterstatic void
208452558Sobrienvwarning (msgid, ap)
208552558Sobrien     const char *msgid;
208618334Speter     va_list ap;
208718334Speter{
208852558Sobrien  v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
208918334Speter}
209018334Speter
209118334Spetervoid
209252558Sobrienwarning VPROTO((const char *msgid, ...))
209318334Speter{
209452558Sobrien#ifndef ANSI_PROTOTYPES
209552558Sobrien  const char *msgid;
209618334Speter#endif
209718334Speter  va_list ap;
209818334Speter
209952558Sobrien  VA_START (ap, msgid);
210018334Speter
210152558Sobrien#ifndef ANSI_PROTOTYPES
210252558Sobrien  msgid = va_arg (ap, const char *);
210318334Speter#endif
210418334Speter
210552558Sobrien  vwarning (msgid, ap);
210618334Speter  va_end (ap);
210718334Speter}
210818334Speter
210918334Speter/* These functions issue either warnings or errors depending on
211018334Speter   -pedantic-errors.  */
211118334Speter
211218334Speterstatic void
211352558Sobrienvpedwarn (msgid, ap)
211452558Sobrien     const char *msgid;
211518334Speter     va_list ap;
211618334Speter{
211718334Speter  if (flag_pedantic_errors)
211852558Sobrien    verror (msgid, ap);
211918334Speter  else
212052558Sobrien    vwarning (msgid, ap);
212118334Speter}
212218334Speter
212318334Spetervoid
212452558Sobrienpedwarn VPROTO((const char *msgid, ...))
212518334Speter{
212652558Sobrien#ifndef ANSI_PROTOTYPES
212752558Sobrien  const char *msgid;
212818334Speter#endif
212918334Speter  va_list ap;
213018334Speter
213152558Sobrien  VA_START (ap, msgid);
213218334Speter
213352558Sobrien#ifndef ANSI_PROTOTYPES
213452558Sobrien  msgid = va_arg (ap, const char *);
213518334Speter#endif
213618334Speter
213752558Sobrien  vpedwarn (msgid, ap);
213818334Speter  va_end (ap);
213918334Speter}
214018334Speter
214118334Speterstatic void
214252558Sobrienv_pedwarn_with_decl (decl, msgid, ap)
214318334Speter     tree decl;
214452558Sobrien     const char *msgid;
214518334Speter     va_list ap;
214618334Speter{
214718334Speter  /* We don't want -pedantic-errors to cause the compilation to fail from
214818334Speter     "errors" in system header files.  Sometimes fixincludes can't fix what's
214918334Speter     broken (eg: unsigned char bitfields - fixing it may change the alignment
215018334Speter     which will cause programs to mysteriously fail because the C library
215118334Speter     or kernel uses the original layout).  There's no point in issuing a
215218334Speter     warning either, it's just unnecessary noise.  */
215318334Speter
215418334Speter  if (! DECL_IN_SYSTEM_HEADER (decl))
215518334Speter    {
215618334Speter      if (flag_pedantic_errors)
215752558Sobrien	v_error_with_decl (decl, msgid, ap);
215818334Speter      else
215952558Sobrien	v_warning_with_decl (decl, msgid, ap);
216018334Speter    }
216118334Speter}
216218334Speter
216318334Spetervoid
216452558Sobrienpedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
216518334Speter{
216652558Sobrien#ifndef ANSI_PROTOTYPES
216718334Speter  tree decl;
216852558Sobrien  const char *msgid;
216918334Speter#endif
217018334Speter  va_list ap;
217118334Speter
217252558Sobrien  VA_START (ap, msgid);
217318334Speter
217452558Sobrien#ifndef ANSI_PROTOTYPES
217518334Speter  decl = va_arg (ap, tree);
217652558Sobrien  msgid = va_arg (ap, const char *);
217718334Speter#endif
217818334Speter
217952558Sobrien  v_pedwarn_with_decl (decl, msgid, ap);
218018334Speter  va_end (ap);
218118334Speter}
218218334Speter
218318334Speterstatic void
218452558Sobrienv_pedwarn_with_file_and_line (file, line, msgid, ap)
218552558Sobrien     const char *file;
218618334Speter     int line;
218752558Sobrien     const char *msgid;
218818334Speter     va_list ap;
218918334Speter{
219018334Speter  if (flag_pedantic_errors)
219152558Sobrien    v_error_with_file_and_line (file, line, msgid, ap);
219218334Speter  else
219352558Sobrien    v_warning_with_file_and_line (file, line, msgid, ap);
219418334Speter}
219518334Speter
219618334Spetervoid
219752558Sobrienpedwarn_with_file_and_line VPROTO((const char *file, int line,
219852558Sobrien				   const char *msgid, ...))
219918334Speter{
220052558Sobrien#ifndef ANSI_PROTOTYPES
220152558Sobrien  const char *file;
220218334Speter  int line;
220352558Sobrien  const char *msgid;
220418334Speter#endif
220518334Speter  va_list ap;
220618334Speter
220752558Sobrien  VA_START (ap, msgid);
220818334Speter
220952558Sobrien#ifndef ANSI_PROTOTYPES
221052558Sobrien  file = va_arg (ap, const char *);
221118334Speter  line = va_arg (ap, int);
221252558Sobrien  msgid = va_arg (ap, const char *);
221318334Speter#endif
221418334Speter
221552558Sobrien  v_pedwarn_with_file_and_line (file, line, msgid, ap);
221618334Speter  va_end (ap);
221718334Speter}
221818334Speter
221918334Speter/* Apologize for not implementing some feature.  */
222018334Speter
222118334Speterstatic void
222252558Sobrienvsorry (msgid, ap)
222352558Sobrien     const char *msgid;
222418334Speter     va_list ap;
222518334Speter{
222618334Speter  sorrycount++;
222718334Speter  if (input_filename)
222818334Speter    fprintf (stderr, "%s:%d: ", input_filename, lineno);
222918334Speter  else
223018334Speter    fprintf (stderr, "%s: ", progname);
223152558Sobrien  notice ("sorry, not implemented: ");
223252558Sobrien  vnotice (stderr, msgid, ap);
223318334Speter  fputc ('\n', stderr);
223418334Speter}
223518334Speter
223618334Spetervoid
223752558Sobriensorry VPROTO((const char *msgid, ...))
223818334Speter{
223952558Sobrien#ifndef ANSI_PROTOTYPES
224052558Sobrien  const char *msgid;
224118334Speter#endif
224218334Speter  va_list ap;
224318334Speter
224452558Sobrien  VA_START (ap, msgid);
224518334Speter
224652558Sobrien#ifndef ANSI_PROTOTYPES
224752558Sobrien  msgid = va_arg (ap, const char *);
224818334Speter#endif
224918334Speter
225052558Sobrien  vsorry (msgid, ap);
225118334Speter  va_end (ap);
225218334Speter}
225352558Sobrien
225452558Sobrien/* Given a partial pathname as input, return another pathname that shares
225552558Sobrien   no elements with the pathname of __FILE__.  This is used by abort() to
225652558Sobrien   print `Internal compiler error in expr.c' instead of `Internal compiler
225752558Sobrien   error in ../../egcs/gcc/expr.c'.  */
225852558Sobrienconst char *
225952558Sobrientrim_filename (name)
226052558Sobrien     const char *name;
226118334Speter{
226252558Sobrien  static const char *this_file = __FILE__;
226352558Sobrien  const char *p = name, *q = this_file;
226418334Speter
226552558Sobrien  while (*p == *q && *p != 0 && *q != 0) p++, q++;
226652558Sobrien  while (p > name && p[-1] != DIR_SEPARATOR
226752558Sobrien#ifdef DIR_SEPARATOR_2
226852558Sobrien	 && p[-1] != DIR_SEPARATOR_2
226918334Speter#endif
227052558Sobrien	 )
227152558Sobrien    p--;
227218334Speter
227352558Sobrien  return p;
227452558Sobrien}
227518334Speter
227618334Speter/* More 'friendly' abort that prints the line and file.
227718334Speter   config.h can #define abort fancy_abort if you like that sort of thing.
227818334Speter
227918334Speter   I don't think this is actually a good idea.
228018334Speter   Other sorts of crashes will look a certain way.
228118334Speter   It is a good thing if crashes from calling abort look the same way.
228218334Speter     -- RMS  */
228318334Speter
228418334Spetervoid
228518334Speterfancy_abort ()
228618334Speter{
228718334Speter  fatal ("internal gcc abort");
228818334Speter}
228918334Speter
229018334Speter/* This calls abort and is used to avoid problems when abort if a macro.
229118334Speter   It is used when we need to pass the address of abort.  */
229218334Speter
229318334Spetervoid
229418334Speterdo_abort ()
229518334Speter{
229618334Speter  abort ();
229718334Speter}
229818334Speter
229918334Speter/* When `malloc.c' is compiled with `rcheck' defined,
230018334Speter   it calls this function to report clobberage.  */
230118334Speter
230218334Spetervoid
230318334Speterbotch (s)
230452558Sobrien  const char * s ATTRIBUTE_UNUSED;
230518334Speter{
230618334Speter  abort ();
230718334Speter}
230818334Speter
230918334Speter/* Same as `malloc' but report error if no memory available.  */
231018334Speter
231152558SobrienPTR
231218334Speterxmalloc (size)
231352558Sobrien  size_t size;
231418334Speter{
231552558Sobrien  register PTR value;
231650615Sobrien
231750615Sobrien  if (size == 0)
231850615Sobrien    size = 1;
231950615Sobrien
232052558Sobrien  value = (PTR) malloc (size);
232118334Speter  if (value == 0)
232218334Speter    fatal ("virtual memory exhausted");
232318334Speter  return value;
232418334Speter}
232518334Speter
232650615Sobrien/* Same as `calloc' but report error if no memory available.  */
232718334Speter
232852558SobrienPTR
232950615Sobrienxcalloc (size1, size2)
233052558Sobrien  size_t size1, size2;
233150615Sobrien{
233252558Sobrien  register PTR value;
233350615Sobrien
233450615Sobrien  if (size1 == 0 || size2 == 0)
233550615Sobrien    size1 = size2 = 1;
233650615Sobrien
233752558Sobrien  value = (PTR) calloc (size1, size2);
233850615Sobrien  if (value == 0)
233950615Sobrien    fatal ("virtual memory exhausted");
234050615Sobrien  return value;
234150615Sobrien}
234250615Sobrien
234350615Sobrien
234450615Sobrien/* Same as `realloc' but report error if no memory available.
234550615Sobrien   Also handle null PTR even if the vendor realloc gets it wrong.  */
234650615Sobrien
234752558SobrienPTR
234818334Speterxrealloc (ptr, size)
234952558Sobrien  PTR ptr;
235052558Sobrien  size_t size;
235118334Speter{
235252558Sobrien  register PTR result;
235350615Sobrien
235450615Sobrien  if (size == 0)
235550615Sobrien    size = 1;
235650615Sobrien
235752558Sobrien  result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
235850615Sobrien
235918334Speter  if (!result)
236018334Speter    fatal ("virtual memory exhausted");
236150615Sobrien
236218334Speter  return result;
236318334Speter}
236450615Sobrien
236550615Sobrien/* Same as `strdup' but report error if no memory available.  */
236650615Sobrien
236750615Sobrienchar *
236850615Sobrienxstrdup (s)
236952558Sobrien  register const char *s;
237050615Sobrien{
237150615Sobrien  register char *result = (char *) malloc (strlen (s) + 1);
237250615Sobrien
237350615Sobrien  if (! result)
237450615Sobrien    fatal ("virtual memory exhausted");
237550615Sobrien  strcpy (result, s);
237650615Sobrien  return result;
237750615Sobrien}
237818334Speter
237918334Speter/* Return the logarithm of X, base 2, considering X unsigned,
238018334Speter   if X is a power of 2.  Otherwise, returns -1.
238118334Speter
238218334Speter   This should be used via the `exact_log2' macro.  */
238318334Speter
238418334Speterint
238518334Speterexact_log2_wide (x)
238618334Speter     register unsigned HOST_WIDE_INT x;
238718334Speter{
238818334Speter  register int log = 0;
238918334Speter  /* Test for 0 or a power of 2.  */
239018334Speter  if (x == 0 || x != (x & -x))
239118334Speter    return -1;
239218334Speter  while ((x >>= 1) != 0)
239318334Speter    log++;
239418334Speter  return log;
239518334Speter}
239618334Speter
239718334Speter/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
239818334Speter   If X is 0, return -1.
239918334Speter
240018334Speter   This should be used via the floor_log2 macro.  */
240118334Speter
240218334Speterint
240318334Speterfloor_log2_wide (x)
240418334Speter     register unsigned HOST_WIDE_INT x;
240518334Speter{
240618334Speter  register int log = -1;
240718334Speter  while (x != 0)
240818334Speter    log++,
240918334Speter    x >>= 1;
241018334Speter  return log;
241118334Speter}
241218334Speter
241350615Sobrienstatic int float_handler_set;
241418334Speterint float_handled;
241518334Speterjmp_buf float_handler;
241618334Speter
241750615Sobrien/* Signals actually come here.  */
241850615Sobrien
241950615Sobrienstatic void
242050615Sobrienfloat_signal (signo)
242150615Sobrien     /* If this is missing, some compilers complain.  */
242250615Sobrien     int signo ATTRIBUTE_UNUSED;
242350615Sobrien{
242450615Sobrien  if (float_handled == 0)
242550615Sobrien    abort ();
242650615Sobrien#if defined (USG) || defined (hpux)
242750615Sobrien  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
242850615Sobrien#endif
242950615Sobrien  float_handled = 0;
243050615Sobrien  signal (SIGFPE, float_signal);
243150615Sobrien  longjmp (float_handler, 1);
243250615Sobrien}
243350615Sobrien
243418334Speter/* Specify where to longjmp to when a floating arithmetic error happens.
243518334Speter   If HANDLER is 0, it means don't handle the errors any more.  */
243618334Speter
243718334Spetervoid
243818334Speterset_float_handler (handler)
243918334Speter     jmp_buf handler;
244018334Speter{
244118334Speter  float_handled = (handler != 0);
244218334Speter  if (handler)
244318334Speter    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
244450615Sobrien
244550615Sobrien  if (float_handled && ! float_handler_set)
244650615Sobrien    {
244750615Sobrien      signal (SIGFPE, float_signal);
244850615Sobrien      float_handler_set = 1;
244950615Sobrien    }
245018334Speter}
245118334Speter
245252558Sobrien/* This is a wrapper function for code which might elicit an
245352558Sobrien   arithmetic exception.  That code should be passed in as a function
245452558Sobrien   pointer FN, and one argument DATA.  DATA is usually a struct which
245552558Sobrien   contains the real input and output for function FN.  This function
245652558Sobrien   returns 0 (failure) if longjmp was called (i.e. an exception
245752558Sobrien   occured.)  It returns 1 (success) otherwise. */
245852558Sobrien
245952558Sobrienint
246052558Sobriendo_float_handler (fn, data)
246152558Sobrien  void (*fn) PROTO ((PTR));
246252558Sobrien  PTR data;
246352558Sobrien{
246452558Sobrien  jmp_buf buf;
246552558Sobrien
246652558Sobrien  if (setjmp (buf))
246752558Sobrien    {
246852558Sobrien      /* We got here via longjmp() caused by an exception in function fn() */
246952558Sobrien      set_float_handler (NULL);
247052558Sobrien      return 0;
247152558Sobrien    }
247252558Sobrien
247352558Sobrien  set_float_handler (buf);
247452558Sobrien  (*fn)(data);
247552558Sobrien  set_float_handler (NULL);
247652558Sobrien  return 1;
247752558Sobrien}
247852558Sobrien
247918334Speter/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
248018334Speter   error happens, pushing the previous specification into OLD_HANDLER.
248118334Speter   Return an indication of whether there was a previous handler in effect.  */
248218334Speter
248318334Speterint
248418334Speterpush_float_handler (handler, old_handler)
248518334Speter     jmp_buf handler, old_handler;
248618334Speter{
248718334Speter  int was_handled = float_handled;
248818334Speter
248918334Speter  float_handled = 1;
249018334Speter  if (was_handled)
249152558Sobrien    memcpy ((char *) old_handler, (char *) float_handler,
249218334Speter	   sizeof (float_handler));
249318334Speter
249452558Sobrien  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
249518334Speter  return was_handled;
249618334Speter}
249718334Speter
249818334Speter/* Restore the previous specification of whether and where to longjmp to
249918334Speter   when a floating arithmetic error happens.  */
250018334Speter
250118334Spetervoid
250218334Speterpop_float_handler (handled, handler)
250318334Speter     int handled;
250418334Speter     jmp_buf handler;
250518334Speter{
250618334Speter  float_handled = handled;
250718334Speter  if (handled)
250818334Speter    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
250918334Speter}
251018334Speter
251118334Speter/* Handler for SIGPIPE.  */
251218334Speter
251318334Speterstatic void
251418334Speterpipe_closed (signo)
251518334Speter     /* If this is missing, some compilers complain.  */
251650615Sobrien     int signo ATTRIBUTE_UNUSED;
251718334Speter{
251818334Speter  fatal ("output pipe has been closed");
251918334Speter}
252018334Speter
252118334Speter/* Strip off a legitimate source ending from the input string NAME of
252218334Speter   length LEN.  Rather than having to know the names used by all of
252350615Sobrien   our front ends, we strip off an ending of a period followed by
252450615Sobrien   up to five characters.  (Java uses ".class".) */
252518334Speter
252618334Spetervoid
252718334Speterstrip_off_ending (name, len)
252818334Speter     char *name;
252918334Speter     int len;
253018334Speter{
253150615Sobrien  int i;
253250615Sobrien  for (i = 2;  i < 6 && len > i;  i++)
253350615Sobrien    {
253450615Sobrien      if (name[len - i] == '.')
253550615Sobrien	{
253650615Sobrien	  name[len - i] = '\0';
253750615Sobrien	  break;
253850615Sobrien	}
253950615Sobrien    }
254018334Speter}
254118334Speter
254218334Speter/* Output a quoted string.  */
254350615Sobrien
254418334Spetervoid
254518334Speteroutput_quoted_string (asm_file, string)
254618334Speter     FILE *asm_file;
254752558Sobrien     const char *string;
254818334Speter{
254950615Sobrien#ifdef OUTPUT_QUOTED_STRING
255050615Sobrien  OUTPUT_QUOTED_STRING (asm_file, string);
255150615Sobrien#else
255218334Speter  char c;
255318334Speter
255418334Speter  putc ('\"', asm_file);
255518334Speter  while ((c = *string++) != 0)
255618334Speter    {
255718334Speter      if (c == '\"' || c == '\\')
255818334Speter	putc ('\\', asm_file);
255918334Speter      putc (c, asm_file);
256018334Speter    }
256118334Speter  putc ('\"', asm_file);
256250615Sobrien#endif
256318334Speter}
256418334Speter
256518334Speter/* Output a file name in the form wanted by System V.  */
256618334Speter
256718334Spetervoid
256818334Speteroutput_file_directive (asm_file, input_name)
256918334Speter     FILE *asm_file;
257052558Sobrien     const char *input_name;
257118334Speter{
257218334Speter  int len = strlen (input_name);
257352558Sobrien  const char *na = input_name + len;
257418334Speter
257518334Speter  /* NA gets INPUT_NAME sans directory names.  */
257618334Speter  while (na > input_name)
257718334Speter    {
257818334Speter      if (na[-1] == '/')
257918334Speter	break;
258052558Sobrien#ifdef DIR_SEPARATOR
258152558Sobrien      if (na[-1] == DIR_SEPARATOR)
258252558Sobrien	break;
258352558Sobrien#endif
258418334Speter      na--;
258518334Speter    }
258618334Speter
258718334Speter#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
258818334Speter  ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
258918334Speter#else
259018334Speter#ifdef ASM_OUTPUT_SOURCE_FILENAME
259118334Speter  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
259218334Speter#else
259318334Speter  fprintf (asm_file, "\t.file\t");
259418334Speter  output_quoted_string (asm_file, na);
259518334Speter  fputc ('\n', asm_file);
259618334Speter#endif
259718334Speter#endif
259818334Speter}
259918334Speter
260052558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE
260150615Sobrien/* Routine to build language identifier for object file.  */
260218334Speterstatic void
260318334Speteroutput_lang_identify (asm_out_file)
260418334Speter     FILE *asm_out_file;
260518334Speter{
260618334Speter  int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
260718334Speter  char *s = (char *) alloca (len);
260818334Speter  sprintf (s, "__gnu_compiled_%s", lang_identify ());
260918334Speter  ASM_OUTPUT_LABEL (asm_out_file, s);
261018334Speter}
261152558Sobrien#endif
261218334Speter
261318334Speter/* Routine to open a dump file.  */
261450615Sobrienstatic void
261550615Sobrienopen_dump_file (suffix, function_name)
261652558Sobrien     const char *suffix;
261752558Sobrien     const char *function_name;
261818334Speter{
261950615Sobrien  char *dumpname;
262018334Speter
262150615Sobrien  TIMEVAR
262250615Sobrien    (dump_time,
262350615Sobrien     {
262450615Sobrien       dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
262550615Sobrien
262650615Sobrien       if (rtl_dump_file != NULL)
262750615Sobrien	 fclose (rtl_dump_file);
262850615Sobrien
262950615Sobrien       strcpy (dumpname, dump_base_name);
263050615Sobrien       strcat (dumpname, suffix);
263150615Sobrien
263250615Sobrien       rtl_dump_file = fopen (dumpname, "a");
263350615Sobrien
263450615Sobrien       if (rtl_dump_file == NULL)
263550615Sobrien	 pfatal_with_name (dumpname);
263650615Sobrien
263750615Sobrien       free (dumpname);
263850615Sobrien
263950615Sobrien       if (function_name)
264050615Sobrien	 fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
264150615Sobrien     });
264250615Sobrien
264350615Sobrien  return;
264450615Sobrien}
264550615Sobrien
264650615Sobrien/* Routine to close a dump file.  */
264750615Sobrienstatic void
264850615Sobrienclose_dump_file (func, insns)
264950615Sobrien     void (*func) PROTO ((FILE *, rtx));
265050615Sobrien     rtx    insns;
265150615Sobrien{
265250615Sobrien  TIMEVAR
265350615Sobrien    (dump_time,
265450615Sobrien     {
265550615Sobrien       if (func)
265650615Sobrien	 func (rtl_dump_file, insns);
265750615Sobrien
265850615Sobrien       fflush (rtl_dump_file);
265950615Sobrien       fclose (rtl_dump_file);
266050615Sobrien
266150615Sobrien       rtl_dump_file = NULL;
266250615Sobrien     });
266350615Sobrien
266450615Sobrien  return;
266550615Sobrien}
266650615Sobrien
266750615Sobrien/* Routine to dump rtl into a file.  */
266850615Sobrienstatic void
266950615Sobriendump_rtl (suffix, decl, func, insns)
267052558Sobrien     const char *suffix;
267150615Sobrien     tree   decl;
267250615Sobrien     void (*func) PROTO ((FILE *, rtx));
267350615Sobrien     rtx    insns;
267450615Sobrien{
267550615Sobrien  open_dump_file (suffix, decl_printable_name (decl, 2));
267650615Sobrien  close_dump_file (func, insns);
267750615Sobrien}
267850615Sobrien
267950615Sobrien/* Routine to empty a dump file.  */
268050615Sobrienstatic void
268150615Sobrienclean_dump_file (suffix)
268252558Sobrien  const char *suffix;
268350615Sobrien{
268452558Sobrien  char *dumpname;
268550615Sobrien
268650615Sobrien  dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
268750615Sobrien
268850615Sobrien  strcpy (dumpname, dump_base_name);
268918334Speter  strcat (dumpname, suffix);
269050615Sobrien
269150615Sobrien  rtl_dump_file = fopen (dumpname, "w");
269250615Sobrien
269350615Sobrien  if (rtl_dump_file == NULL)
269450615Sobrien    pfatal_with_name (dumpname);
269550615Sobrien
269650615Sobrien  free (dumpname);
269750615Sobrien
269850615Sobrien  fclose (rtl_dump_file);
269950615Sobrien  rtl_dump_file = NULL;
270050615Sobrien
270150615Sobrien  return;
270218334Speter}
270318334Speter
270452558Sobrien/* Do any final processing required for the declarations in VEC, of
270552558Sobrien   which there are LEN.  We write out inline functions and variables
270652558Sobrien   that have been deferred until this point, but which are required.
270752558Sobrien   Returns non-zero if anything was put out.  */
270852558Sobrienint
270952558Sobrienwrapup_global_declarations (vec, len)
271052558Sobrien     tree *vec;
271152558Sobrien     int len;
271252558Sobrien{
271352558Sobrien  tree decl;
271452558Sobrien  int i;
271552558Sobrien  int reconsider;
271652558Sobrien  int output_something = 0;
271750615Sobrien
271852558Sobrien  for (i = 0; i < len; i++)
271952558Sobrien    {
272052558Sobrien      decl = vec[i];
272152558Sobrien
272252558Sobrien      /* We're not deferring this any longer.  */
272352558Sobrien      DECL_DEFER_OUTPUT (decl) = 0;
272452558Sobrien
272552558Sobrien      if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
272652558Sobrien	  && incomplete_decl_finalize_hook != 0)
272752558Sobrien	(*incomplete_decl_finalize_hook) (decl);
272852558Sobrien    }
272952558Sobrien
273052558Sobrien  /* Now emit any global variables or functions that we have been
273152558Sobrien     putting off.  We need to loop in case one of the things emitted
273252558Sobrien     here references another one which comes earlier in the list.  */
273352558Sobrien  do
273452558Sobrien    {
273552558Sobrien      reconsider = 0;
273652558Sobrien      for (i = 0; i < len; i++)
273752558Sobrien	{
273852558Sobrien	  decl = vec[i];
273952558Sobrien
274052558Sobrien	  if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
274152558Sobrien	    continue;
274252558Sobrien
274352558Sobrien	  /* Don't write out static consts, unless we still need them.
274452558Sobrien
274552558Sobrien	     We also keep static consts if not optimizing (for debugging),
274652558Sobrien	     unless the user specified -fno-keep-static-consts.
274752558Sobrien	     ??? They might be better written into the debug information.
274852558Sobrien	     This is possible when using DWARF.
274952558Sobrien
275052558Sobrien	     A language processor that wants static constants to be always
275152558Sobrien	     written out (even if it is not used) is responsible for
275252558Sobrien	     calling rest_of_decl_compilation itself.  E.g. the C front-end
275352558Sobrien	     calls rest_of_decl_compilation from finish_decl.
275452558Sobrien	     One motivation for this is that is conventional in some
275552558Sobrien	     environments to write things like:
275652558Sobrien	     static const char rcsid[] = "... version string ...";
275752558Sobrien	     intending to force the string to be in the executable.
275852558Sobrien
275952558Sobrien	     A language processor that would prefer to have unneeded
276052558Sobrien	     static constants "optimized away" would just defer writing
276152558Sobrien	     them out until here.  E.g. C++ does this, because static
276252558Sobrien	     constants are often defined in header files.
276352558Sobrien
276452558Sobrien	     ??? A tempting alternative (for both C and C++) would be
276552558Sobrien	     to force a constant to be written if and only if it is
276652558Sobrien	     defined in a main file, as opposed to an include file.  */
276752558Sobrien
276852558Sobrien	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
276952558Sobrien	      && (! TREE_READONLY (decl)
277052558Sobrien		  || TREE_PUBLIC (decl)
277152558Sobrien		  || (!optimize && flag_keep_static_consts)
277252558Sobrien		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
277352558Sobrien	    {
277452558Sobrien	      reconsider = 1;
277552558Sobrien	      rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
277652558Sobrien	    }
277752558Sobrien
277852558Sobrien	  if (TREE_CODE (decl) == FUNCTION_DECL
277952558Sobrien	      && DECL_INITIAL (decl) != 0
278052558Sobrien	      && DECL_SAVED_INSNS (decl) != 0
278152558Sobrien	      && (flag_keep_inline_functions
278252558Sobrien		  || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
278352558Sobrien		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
278452558Sobrien	    {
278552558Sobrien	      reconsider = 1;
278652558Sobrien	      temporary_allocation ();
278752558Sobrien	      output_inline_function (decl);
278852558Sobrien	      permanent_allocation (1);
278952558Sobrien	    }
279052558Sobrien	}
279152558Sobrien
279252558Sobrien      if (reconsider)
279352558Sobrien	output_something = 1;
279452558Sobrien    }
279552558Sobrien  while (reconsider);
279652558Sobrien
279752558Sobrien  return output_something;
279852558Sobrien}
279952558Sobrien
280052558Sobrien/* Issue appropriate warnings for the global declarations in VEC (of
280152558Sobrien   which there are LEN).  Output debugging information for them.  */
280252558Sobrienvoid
280352558Sobriencheck_global_declarations (vec, len)
280452558Sobrien     tree *vec;
280552558Sobrien     int len;
280652558Sobrien{
280752558Sobrien  tree decl;
280852558Sobrien  int i;
280952558Sobrien
281052558Sobrien  for (i = 0; i < len; i++)
281152558Sobrien    {
281252558Sobrien      decl = vec[i];
281352558Sobrien
281452558Sobrien      if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
281552558Sobrien	  && ! TREE_ASM_WRITTEN (decl))
281652558Sobrien	/* Cancel the RTL for this decl so that, if debugging info
281752558Sobrien	   output for global variables is still to come,
281852558Sobrien	   this one will be omitted.  */
281952558Sobrien	DECL_RTL (decl) = NULL;
282052558Sobrien
282152558Sobrien      /* Warn about any function
282252558Sobrien	 declared static but not defined.
282352558Sobrien	 We don't warn about variables,
282452558Sobrien	 because many programs have static variables
282552558Sobrien	 that exist only to get some text into the object file.  */
282652558Sobrien      if (TREE_CODE (decl) == FUNCTION_DECL
282752558Sobrien	  && (warn_unused
282852558Sobrien	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
282952558Sobrien	  && DECL_INITIAL (decl) == 0
283052558Sobrien	  && DECL_EXTERNAL (decl)
283152558Sobrien	  && ! DECL_ARTIFICIAL (decl)
283252558Sobrien	  && ! TREE_PUBLIC (decl))
283352558Sobrien	{
283452558Sobrien	  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
283552558Sobrien	    pedwarn_with_decl (decl,
283652558Sobrien			       "`%s' used but never defined");
283752558Sobrien	  else
283852558Sobrien	    warning_with_decl (decl,
283952558Sobrien			       "`%s' declared `static' but never defined");
284052558Sobrien	  /* This symbol is effectively an "extern" declaration now.  */
284152558Sobrien	  TREE_PUBLIC (decl) = 1;
284252558Sobrien	  assemble_external (decl);
284352558Sobrien	}
284452558Sobrien
284552558Sobrien      /* Warn about static fns or vars defined but not used,
284652558Sobrien	 but not about inline functions or static consts
284752558Sobrien	 since defining those in header files is normal practice.  */
284852558Sobrien      if (warn_unused
284952558Sobrien	  && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
285052558Sobrien	      || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
285152558Sobrien	  && ! DECL_IN_SYSTEM_HEADER (decl)
285252558Sobrien	  && ! DECL_EXTERNAL (decl)
285352558Sobrien	  && ! TREE_PUBLIC (decl)
285452558Sobrien	  && ! TREE_USED (decl)
285552558Sobrien	  && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl))
285652558Sobrien	  /* The TREE_USED bit for file-scope decls
285752558Sobrien	     is kept in the identifier, to handle multiple
285852558Sobrien	     external decls in different scopes.  */
285952558Sobrien	  && ! TREE_USED (DECL_NAME (decl)))
286052558Sobrien	warning_with_decl (decl, "`%s' defined but not used");
286152558Sobrien
286252558Sobrien#ifdef SDB_DEBUGGING_INFO
286352558Sobrien      /* The COFF linker can move initialized global vars to the end.
286452558Sobrien	 And that can screw up the symbol ordering.
286552558Sobrien	 By putting the symbols in that order to begin with,
286652558Sobrien	 we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
286752558Sobrien      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
286852558Sobrien	  && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
286952558Sobrien	  && ! DECL_EXTERNAL (decl)
287052558Sobrien	  && DECL_RTL (decl) != 0)
287152558Sobrien	TIMEVAR (symout_time, sdbout_symbol (decl, 0));
287252558Sobrien
287352558Sobrien      /* Output COFF information for non-global
287452558Sobrien	 file-scope initialized variables.  */
287552558Sobrien      if (write_symbols == SDB_DEBUG
287652558Sobrien	  && TREE_CODE (decl) == VAR_DECL
287752558Sobrien	  && DECL_INITIAL (decl)
287852558Sobrien	  && ! DECL_EXTERNAL (decl)
287952558Sobrien	  && DECL_RTL (decl) != 0
288052558Sobrien	  && GET_CODE (DECL_RTL (decl)) == MEM)
288152558Sobrien	TIMEVAR (symout_time, sdbout_toplevel_data (decl));
288252558Sobrien#endif /* SDB_DEBUGGING_INFO */
288352558Sobrien#ifdef DWARF_DEBUGGING_INFO
288452558Sobrien      /* Output DWARF information for file-scope tentative data object
288552558Sobrien	 declarations, file-scope (extern) function declarations (which
288652558Sobrien	 had no corresponding body) and file-scope tagged type declarations
288752558Sobrien	 and definitions which have not yet been forced out.  */
288852558Sobrien
288952558Sobrien      if (write_symbols == DWARF_DEBUG
289052558Sobrien	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
289152558Sobrien	TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
289252558Sobrien#endif
289352558Sobrien#ifdef DWARF2_DEBUGGING_INFO
289452558Sobrien      /* Output DWARF2 information for file-scope tentative data object
289552558Sobrien	 declarations, file-scope (extern) function declarations (which
289652558Sobrien	 had no corresponding body) and file-scope tagged type declarations
289752558Sobrien	 and definitions which have not yet been forced out.  */
289852558Sobrien
289952558Sobrien      if (write_symbols == DWARF2_DEBUG
290052558Sobrien	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
290152558Sobrien	TIMEVAR (symout_time, dwarf2out_decl (decl));
290252558Sobrien#endif
290352558Sobrien    }
290452558Sobrien}
290552558Sobrien
290618334Speter/* Compile an entire file of output from cpp, named NAME.
290718334Speter   Write a file of assembly output and various debugging dumps.  */
290818334Speter
290918334Speterstatic void
291018334Spetercompile_file (name)
291118334Speter     char *name;
291218334Speter{
291318334Speter  tree globals;
291418334Speter  int start_time;
291518334Speter
291618334Speter  int name_specified = name != 0;
291718334Speter
291818334Speter  if (dump_base_name == 0)
291918334Speter    dump_base_name = name ? name : "gccdump";
292018334Speter
292118334Speter  parse_time = 0;
292218334Speter  varconst_time = 0;
292318334Speter  integration_time = 0;
292418334Speter  jump_time = 0;
292518334Speter  cse_time = 0;
292650615Sobrien  gcse_time = 0;
292718334Speter  loop_time = 0;
292818334Speter  cse2_time = 0;
292950615Sobrien  branch_prob_time = 0;
293018334Speter  flow_time = 0;
293118334Speter  combine_time = 0;
293250615Sobrien  regmove_time = 0;
293318334Speter  sched_time = 0;
293418334Speter  local_alloc_time = 0;
293518334Speter  global_alloc_time = 0;
293652558Sobrien  flow2_time = 0;
293718334Speter  sched2_time = 0;
293850615Sobrien#ifdef DELAY_SLOTS
293918334Speter  dbr_sched_time = 0;
294050615Sobrien#endif
294118334Speter  shorten_branch_time = 0;
294218334Speter  stack_reg_time = 0;
294318334Speter  final_time = 0;
294418334Speter  symout_time = 0;
294518334Speter  dump_time = 0;
294618334Speter
294718334Speter  /* Initialize data in various passes.  */
294818334Speter
294918334Speter  init_obstacks ();
295018334Speter  init_tree_codes ();
295150615Sobrien  name = init_parse (name);
295218334Speter  init_rtl ();
295318334Speter  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
295450615Sobrien		  || debug_info_level == DINFO_LEVEL_VERBOSE
295550615Sobrien		  || flag_test_coverage);
295618334Speter  init_regs ();
295718334Speter  init_decl_processing ();
295818334Speter  init_optabs ();
295918334Speter  init_stmt ();
296018334Speter  init_expmed ();
296118334Speter  init_expr_once ();
296218334Speter  init_loop ();
296318334Speter  init_reload ();
296450615Sobrien  init_alias_once ();
296518334Speter
296618334Speter  if (flag_caller_saves)
296718334Speter    init_caller_save ();
296818334Speter
296918334Speter  /* If auxiliary info generation is desired, open the output file.
297018334Speter     This goes in the same directory as the source file--unlike
297118334Speter     all the other output files.  */
297218334Speter  if (flag_gen_aux_info)
297318334Speter    {
297418334Speter      aux_info_file = fopen (aux_info_file_name, "w");
297518334Speter      if (aux_info_file == 0)
297618334Speter	pfatal_with_name (aux_info_file_name);
297718334Speter    }
297818334Speter
297952558Sobrien  /* Clear the dump files.  */
298018334Speter  if (rtl_dump)
298150615Sobrien    clean_dump_file (".rtl");
298218334Speter  if (jump_opt_dump)
298352558Sobrien    {
298452558Sobrien      clean_dump_file (".jump");
298552558Sobrien      if (graph_dump_format != no_graph)
298652558Sobrien	clean_graph_dump_file (dump_base_name, ".jump");
298752558Sobrien    }
298850615Sobrien  if (addressof_dump)
298952558Sobrien    {
299052558Sobrien      clean_dump_file (".addressof");
299152558Sobrien      if (graph_dump_format != no_graph)
299252558Sobrien	clean_graph_dump_file (dump_base_name, ".addressof");
299352558Sobrien    }
299418334Speter  if (cse_dump)
299552558Sobrien    {
299652558Sobrien      clean_dump_file (".cse");
299752558Sobrien      if (graph_dump_format != no_graph)
299852558Sobrien	clean_graph_dump_file (dump_base_name, ".cse");
299952558Sobrien    }
300018334Speter  if (loop_dump)
300152558Sobrien    {
300252558Sobrien      clean_dump_file (".loop");
300352558Sobrien      if (graph_dump_format != no_graph)
300452558Sobrien	clean_graph_dump_file (dump_base_name, ".loop");
300552558Sobrien    }
300618334Speter  if (cse2_dump)
300752558Sobrien    {
300852558Sobrien      clean_dump_file (".cse2");
300952558Sobrien      if (graph_dump_format != no_graph)
301052558Sobrien	clean_graph_dump_file (dump_base_name, ".cse2");
301152558Sobrien    }
301250615Sobrien  if (branch_prob_dump)
301352558Sobrien    {
301452558Sobrien      clean_dump_file (".bp");
301552558Sobrien      if (graph_dump_format != no_graph)
301652558Sobrien	clean_graph_dump_file (dump_base_name, ".bp");
301752558Sobrien    }
301818334Speter  if (flow_dump)
301952558Sobrien    {
302052558Sobrien      clean_dump_file (".flow");
302152558Sobrien      if (graph_dump_format != no_graph)
302252558Sobrien	clean_graph_dump_file (dump_base_name, ".flow");
302352558Sobrien    }
302418334Speter  if (combine_dump)
302552558Sobrien    {
302652558Sobrien      clean_dump_file (".combine");
302752558Sobrien      if (graph_dump_format != no_graph)
302852558Sobrien	clean_graph_dump_file (dump_base_name, ".combine");
302952558Sobrien    }
303050615Sobrien  if (regmove_dump)
303152558Sobrien    {
303252558Sobrien      clean_dump_file (".regmove");
303352558Sobrien      if (graph_dump_format != no_graph)
303452558Sobrien	clean_graph_dump_file (dump_base_name, ".regmove");
303552558Sobrien    }
303618334Speter  if (sched_dump)
303752558Sobrien    {
303852558Sobrien      clean_dump_file (".sched");
303952558Sobrien      if (graph_dump_format != no_graph)
304052558Sobrien	clean_graph_dump_file (dump_base_name, ".sched");
304152558Sobrien    }
304218334Speter  if (local_reg_dump)
304352558Sobrien    {
304452558Sobrien      clean_dump_file (".lreg");
304552558Sobrien      if (graph_dump_format != no_graph)
304652558Sobrien	clean_graph_dump_file (dump_base_name, ".lreg");
304752558Sobrien    }
304818334Speter  if (global_reg_dump)
304952558Sobrien    {
305052558Sobrien      clean_dump_file (".greg");
305152558Sobrien      if (graph_dump_format != no_graph)
305252558Sobrien	clean_graph_dump_file (dump_base_name, ".greg");
305352558Sobrien    }
305452558Sobrien  if (flow2_dump)
305552558Sobrien    {
305652558Sobrien      clean_dump_file (".flow2");
305752558Sobrien      if (graph_dump_format != no_graph)
305852558Sobrien	clean_graph_dump_file (dump_base_name, ".flow2");
305952558Sobrien    }
306018334Speter  if (sched2_dump)
306152558Sobrien    {
306252558Sobrien      clean_dump_file (".sched2");
306352558Sobrien      if (graph_dump_format != no_graph)
306452558Sobrien	clean_graph_dump_file (dump_base_name, ".sched2");
306552558Sobrien    }
306618334Speter  if (jump2_opt_dump)
306752558Sobrien    {
306852558Sobrien      clean_dump_file (".jump2");
306952558Sobrien      if (graph_dump_format != no_graph)
307052558Sobrien	clean_graph_dump_file (dump_base_name, ".jump2");
307152558Sobrien    }
307250615Sobrien#ifdef DELAY_SLOTS
307318334Speter  if (dbr_sched_dump)
307452558Sobrien    {
307552558Sobrien      clean_dump_file (".dbr");
307652558Sobrien      if (graph_dump_format != no_graph)
307752558Sobrien	clean_graph_dump_file (dump_base_name, ".dbr");
307852558Sobrien    }
307950615Sobrien#endif
308050615Sobrien  if (gcse_dump)
308152558Sobrien    {
308252558Sobrien      clean_dump_file (".gcse");
308352558Sobrien      if (graph_dump_format != no_graph)
308452558Sobrien	clean_graph_dump_file (dump_base_name, ".gcse");
308552558Sobrien    }
308618334Speter#ifdef STACK_REGS
308718334Speter  if (stack_reg_dump)
308852558Sobrien    {
308952558Sobrien      clean_dump_file (".stack");
309052558Sobrien      if (graph_dump_format != no_graph)
309152558Sobrien	clean_graph_dump_file (dump_base_name, ".stack");
309252558Sobrien    }
309318334Speter#endif
309450615Sobrien#ifdef MACHINE_DEPENDENT_REORG
309550615Sobrien  if (mach_dep_reorg_dump)
309652558Sobrien    {
309752558Sobrien      clean_dump_file (".mach");
309852558Sobrien      if (graph_dump_format != no_graph)
309952558Sobrien	clean_graph_dump_file (dump_base_name, ".mach");
310052558Sobrien    }
310150615Sobrien#endif
310218334Speter
310318334Speter  /* Open assembler code output file.  */
310418334Speter
310552558Sobrien  if (flag_syntax_only)
310652558Sobrien    asm_out_file = NULL;
310718334Speter  else
310818334Speter    {
310952558Sobrien      if (! name_specified && asm_file_name == 0)
311052558Sobrien	asm_out_file = stdout;
311152558Sobrien      else
311218334Speter	{
311352558Sobrien	  int len = strlen (dump_base_name);
311452558Sobrien	  register char *dumpname = (char *) xmalloc (len + 6);
311552558Sobrien	  strcpy (dumpname, dump_base_name);
311652558Sobrien	  strip_off_ending (dumpname, len);
311752558Sobrien	  strcat (dumpname, ".s");
311852558Sobrien	  if (asm_file_name == 0)
311952558Sobrien	    {
312052558Sobrien	      asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
312152558Sobrien	      strcpy (asm_file_name, dumpname);
312252558Sobrien	    }
312352558Sobrien	  if (!strcmp (asm_file_name, "-"))
312452558Sobrien	    asm_out_file = stdout;
312552558Sobrien	  else
312652558Sobrien	    asm_out_file = fopen (asm_file_name, "w");
312752558Sobrien	  if (asm_out_file == 0)
312852558Sobrien	    pfatal_with_name (asm_file_name);
312918334Speter	}
313018334Speter
313118334Speter#ifdef IO_BUFFER_SIZE
313252558Sobrien      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
313352558Sobrien	       _IOFBF, IO_BUFFER_SIZE);
313418334Speter#endif
313552558Sobrien    }
313618334Speter
313718334Speter  input_filename = name;
313818334Speter
313918334Speter  /* Put an entry on the input file stack for the main input file.  */
314018334Speter  input_file_stack
314118334Speter    = (struct file_stack *) xmalloc (sizeof (struct file_stack));
314218334Speter  input_file_stack->next = 0;
314318334Speter  input_file_stack->name = input_filename;
314418334Speter
314518334Speter  /* Perform language-specific initialization.
314618334Speter     This may set main_input_filename.  */
314718334Speter  lang_init ();
314818334Speter
314918334Speter  /* If the input doesn't start with a #line, use the input name
315018334Speter     as the official input file name.  */
315118334Speter  if (main_input_filename == 0)
315218334Speter    main_input_filename = name;
315318334Speter
315452558Sobrien  if (flag_syntax_only)
315552558Sobrien    {
315652558Sobrien      write_symbols = NO_DEBUG;
315752558Sobrien      profile_flag = 0;
315852558Sobrien      profile_block_flag = 0;
315952558Sobrien    }
316052558Sobrien  else
316152558Sobrien    {
316252558Sobrien      ASM_FILE_START (asm_out_file);
316350615Sobrien
316450615Sobrien#ifdef ASM_COMMENT_START
316552558Sobrien      if (flag_verbose_asm)
316652558Sobrien	{
316752558Sobrien	  /* Print the list of options in effect.  */
316852558Sobrien	  print_version (asm_out_file, ASM_COMMENT_START);
316952558Sobrien	  print_switch_values (asm_out_file, 0, MAX_LINE,
317050615Sobrien			       ASM_COMMENT_START, " ", "\n");
317152558Sobrien	  /* Add a blank line here so it appears in assembler output but not
317252558Sobrien	     screen output.  */
317352558Sobrien	  fprintf (asm_out_file, "\n");
317452558Sobrien	}
317550615Sobrien#endif
317618334Speter
317752558Sobrien      /* Output something to inform GDB that this compilation was by GCC.  */
317818334Speter#ifndef ASM_IDENTIFY_GCC
317952558Sobrien      fprintf (asm_out_file, "gcc2_compiled.:\n");
318018334Speter#else
318152558Sobrien      ASM_IDENTIFY_GCC (asm_out_file);
318218334Speter#endif
318318334Speter
318450615Sobrien  /* Output something to identify which front-end produced this file.  */
318518334Speter#ifdef ASM_IDENTIFY_LANGUAGE
318652558Sobrien      ASM_IDENTIFY_LANGUAGE (asm_out_file);
318718334Speter#endif
318852558Sobrien    } /* ! flag_syntax_only */
318918334Speter
319050615Sobrien#ifndef ASM_OUTPUT_SECTION_NAME
319150615Sobrien  if (flag_function_sections)
319218334Speter    {
319350615Sobrien      warning ("-ffunction-sections not supported for this target.");
319450615Sobrien      flag_function_sections = 0;
319518334Speter    }
319652558Sobrien  if (flag_data_sections)
319752558Sobrien    {
319852558Sobrien      warning ("-fdata-sections not supported for this target.");
319952558Sobrien      flag_data_sections = 0;
320052558Sobrien    }
320150615Sobrien#endif
320250615Sobrien
320350615Sobrien  if (flag_function_sections
320450615Sobrien      && (profile_flag || profile_block_flag))
320518334Speter    {
320650615Sobrien      warning ("-ffunction-sections disabled; it makes profiling impossible.");
320750615Sobrien      flag_function_sections = 0;
320850615Sobrien    }
320950615Sobrien
321052558Sobrien#ifndef OBJECT_FORMAT_ELF
321150615Sobrien  if (flag_function_sections && write_symbols != NO_DEBUG)
321250615Sobrien    warning ("-ffunction-sections may affect debugging on some targets.");
321352558Sobrien#endif
321450615Sobrien
321550615Sobrien  /* ??? Note: There used to be a conditional here
321650615Sobrien      to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
321750615Sobrien      This was to guarantee separation between gcc_compiled. and
321850615Sobrien      the first function, for the sake of dbx on Suns.
321950615Sobrien      However, having the extra zero here confused the Emacs
322050615Sobrien      code for unexec, and might confuse other programs too.
322150615Sobrien      Therefore, I took out that change.
322250615Sobrien      In future versions we should find another way to solve
322350615Sobrien      that dbx problem.  -- rms, 23 May 93.  */
322418334Speter
322550615Sobrien  /* Don't let the first function fall at the same address
322650615Sobrien     as gcc_compiled., if profiling.  */
322750615Sobrien  if (profile_flag || profile_block_flag)
322850615Sobrien    {
322950615Sobrien      /* It's best if we can write a nop here since some
323050615Sobrien	 assemblers don't tolerate zeros in the text section.  */
323150615Sobrien      if (insn_template[CODE_FOR_nop] != 0)
323250615Sobrien	output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
323350615Sobrien      else
323418334Speter	assemble_zeros (UNITS_PER_WORD);
323518334Speter    }
323618334Speter
323718334Speter  /* If dbx symbol table desired, initialize writing it
323818334Speter     and output the predefined types.  */
323918334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
324018334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
324118334Speter    TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
324218334Speter				       getdecls ()));
324318334Speter#endif
324418334Speter#ifdef SDB_DEBUGGING_INFO
324518334Speter  if (write_symbols == SDB_DEBUG)
324618334Speter    TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
324718334Speter				       getdecls ()));
324818334Speter#endif
324918334Speter#ifdef DWARF_DEBUGGING_INFO
325018334Speter  if (write_symbols == DWARF_DEBUG)
325118334Speter    TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
325218334Speter#endif
325350615Sobrien#ifdef DWARF2_UNWIND_INFO
325450615Sobrien  if (dwarf2out_do_frame ())
325550615Sobrien    dwarf2out_frame_init ();
325650615Sobrien#endif
325750615Sobrien#ifdef DWARF2_DEBUGGING_INFO
325850615Sobrien  if (write_symbols == DWARF2_DEBUG)
325950615Sobrien    TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
326050615Sobrien#endif
326118334Speter
326218334Speter  /* Initialize yet another pass.  */
326318334Speter
326450615Sobrien  init_final (main_input_filename);
326550615Sobrien  init_branch_prob (dump_base_name);
326618334Speter
326718334Speter  start_time = get_run_time ();
326818334Speter
326918334Speter  /* Call the parser, which parses the entire file
327018334Speter     (calling rest_of_compilation for each function).  */
327118334Speter
327218334Speter  if (yyparse () != 0)
327318334Speter    {
327418334Speter      if (errorcount == 0)
327552558Sobrien	notice ("Errors detected in input file (your bison.simple is out of date)\n");
327618334Speter
327718334Speter      /* In case there were missing closebraces,
327818334Speter	 get us back to the global binding level.  */
327918334Speter      while (! global_bindings_p ())
328018334Speter	poplevel (0, 0, 0);
328118334Speter    }
328218334Speter
328318334Speter  /* Compilation is now finished except for writing
328418334Speter     what's left of the symbol table output.  */
328518334Speter
328618334Speter  parse_time += get_run_time () - start_time;
328718334Speter
328818334Speter  parse_time -= integration_time;
328918334Speter  parse_time -= varconst_time;
329018334Speter
329152558Sobrien  if (flag_syntax_only)
329252558Sobrien    goto finish_syntax;
329352558Sobrien
329418334Speter  globals = getdecls ();
329518334Speter
329618334Speter  /* Really define vars that have had only a tentative definition.
329718334Speter     Really output inline functions that must actually be callable
329818334Speter     and have not been output so far.  */
329918334Speter
330018334Speter  {
330118334Speter    int len = list_length (globals);
330218334Speter    tree *vec = (tree *) alloca (sizeof (tree) * len);
330318334Speter    int i;
330418334Speter    tree decl;
330518334Speter
330618334Speter    /* Process the decls in reverse order--earliest first.
330718334Speter       Put them into VEC from back to front, then take out from front.  */
330818334Speter
330918334Speter    for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
331018334Speter      vec[len - i - 1] = decl;
331118334Speter
331252558Sobrien    wrapup_global_declarations (vec, len);
331318334Speter
331452558Sobrien    /* This must occur after the loop to output deferred functions.  Else
331552558Sobrien       the profiler initializer would not be emitted if all the functions
331652558Sobrien       in this compilation unit were deferred.
331718334Speter
331852558Sobrien       output_func_start_profiler can not cause any additional functions or
331952558Sobrien       data to need to be output, so it need not be in the deferred function
332052558Sobrien       loop above.  */
332152558Sobrien    output_func_start_profiler ();
332218334Speter
332350615Sobrien    /* Now that all possible functions have been output, we can dump
332450615Sobrien       the exception table.  */
332550615Sobrien
332650615Sobrien    output_exception_table ();
332750615Sobrien
332852558Sobrien    check_global_declarations (vec, len);
332918334Speter  }
333018334Speter
333118334Speter  /* Write out any pending weak symbol declarations.  */
333218334Speter
333318334Speter  weak_finish ();
333418334Speter
333518334Speter  /* Do dbx symbols */
333618334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
333718334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
333818334Speter    TIMEVAR (symout_time,
333918334Speter	     {
334018334Speter	       dbxout_finish (asm_out_file, main_input_filename);
334118334Speter	     });
334218334Speter#endif
334318334Speter
334418334Speter#ifdef DWARF_DEBUGGING_INFO
334518334Speter  if (write_symbols == DWARF_DEBUG)
334618334Speter    TIMEVAR (symout_time,
334718334Speter	     {
334818334Speter	       dwarfout_finish ();
334918334Speter	     });
335018334Speter#endif
335118334Speter
335250615Sobrien#ifdef DWARF2_UNWIND_INFO
335350615Sobrien  if (dwarf2out_do_frame ())
335450615Sobrien    dwarf2out_frame_finish ();
335550615Sobrien#endif
335650615Sobrien
335750615Sobrien#ifdef DWARF2_DEBUGGING_INFO
335850615Sobrien  if (write_symbols == DWARF2_DEBUG)
335950615Sobrien    TIMEVAR (symout_time,
336050615Sobrien	     {
336150615Sobrien	       dwarf2out_finish ();
336250615Sobrien	     });
336350615Sobrien#endif
336450615Sobrien
336518334Speter  /* Output some stuff at end of file if nec.  */
336618334Speter
336750615Sobrien  end_final (dump_base_name);
336850615Sobrien
336950615Sobrien  if (branch_prob_dump)
337050615Sobrien    open_dump_file (".bp", NULL);
337150615Sobrien
337250615Sobrien  TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
337350615Sobrien
337450615Sobrien  if (branch_prob_dump)
337550615Sobrien    close_dump_file (NULL, NULL_RTX);
337650615Sobrien
337718334Speter#ifdef ASM_FILE_END
337850615Sobrien  ASM_FILE_END (asm_out_file);
337918334Speter#endif
338018334Speter
338152558Sobrien
338218334Speter  /* Language-specific end of compilation actions.  */
338352558Sobrien finish_syntax:
338418334Speter  lang_finish ();
338518334Speter
338618334Speter  /* Close the dump files.  */
338718334Speter
338818334Speter  if (flag_gen_aux_info)
338918334Speter    {
339018334Speter      fclose (aux_info_file);
339118334Speter      if (errorcount)
339218334Speter	unlink (aux_info_file_name);
339318334Speter    }
339418334Speter
339518334Speter  if (combine_dump)
339618334Speter    {
339750615Sobrien      open_dump_file (".combine", NULL);
339850615Sobrien      TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
339950615Sobrien      close_dump_file (NULL, NULL_RTX);
340018334Speter    }
340118334Speter
340218334Speter  /* Close non-debugging input and output files.  Take special care to note
340318334Speter     whether fclose returns an error, since the pages might still be on the
340418334Speter     buffer chain while the file is open.  */
340518334Speter
340650615Sobrien  finish_parse ();
340750615Sobrien
340852558Sobrien  if (! flag_syntax_only
340952558Sobrien      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
341018334Speter    fatal_io_error (asm_file_name);
341118334Speter
341252558Sobrien  /* Do whatever is necessary to finish printing the graphs.  */
341352558Sobrien  if (graph_dump_format != no_graph)
341452558Sobrien    {
341552558Sobrien      if (jump_opt_dump)
341652558Sobrien	finish_graph_dump_file (dump_base_name, ".jump");
341752558Sobrien      if (addressof_dump)
341852558Sobrien	finish_graph_dump_file (dump_base_name, ".addressof");
341952558Sobrien      if (cse_dump)
342052558Sobrien	finish_graph_dump_file (dump_base_name, ".cse");
342152558Sobrien      if (loop_dump)
342252558Sobrien	finish_graph_dump_file (dump_base_name, ".loop");
342352558Sobrien      if (cse2_dump)
342452558Sobrien	finish_graph_dump_file (dump_base_name, ".cse2");
342552558Sobrien      if (branch_prob_dump)
342652558Sobrien	finish_graph_dump_file (dump_base_name, ".bp");
342752558Sobrien      if (flow_dump)
342852558Sobrien	finish_graph_dump_file (dump_base_name, ".flow");
342952558Sobrien      if (combine_dump)
343052558Sobrien	finish_graph_dump_file (dump_base_name, ".combine");
343152558Sobrien      if (regmove_dump)
343252558Sobrien	finish_graph_dump_file (dump_base_name, ".regmove");
343352558Sobrien      if (sched_dump)
343452558Sobrien	finish_graph_dump_file (dump_base_name, ".sched");
343552558Sobrien      if (local_reg_dump)
343652558Sobrien	finish_graph_dump_file (dump_base_name, ".lreg");
343752558Sobrien      if (global_reg_dump)
343852558Sobrien	finish_graph_dump_file (dump_base_name, ".greg");
343952558Sobrien      if (flow2_dump)
344052558Sobrien	finish_graph_dump_file (dump_base_name, ".flow2");
344152558Sobrien      if (sched2_dump)
344252558Sobrien	finish_graph_dump_file (dump_base_name, ".sched2");
344352558Sobrien      if (jump2_opt_dump)
344452558Sobrien	finish_graph_dump_file (dump_base_name, ".jump2");
344552558Sobrien#ifdef DELAY_SLOTS
344652558Sobrien      if (dbr_sched_dump)
344752558Sobrien	finish_graph_dump_file (dump_base_name, ".dbr");
344852558Sobrien#endif
344952558Sobrien      if (gcse_dump)
345052558Sobrien	finish_graph_dump_file (dump_base_name, ".gcse");
345152558Sobrien#ifdef STACK_REGS
345252558Sobrien      if (stack_reg_dump)
345352558Sobrien	finish_graph_dump_file (dump_base_name, ".stack");
345452558Sobrien#endif
345552558Sobrien#ifdef MACHINE_DEPENDENT_REORG
345652558Sobrien      if (mach_dep_reorg_dump)
345752558Sobrien	finish_graph_dump_file (dump_base_name, ".mach");
345852558Sobrien#endif
345952558Sobrien    }
346052558Sobrien
346152558Sobrien  /* Free up memory for the benefit of leak detectors.  */
346252558Sobrien  free_reg_info ();
346352558Sobrien
346418334Speter  /* Print the times.  */
346518334Speter
346618334Speter  if (! quiet_flag)
346718334Speter    {
346818334Speter      fprintf (stderr,"\n");
346918334Speter      print_time ("parse", parse_time);
347018334Speter
347150615Sobrien      print_time ("integration", integration_time);
347250615Sobrien      print_time ("jump", jump_time);
347350615Sobrien      print_time ("cse", cse_time);
347450615Sobrien      print_time ("gcse", gcse_time);
347550615Sobrien      print_time ("loop", loop_time);
347650615Sobrien      print_time ("cse2", cse2_time);
347750615Sobrien      print_time ("branch-prob", branch_prob_time);
347850615Sobrien      print_time ("flow", flow_time);
347950615Sobrien      print_time ("combine", combine_time);
348050615Sobrien      print_time ("regmove", regmove_time);
348150615Sobrien      print_time ("sched", sched_time);
348250615Sobrien      print_time ("local-alloc", local_alloc_time);
348350615Sobrien      print_time ("global-alloc", global_alloc_time);
348452558Sobrien      print_time ("flow2", flow2_time);
348550615Sobrien      print_time ("sched2", sched2_time);
348650615Sobrien#ifdef DELAY_SLOTS
348750615Sobrien      print_time ("dbranch", dbr_sched_time);
348850615Sobrien#endif
348950615Sobrien      print_time ("shorten-branch", shorten_branch_time);
349050615Sobrien      print_time ("stack-reg", stack_reg_time);
349150615Sobrien      print_time ("final", final_time);
349250615Sobrien      print_time ("varconst", varconst_time);
349350615Sobrien      print_time ("symout", symout_time);
349450615Sobrien      print_time ("dump", dump_time);
349518334Speter    }
349618334Speter}
349718334Speter
349818334Speter/* This is called from various places for FUNCTION_DECL, VAR_DECL,
349918334Speter   and TYPE_DECL nodes.
350018334Speter
350118334Speter   This does nothing for local (non-static) variables.
350218334Speter   Otherwise, it sets up the RTL and outputs any assembler code
350318334Speter   (label definition, storage allocation and initialization).
350418334Speter
350518334Speter   DECL is the declaration.  If ASMSPEC is nonzero, it specifies
350618334Speter   the assembler symbol name to be used.  TOP_LEVEL is nonzero
350718334Speter   if this declaration is not within a function.  */
350818334Speter
350918334Spetervoid
351018334Speterrest_of_decl_compilation (decl, asmspec, top_level, at_end)
351118334Speter     tree decl;
351252558Sobrien     const char *asmspec;
351318334Speter     int top_level;
351418334Speter     int at_end;
351518334Speter{
351618334Speter  /* Declarations of variables, and of functions defined elsewhere.  */
351718334Speter
351818334Speter/* The most obvious approach, to put an #ifndef around where
351918334Speter   this macro is used, doesn't work since it's inside a macro call.  */
352018334Speter#ifndef ASM_FINISH_DECLARE_OBJECT
352118334Speter#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
352218334Speter#endif
352318334Speter
352418334Speter  /* Forward declarations for nested functions are not "external",
352518334Speter     but we need to treat them as if they were.  */
352618334Speter  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
352718334Speter      || TREE_CODE (decl) == FUNCTION_DECL)
352818334Speter    TIMEVAR (varconst_time,
352918334Speter	     {
353018334Speter	       make_decl_rtl (decl, asmspec, top_level);
353118334Speter	       /* Initialized extern variable exists to be replaced
353218334Speter		  with its value, or represents something that will be
353318334Speter		  output in another file.  */
353418334Speter	       if (! (TREE_CODE (decl) == VAR_DECL
353518334Speter		      && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
353618334Speter		      && DECL_INITIAL (decl) != 0
353718334Speter		      && DECL_INITIAL (decl) != error_mark_node))
353818334Speter		 /* Don't output anything
353918334Speter		    when a tentative file-scope definition is seen.
354018334Speter		    But at end of compilation, do output code for them.  */
354118334Speter		 if (! (! at_end && top_level
354218334Speter			&& (DECL_INITIAL (decl) == 0
354318334Speter			    || DECL_INITIAL (decl) == error_mark_node)))
354418334Speter		   assemble_variable (decl, top_level, at_end, 0);
354518334Speter	       if (decl == last_assemble_variable_decl)
354618334Speter		 {
354718334Speter		   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
354818334Speter					      top_level, at_end);
354918334Speter		 }
355018334Speter	     });
355118334Speter  else if (DECL_REGISTER (decl) && asmspec != 0)
355218334Speter    {
355318334Speter      if (decode_reg_name (asmspec) >= 0)
355418334Speter	{
355518334Speter	  DECL_RTL (decl) = 0;
355618334Speter	  make_decl_rtl (decl, asmspec, top_level);
355718334Speter	}
355818334Speter      else
355918334Speter	error ("invalid register name `%s' for register variable", asmspec);
356018334Speter    }
356118334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
356218334Speter  else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
356318334Speter	   && TREE_CODE (decl) == TYPE_DECL)
356418334Speter    TIMEVAR (symout_time, dbxout_symbol (decl, 0));
356518334Speter#endif
356618334Speter#ifdef SDB_DEBUGGING_INFO
356718334Speter  else if (write_symbols == SDB_DEBUG && top_level
356818334Speter	   && TREE_CODE (decl) == TYPE_DECL)
356918334Speter    TIMEVAR (symout_time, sdbout_symbol (decl, 0));
357018334Speter#endif
357118334Speter}
357218334Speter
357318334Speter/* Called after finishing a record, union or enumeral type.  */
357418334Speter
357518334Spetervoid
357618334Speterrest_of_type_compilation (type, toplev)
357752558Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
357818334Speter     tree type;
357918334Speter     int toplev;
358052558Sobrien#else
358152558Sobrien     tree type ATTRIBUTE_UNUSED;
358252558Sobrien     int toplev ATTRIBUTE_UNUSED;
358352558Sobrien#endif
358418334Speter{
358518334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
358618334Speter  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
358718334Speter    TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
358818334Speter#endif
358918334Speter#ifdef SDB_DEBUGGING_INFO
359018334Speter  if (write_symbols == SDB_DEBUG)
359118334Speter    TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
359218334Speter#endif
359318334Speter}
359418334Speter
359518334Speter/* This is called from finish_function (within yyparse)
359618334Speter   after each top-level definition is parsed.
359718334Speter   It is supposed to compile that function or variable
359818334Speter   and output the assembler code for it.
359918334Speter   After we return, the tree storage is freed.  */
360018334Speter
360118334Spetervoid
360218334Speterrest_of_compilation (decl)
360318334Speter     tree decl;
360418334Speter{
360518334Speter  register rtx insns;
360618334Speter  int start_time = get_run_time ();
360718334Speter  int tem;
360818334Speter  /* Nonzero if we have saved the original DECL_INITIAL of the function,
360918334Speter     to be restored after we finish compiling the function
361018334Speter     (for use when compiling inline calls to this function).  */
361118334Speter  tree saved_block_tree = 0;
361218334Speter  /* Likewise, for DECL_ARGUMENTS.  */
361318334Speter  tree saved_arguments = 0;
361418334Speter  int failure = 0;
361552558Sobrien  int rebuild_label_notes_after_reload;
361618334Speter
361718334Speter  /* If we are reconsidering an inline function
361818334Speter     at the end of compilation, skip the stuff for making it inline.  */
361918334Speter
362018334Speter  if (DECL_SAVED_INSNS (decl) == 0)
362118334Speter    {
362250615Sobrien      int inlinable = 0;
362352558Sobrien      const char *lose;
362418334Speter
362518334Speter      /* If requested, consider whether to make this function inline.  */
362650615Sobrien      if (DECL_INLINE (decl) || flag_inline_functions)
362718334Speter	TIMEVAR (integration_time,
362818334Speter		 {
362918334Speter		   lose = function_cannot_inline_p (decl);
363018334Speter		   if (lose || ! optimize)
363118334Speter		     {
363250615Sobrien		       if (warn_inline && DECL_INLINE (decl))
363318334Speter			 warning_with_decl (decl, lose);
363418334Speter		       DECL_ABSTRACT_ORIGIN (decl) = 0;
363518334Speter		       /* Don't really compile an extern inline function.
363618334Speter			  If we can't make it inline, pretend
363718334Speter			  it was only declared.  */
363818334Speter		       if (DECL_EXTERNAL (decl))
363918334Speter			 {
364018334Speter			   DECL_INITIAL (decl) = 0;
364118334Speter			   goto exit_rest_of_compilation;
364218334Speter			 }
364318334Speter		     }
364418334Speter		   else
364550615Sobrien		     /* ??? Note that this has the effect of making it look
364650615Sobrien			like "inline" was specified for a function if we choose
364750615Sobrien			to inline it.  This isn't quite right, but it's
364850615Sobrien			probably not worth the trouble to fix.  */
364950615Sobrien		     inlinable = DECL_INLINE (decl) = 1;
365018334Speter		 });
365118334Speter
365218334Speter      insns = get_insns ();
365318334Speter
365418334Speter      /* Dump the rtl code if we are dumping rtl.  */
365518334Speter
365618334Speter      if (rtl_dump)
365750615Sobrien	{
365850615Sobrien	  open_dump_file (".rtl", decl_printable_name (decl, 2));
365950615Sobrien
366050615Sobrien	  if (DECL_SAVED_INSNS (decl))
366150615Sobrien	    fprintf (rtl_dump_file, ";; (integrable)\n\n");
366250615Sobrien
366350615Sobrien	  close_dump_file (print_rtl, insns);
366450615Sobrien	}
366518334Speter
366650615Sobrien      /* If we can, defer compiling inlines until EOF.
366750615Sobrien	 save_for_inline_copying can be extremely expensive.  */
366850615Sobrien      if (inlinable && ! decl_function_context (decl))
366950615Sobrien	DECL_DEFER_OUTPUT (decl) = 1;
367050615Sobrien
367118334Speter      /* If function is inline, and we don't yet know whether to
367218334Speter	 compile it by itself, defer decision till end of compilation.
367318334Speter	 finish_compilation will call rest_of_compilation again
367418334Speter	 for those functions that need to be output.  Also defer those
367550615Sobrien	 functions that we are supposed to defer.  We cannot defer
367650615Sobrien	 functions containing nested functions since the nested function
367750615Sobrien	 data is in our non-saved obstack.  We cannot defer nested
367850615Sobrien	 functions for the same reason.  */
367918334Speter
368050615Sobrien      /* If this is a nested inline, remove ADDRESSOF now so we can
368150615Sobrien	 finish compiling ourselves.  Otherwise, wait until EOF.
368250615Sobrien	 We have to do this because the purge_addressof transformation
368350615Sobrien	 changes the DECL_RTL for many variables, which confuses integrate.  */
368450615Sobrien      if (inlinable)
368518334Speter	{
368650615Sobrien	  if (decl_function_context (decl))
368750615Sobrien	    purge_addressof (insns);
368850615Sobrien	  else
368950615Sobrien	    DECL_DEFER_OUTPUT (decl) = 1;
369050615Sobrien	}
369150615Sobrien
369250615Sobrien      if (! current_function_contains_functions
369350615Sobrien	  && (DECL_DEFER_OUTPUT (decl)
369450615Sobrien	      || (DECL_INLINE (decl)
369550615Sobrien		  && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
369650615Sobrien		       && ! flag_keep_inline_functions)
369750615Sobrien		      || DECL_EXTERNAL (decl)))))
369850615Sobrien	{
369918334Speter	  DECL_DEFER_OUTPUT (decl) = 1;
370018334Speter
370150615Sobrien	  /* If -Wreturn-type, we have to do a bit of compilation.
370250615Sobrien	     However, if we just fall through we will call
370350615Sobrien	     save_for_inline_copying() which results in excessive
370450615Sobrien	     memory use.  Instead, we just want to call
370550615Sobrien	     jump_optimize() to figure out whether or not we can fall
370650615Sobrien	     off the end of the function; we do the minimum amount of
370750615Sobrien	     work necessary to make that safe.  And, we set optimize
370850615Sobrien	     to zero to keep jump_optimize from working too hard.  */
370950615Sobrien	  if (warn_return_type)
371018334Speter	    {
371150615Sobrien	      int saved_optimize = optimize;
371250615Sobrien	      optimize = 0;
371350615Sobrien	      find_exception_handler_labels ();
371450615Sobrien	      jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
371550615Sobrien			     !JUMP_AFTER_REGSCAN);
371650615Sobrien	      optimize = saved_optimize;
371750615Sobrien	    }
371850615Sobrien
371918334Speter#ifdef DWARF_DEBUGGING_INFO
372050615Sobrien	  /* Generate the DWARF info for the "abstract" instance
372150615Sobrien	     of a function which we may later generate inlined and/or
372250615Sobrien	     out-of-line instances of.  */
372350615Sobrien	  if (write_symbols == DWARF_DEBUG)
372450615Sobrien	    {
372550615Sobrien	      set_decl_abstract_flags (decl, 1);
372650615Sobrien	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
372750615Sobrien	      set_decl_abstract_flags (decl, 0);
372850615Sobrien	    }
372918334Speter#endif
373050615Sobrien#ifdef DWARF2_DEBUGGING_INFO
373150615Sobrien	  /* Generate the DWARF2 info for the "abstract" instance
373250615Sobrien	     of a function which we may later generate inlined and/or
373350615Sobrien	     out-of-line instances of.  */
373450615Sobrien	  if (write_symbols == DWARF2_DEBUG)
373550615Sobrien	    {
373650615Sobrien	      set_decl_abstract_flags (decl, 1);
373750615Sobrien	      TIMEVAR (symout_time, dwarf2out_decl (decl));
373850615Sobrien	      set_decl_abstract_flags (decl, 0);
373918334Speter	    }
374050615Sobrien#endif
374150615Sobrien	  TIMEVAR (integration_time, save_for_inline_nocopy (decl));
374250615Sobrien	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
374350615Sobrien	  goto exit_rest_of_compilation;
374418334Speter	}
374518334Speter
374618334Speter      /* If we have to compile the function now, save its rtl and subdecls
374718334Speter	 so that its compilation will not affect what others get.  */
374850615Sobrien      if (inlinable || DECL_DEFER_OUTPUT (decl))
374918334Speter	{
375018334Speter#ifdef DWARF_DEBUGGING_INFO
375118334Speter	  /* Generate the DWARF info for the "abstract" instance of
375218334Speter	     a function which we will generate an out-of-line instance
375318334Speter	     of almost immediately (and which we may also later generate
375418334Speter	     various inlined instances of).  */
375518334Speter	  if (write_symbols == DWARF_DEBUG)
375618334Speter	    {
375718334Speter	      set_decl_abstract_flags (decl, 1);
375818334Speter	      TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
375918334Speter	      set_decl_abstract_flags (decl, 0);
376018334Speter	    }
376118334Speter#endif
376250615Sobrien#ifdef DWARF2_DEBUGGING_INFO
376350615Sobrien	  /* Generate the DWARF2 info for the "abstract" instance of
376450615Sobrien	     a function which we will generate an out-of-line instance
376550615Sobrien	     of almost immediately (and which we may also later generate
376650615Sobrien	     various inlined instances of).  */
376750615Sobrien	  if (write_symbols == DWARF2_DEBUG)
376850615Sobrien	    {
376950615Sobrien	      set_decl_abstract_flags (decl, 1);
377050615Sobrien	      TIMEVAR (symout_time, dwarf2out_decl (decl));
377150615Sobrien	      set_decl_abstract_flags (decl, 0);
377250615Sobrien	    }
377350615Sobrien#endif
377418334Speter	  saved_block_tree = DECL_INITIAL (decl);
377518334Speter	  saved_arguments = DECL_ARGUMENTS (decl);
377618334Speter	  TIMEVAR (integration_time, save_for_inline_copying (decl));
377750615Sobrien	  RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
377818334Speter	}
377918334Speter
378018334Speter      /* If specified extern inline but we aren't inlining it, we are
378152558Sobrien	 done.  This goes for anything that gets here with DECL_EXTERNAL
378252558Sobrien	 set, not just things with DECL_INLINE.  */
378352558Sobrien      if (DECL_EXTERNAL (decl))
378418334Speter	goto exit_rest_of_compilation;
378518334Speter    }
378618334Speter
378718334Speter  if (! DECL_DEFER_OUTPUT (decl))
378818334Speter    TREE_ASM_WRITTEN (decl) = 1;
378918334Speter
379018334Speter  /* Now that integrate will no longer see our rtl, we need not distinguish
379118334Speter     between the return value of this function and the return value of called
379218334Speter     functions.  */
379318334Speter  rtx_equal_function_value_matters = 0;
379418334Speter
379518334Speter  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
379618334Speter  if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
379718334Speter    {
379818334Speter      goto exit_rest_of_compilation;
379918334Speter    }
380018334Speter
380150615Sobrien  /* Emit code to get eh context, if needed. */
380250615Sobrien  emit_eh_context ();
380318334Speter
380418334Speter#ifdef FINALIZE_PIC
380518334Speter  /* If we are doing position-independent code generation, now
380618334Speter     is the time to output special prologues and epilogues.
380718334Speter     We do not want to do this earlier, because it just clutters
380818334Speter     up inline functions with meaningless insns.  */
380918334Speter  if (flag_pic)
381018334Speter    FINALIZE_PIC;
381118334Speter#endif
381218334Speter
381350615Sobrien  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
381450615Sobrien     Note that that may have been done above, in save_for_inline_copying.
381550615Sobrien     The call to resume_temporary_allocation near the end of this function
381650615Sobrien     goes back to the usual state of affairs.  This must be done after
381750615Sobrien     we've built up any unwinders for exception handling, and done
381850615Sobrien     the FINALIZE_PIC work, if necessary.  */
381950615Sobrien
382050615Sobrien  rtl_in_current_obstack ();
382150615Sobrien
382218334Speter  insns = get_insns ();
382318334Speter
382418334Speter  /* Copy any shared structure that should not be shared.  */
382518334Speter
382618334Speter  unshare_all_rtl (insns);
382718334Speter
382850615Sobrien#ifdef SETJMP_VIA_SAVE_AREA
382950615Sobrien  /* This must be performed before virutal register instantiation.  */
383050615Sobrien  if (current_function_calls_alloca)
383150615Sobrien    optimize_save_area_alloca (insns);
383250615Sobrien#endif
383350615Sobrien
383418334Speter  /* Instantiate all virtual registers.  */
383518334Speter
383618334Speter  instantiate_virtual_regs (current_function_decl, get_insns ());
383718334Speter
383818334Speter  /* See if we have allocated stack slots that are not directly addressable.
383918334Speter     If so, scan all the insns and create explicit address computation
384018334Speter     for all references to such slots.  */
384118334Speter/*   fixup_stack_slots (); */
384218334Speter
384350615Sobrien  /* Find all the EH handlers.  */
384450615Sobrien  find_exception_handler_labels ();
384518334Speter
384650615Sobrien  /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
384750615Sobrien     are initialized and to compute whether control can drop off the end
384850615Sobrien     of the function.  */
384950615Sobrien  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
385050615Sobrien  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
385150615Sobrien				     JUMP_AFTER_REGSCAN));
385218334Speter
385318334Speter  /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
385418334Speter  if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
385518334Speter    goto exit_rest_of_compilation;
385618334Speter
385718334Speter  /* Dump rtl code after jump, if we are doing that.  */
385818334Speter
385950615Sobrien    if (jump_opt_dump)
386050615Sobrien      dump_rtl (".jump", decl, print_rtl, insns);
386118334Speter
386218334Speter  /* Perform common subexpression elimination.
386318334Speter     Nonzero value from `cse_main' means that jumps were simplified
386418334Speter     and some code may now be unreachable, so do
386518334Speter     jump optimization again.  */
386618334Speter
386718334Speter  if (optimize > 0)
386818334Speter    {
386950615Sobrien      if (cse_dump)
387050615Sobrien	open_dump_file (".cse", decl_printable_name (decl, 2));
387150615Sobrien
387218334Speter      TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
387318334Speter
387418334Speter      if (flag_thread_jumps)
387518334Speter	/* Hacks by tiemann & kenner.  */
387618334Speter	TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
387718334Speter
387818334Speter      TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
387950615Sobrien					 0, rtl_dump_file));
388050615Sobrien      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
388118334Speter
388218334Speter      if (tem || optimize > 1)
388350615Sobrien	TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
388450615Sobrien					   !JUMP_NOOP_MOVES,
388550615Sobrien					   !JUMP_AFTER_REGSCAN));
388650615Sobrien
388750615Sobrien      /* Dump rtl code after cse, if we are doing that.  */
388852558Sobrien
388950615Sobrien      if (cse_dump)
389052558Sobrien	{
389152558Sobrien	  close_dump_file (print_rtl, insns);
389252558Sobrien	  if (graph_dump_format != no_graph)
389352558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
389452558Sobrien	}
389518334Speter    }
389618334Speter
389750615Sobrien  purge_addressof (insns);
389850615Sobrien  reg_scan (insns, max_reg_num (), 1);
389918334Speter
390050615Sobrien  if (addressof_dump)
390152558Sobrien    {
390252558Sobrien      dump_rtl (".addressof", decl, print_rtl, insns);
390352558Sobrien      if (graph_dump_format != no_graph)
390452558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
390552558Sobrien    }
390652558Sobrien
390750615Sobrien  /* Perform global cse.  */
390818334Speter
390950615Sobrien  if (optimize > 0 && flag_gcse)
391050615Sobrien    {
391150615Sobrien      if (gcse_dump)
391250615Sobrien	open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
391318334Speter
391452558Sobrien      TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
391552558Sobrien
391652558Sobrien      /* If gcse altered any jumps, rerun jump optimizations to clean
391752558Sobrien	 things up.  */
391852558Sobrien      if (tem)
391952558Sobrien	{
392052558Sobrien	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
392152558Sobrien					     !JUMP_NOOP_MOVES,
392252558Sobrien					     !JUMP_AFTER_REGSCAN));
392352558Sobrien        }
392452558Sobrien
392550615Sobrien      if (gcse_dump)
392652558Sobrien	{
392752558Sobrien	  close_dump_file (print_rtl, insns);
392852558Sobrien	  if (graph_dump_format != no_graph)
392952558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
393052558Sobrien	}
393150615Sobrien    }
393218334Speter  /* Move constant computations out of loops.  */
393318334Speter
393418334Speter  if (optimize > 0)
393518334Speter    {
393650615Sobrien      if (loop_dump)
393750615Sobrien	open_dump_file (".loop", decl_printable_name (decl, 2));
393850615Sobrien
393950615Sobrien      TIMEVAR
394050615Sobrien	(loop_time,
394150615Sobrien	 {
394250615Sobrien	   if (flag_rerun_loop_opt)
394318334Speter	     {
394450615Sobrien	       /* We only want to perform unrolling once.  */
394550615Sobrien
394652558Sobrien	       loop_optimize (insns, rtl_dump_file, 0, 0);
394750615Sobrien
394850615Sobrien
394950615Sobrien	       /* The first call to loop_optimize makes some instructions
395050615Sobrien		  trivially dead.  We delete those instructions now in the
395150615Sobrien		  hope that doing so will make the heuristics in loop work
395250615Sobrien		  better and possibly speed up compilation.  */
395350615Sobrien	       delete_trivially_dead_insns (insns, max_reg_num ());
395418334Speter
395550615Sobrien	       /* The regscan pass is currently necessary as the alias
395650615Sobrien		  analysis code depends on this information.  */
395750615Sobrien	       reg_scan (insns, max_reg_num (), 1);
395850615Sobrien	     }
395952558Sobrien	   loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
396050615Sobrien	 });
396152558Sobrien
396250615Sobrien      /* Dump rtl code after loop opt, if we are doing that.  */
396352558Sobrien
396450615Sobrien      if (loop_dump)
396552558Sobrien	{
396652558Sobrien	  close_dump_file (print_rtl, insns);
396752558Sobrien	  if (graph_dump_format != no_graph)
396852558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
396952558Sobrien	}
397050615Sobrien    }
397118334Speter
397250615Sobrien  if (optimize > 0)
397318334Speter    {
397450615Sobrien      if (cse2_dump)
397550615Sobrien	open_dump_file (".cse2", decl_printable_name (decl, 2));
397652558Sobrien
397750615Sobrien      if (flag_rerun_cse_after_loop)
397850615Sobrien	{
397950615Sobrien	  /* Running another jump optimization pass before the second
398050615Sobrien	     cse pass sometimes simplifies the RTL enough to allow
398150615Sobrien	     the second CSE pass to do a better job.  Jump_optimize can change
398250615Sobrien	     max_reg_num so we must rerun reg_scan afterwards.
398350615Sobrien	     ??? Rework to not call reg_scan so often.  */
398450615Sobrien	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
398550615Sobrien	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
398650615Sobrien					     !JUMP_NOOP_MOVES,
398750615Sobrien					     JUMP_AFTER_REGSCAN));
398850615Sobrien
398950615Sobrien	  TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
399050615Sobrien	  TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
399150615Sobrien					      1, rtl_dump_file));
399250615Sobrien	  if (tem)
399350615Sobrien	    TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
399450615Sobrien					       !JUMP_NOOP_MOVES,
399550615Sobrien					       !JUMP_AFTER_REGSCAN));
399650615Sobrien	}
399718334Speter
399850615Sobrien      if (flag_thread_jumps)
399950615Sobrien	{
400050615Sobrien	  /* This pass of jump threading straightens out code
400150615Sobrien	     that was kinked by loop optimization.  */
400250615Sobrien	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
400350615Sobrien	  TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
400450615Sobrien	}
400552558Sobrien
400650615Sobrien      /* Dump rtl code after cse, if we are doing that.  */
400752558Sobrien
400850615Sobrien      if (cse2_dump)
400952558Sobrien	{
401052558Sobrien	  close_dump_file (print_rtl, insns);
401152558Sobrien	  if (graph_dump_format != no_graph)
401252558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
401352558Sobrien	}
401418334Speter    }
401552558Sobrien
401650615Sobrien  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
401750615Sobrien    {
401850615Sobrien      if (branch_prob_dump)
401950615Sobrien	open_dump_file (".bp", decl_printable_name (decl, 2));
402052558Sobrien
402150615Sobrien      TIMEVAR
402250615Sobrien	(branch_prob_time,
402350615Sobrien	 {
402450615Sobrien	   branch_prob (insns, rtl_dump_file);
402550615Sobrien	 });
402652558Sobrien
402750615Sobrien      if (branch_prob_dump)
402852558Sobrien	{
402952558Sobrien	  close_dump_file (print_rtl, insns);
403052558Sobrien	  if (graph_dump_format != no_graph)
403152558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
403252558Sobrien	}
403350615Sobrien    }
403452558Sobrien
403518334Speter  /* We are no longer anticipating cse in this function, at least.  */
403618334Speter
403718334Speter  cse_not_expected = 1;
403818334Speter
403918334Speter  /* Now we choose between stupid (pcc-like) register allocation
404018334Speter     (if we got the -noreg switch and not -opt)
404118334Speter     and smart register allocation.  */
404218334Speter
404352558Sobrien  if (optimize > 0)		/* Stupid allocation probably won't work */
404418334Speter    obey_regdecls = 0;		/* if optimizations being done.  */
404518334Speter
404618334Speter  regclass_init ();
404718334Speter
404818334Speter  /* Print function header into flow dump now
404918334Speter     because doing the flow analysis makes some of the dump.  */
405018334Speter
405118334Speter  if (flow_dump)
405250615Sobrien    open_dump_file (".flow", decl_printable_name (decl, 2));
405350615Sobrien
405418334Speter  if (obey_regdecls)
405518334Speter    {
405618334Speter      TIMEVAR (flow_time,
405718334Speter	       {
405818334Speter		 regclass (insns, max_reg_num ());
405918334Speter		 stupid_life_analysis (insns, max_reg_num (),
406050615Sobrien				       rtl_dump_file);
406118334Speter	       });
406218334Speter    }
406318334Speter  else
406418334Speter    {
406518334Speter      /* Do control and data flow analysis,
406618334Speter	 and write some of the results to dump file.  */
406718334Speter
406850615Sobrien      TIMEVAR
406950615Sobrien	(flow_time,
407050615Sobrien	 {
407150615Sobrien	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
407252558Sobrien	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
407350615Sobrien	 });
407450615Sobrien
407518334Speter      if (warn_uninitialized)
407618334Speter	{
407718334Speter	  uninitialized_vars_warning (DECL_INITIAL (decl));
407818334Speter	  setjmp_args_warning ();
407918334Speter	}
408018334Speter    }
408118334Speter
408218334Speter  /* Dump rtl after flow analysis.  */
408318334Speter
408418334Speter  if (flow_dump)
408552558Sobrien    {
408652558Sobrien      close_dump_file (print_rtl_with_bb, insns);
408752558Sobrien      if (graph_dump_format != no_graph)
408852558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
408952558Sobrien    }
409052558Sobrien
409152558Sobrien  /* The first life analysis pass has finished.  From now on we can not
409252558Sobrien     generate any new pseudos.  */
409352558Sobrien  no_new_pseudos = 1;
409452558Sobrien
409518334Speter  /* If -opt, try combining insns through substitution.  */
409618334Speter
409718334Speter  if (optimize > 0)
409850615Sobrien    {
409950615Sobrien      TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
410052558Sobrien
410150615Sobrien      /* Dump rtl code after insn combination.  */
410252558Sobrien
410350615Sobrien      if (combine_dump)
410452558Sobrien	{
410552558Sobrien	  dump_rtl (".combine", decl, print_rtl_with_bb, insns);
410652558Sobrien	  if (graph_dump_format != no_graph)
410752558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
410852558Sobrien	}
410950615Sobrien    }
411018334Speter
411150615Sobrien  /* Register allocation pre-pass, to reduce number of moves
411250615Sobrien     necessary for two-address machines.  */
411350615Sobrien  if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
411450615Sobrien    {
411550615Sobrien      if (regmove_dump)
411650615Sobrien	open_dump_file (".regmove", decl_printable_name (decl, 2));
411752558Sobrien
411850615Sobrien      TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
411950615Sobrien					       rtl_dump_file));
412052558Sobrien
412150615Sobrien      if (regmove_dump)
412252558Sobrien	{
412352558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
412452558Sobrien	  if (graph_dump_format != no_graph)
412552558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
412652558Sobrien	}
412750615Sobrien    }
412818334Speter
412918334Speter  /* Print function header into sched dump now
413018334Speter     because doing the sched analysis makes some of the dump.  */
413118334Speter
413218334Speter  if (optimize > 0 && flag_schedule_insns)
413318334Speter    {
413450615Sobrien      if (sched_dump)
413550615Sobrien	open_dump_file (".sched", decl_printable_name (decl, 2));
413652558Sobrien
413718334Speter      /* Do control and data sched analysis,
413818334Speter	 and write some of the results to dump file.  */
413918334Speter
414050615Sobrien      TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
414152558Sobrien
414250615Sobrien      /* Dump rtl after instruction scheduling.  */
414352558Sobrien
414450615Sobrien      if (sched_dump)
414552558Sobrien	{
414652558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
414752558Sobrien	  if (graph_dump_format != no_graph)
414852558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
414952558Sobrien	}
415018334Speter    }
415118334Speter
415252558Sobrien  /* Determine if the current function is a leaf before running reload
415352558Sobrien     since this can impact optimizations done by the prologue and
415452558Sobrien     epilogue thus changing register elimination offsets.  */
415552558Sobrien  current_function_is_leaf = leaf_function_p ();
415652558Sobrien
415718334Speter  /* Unless we did stupid register allocation,
415852558Sobrien     allocate pseudo-regs that are used only within 1 basic block.
415918334Speter
416052558Sobrien     RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
416152558Sobrien     jump optimizer after register allocation and reloading are finished.  */
416252558Sobrien
416318334Speter  if (!obey_regdecls)
416418334Speter    TIMEVAR (local_alloc_time,
416518334Speter	     {
416652558Sobrien	       recompute_reg_usage (insns, ! optimize_size);
416718334Speter	       regclass (insns, max_reg_num ());
416852558Sobrien	       rebuild_label_notes_after_reload = local_alloc ();
416918334Speter	     });
417052558Sobrien  else
417152558Sobrien    rebuild_label_notes_after_reload = 0;
417218334Speter
417318334Speter  /* Dump rtl code after allocating regs within basic blocks.  */
417418334Speter
417518334Speter  if (local_reg_dump)
417650615Sobrien    {
417750615Sobrien      open_dump_file (".lreg", decl_printable_name (decl, 2));
417852558Sobrien
417950615Sobrien      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
418050615Sobrien      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
418152558Sobrien
418250615Sobrien      close_dump_file (print_rtl_with_bb, insns);
418352558Sobrien      if (graph_dump_format != no_graph)
418452558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
418550615Sobrien    }
418618334Speter
418718334Speter  if (global_reg_dump)
418850615Sobrien    open_dump_file (".greg", decl_printable_name (decl, 2));
418918334Speter
419018334Speter  /* Unless we did stupid register allocation,
419118334Speter     allocate remaining pseudo-regs, then do the reload pass
419218334Speter     fixing up any insns that are invalid.  */
419318334Speter
419418334Speter  TIMEVAR (global_alloc_time,
419518334Speter	   {
419618334Speter	     if (!obey_regdecls)
419750615Sobrien	       failure = global_alloc (rtl_dump_file);
419818334Speter	     else
419950615Sobrien	       failure = reload (insns, 0, rtl_dump_file);
420018334Speter	   });
420118334Speter
420218334Speter
420318334Speter  if (failure)
420418334Speter    goto exit_rest_of_compilation;
420518334Speter
420650615Sobrien  /* Do a very simple CSE pass over just the hard registers.  */
420750615Sobrien  if (optimize > 0)
420850615Sobrien    reload_cse_regs (insns);
420950615Sobrien
421052558Sobrien  /* Register allocation and reloading may have turned an indirect jump into
421152558Sobrien     a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
421252558Sobrien     jumping instructions.  */
421352558Sobrien  if (rebuild_label_notes_after_reload)
421452558Sobrien    TIMEVAR (jump_time, rebuild_jump_labels (insns));
421552558Sobrien
421652558Sobrien  /* If optimizing and we are performing instruction scheduling after
421752558Sobrien     reload, then go ahead and split insns now since we are about to
421852558Sobrien     recompute flow information anyway.
421952558Sobrien
422052558Sobrien     reload_cse_regs may expose more splitting opportunities, expecially
422152558Sobrien     for double-word operations.  */
422252558Sobrien  if (optimize > 0 && flag_schedule_insns_after_reload)
422352558Sobrien    {
422452558Sobrien      rtx insn;
422552558Sobrien
422652558Sobrien      for (insn = insns; insn; insn = NEXT_INSN (insn))
422752558Sobrien	{
422852558Sobrien	  rtx last;
422952558Sobrien
423052558Sobrien	  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
423152558Sobrien	    continue;
423252558Sobrien
423352558Sobrien	  last = try_split (PATTERN (insn), insn, 1);
423452558Sobrien
423552558Sobrien	  if (last != insn)
423652558Sobrien	    {
423752558Sobrien	      PUT_CODE (insn, NOTE);
423852558Sobrien	      NOTE_SOURCE_FILE (insn) = 0;
423952558Sobrien	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
424052558Sobrien	    }
424152558Sobrien	}
424252558Sobrien    }
424352558Sobrien
424452558Sobrien  if (global_reg_dump)
424552558Sobrien    {
424652558Sobrien      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
424752558Sobrien      close_dump_file (print_rtl_with_bb, insns);
424852558Sobrien      if (graph_dump_format != no_graph)
424952558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
425052558Sobrien    }
425152558Sobrien
425252558Sobrien  /* Re-create the death notes which were deleted during reload.  */
425352558Sobrien  if (flow2_dump)
425452558Sobrien    open_dump_file (".flow2", decl_printable_name (decl, 2));
425552558Sobrien
425652558Sobrien  if (optimize)
425752558Sobrien    {
425852558Sobrien      TIMEVAR
425952558Sobrien	(flow2_time,
426052558Sobrien	 {
426152558Sobrien	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
426252558Sobrien	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
426352558Sobrien	 });
426452558Sobrien    }
426552558Sobrien
426652558Sobrien  flow2_completed = 1;
426752558Sobrien
426818334Speter  /* On some machines, the prologue and epilogue code, or parts thereof,
426918334Speter     can be represented as RTL.  Doing so lets us schedule insns between
427018334Speter     it and the rest of the code and also allows delayed branch
427118334Speter     scheduling to operate in the epilogue.  */
427218334Speter
427318334Speter  thread_prologue_and_epilogue_insns (insns);
427418334Speter
427552558Sobrien  if (flow2_dump)
427650615Sobrien    {
427750615Sobrien      close_dump_file (print_rtl_with_bb, insns);
427852558Sobrien      if (graph_dump_format != no_graph)
427952558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
428050615Sobrien    }
428152558Sobrien
428218334Speter  if (optimize > 0 && flag_schedule_insns_after_reload)
428318334Speter    {
428418334Speter      if (sched2_dump)
428550615Sobrien	open_dump_file (".sched2", decl_printable_name (decl, 2));
428618334Speter
428718334Speter      /* Do control and data sched analysis again,
428818334Speter	 and write some more of the results to dump file.  */
428918334Speter
429050615Sobrien      TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
429118334Speter
429218334Speter      /* Dump rtl after post-reorder instruction scheduling.  */
429318334Speter
429418334Speter      if (sched2_dump)
429552558Sobrien	{
429652558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
429752558Sobrien	  if (graph_dump_format != no_graph)
429852558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
429952558Sobrien	}
430018334Speter    }
430118334Speter
430218334Speter#ifdef LEAF_REGISTERS
430352558Sobrien  current_function_uses_only_leaf_regs
430452558Sobrien    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
430518334Speter#endif
430618334Speter
430718334Speter  /* One more attempt to remove jumps to .+1
430818334Speter     left by dead-store-elimination.
430918334Speter     Also do cross-jumping this time
431018334Speter     and delete no-op move insns.  */
431118334Speter
431218334Speter  if (optimize > 0)
431318334Speter    {
431450615Sobrien      TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
431550615Sobrien					 JUMP_NOOP_MOVES,
431650615Sobrien					 !JUMP_AFTER_REGSCAN));
431752558Sobrien
431850615Sobrien      /* Dump rtl code after jump, if we are doing that.  */
431950615Sobrien
432050615Sobrien      if (jump2_opt_dump)
432152558Sobrien	{
432252558Sobrien	  dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
432352558Sobrien	  if (graph_dump_format != no_graph)
432452558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
432552558Sobrien	}
432618334Speter    }
432718334Speter
432818334Speter  /* If a machine dependent reorganization is needed, call it.  */
432918334Speter#ifdef MACHINE_DEPENDENT_REORG
433018334Speter   MACHINE_DEPENDENT_REORG (insns);
433150615Sobrien
433250615Sobrien   if (mach_dep_reorg_dump)
433352558Sobrien     {
433452558Sobrien       dump_rtl (".mach", decl, print_rtl_with_bb, insns);
433552558Sobrien       if (graph_dump_format != no_graph)
433652558Sobrien	 print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
433752558Sobrien     }
433818334Speter#endif
433918334Speter
434018334Speter  /* If a scheduling pass for delayed branches is to be done,
434150615Sobrien     call the scheduling code.  */
434218334Speter
434318334Speter#ifdef DELAY_SLOTS
434418334Speter  if (optimize > 0 && flag_delayed_branch)
434518334Speter    {
434652558Sobrien      if (dbr_sched_dump)
434752558Sobrien	open_dump_file (".dbr", decl_printable_name (decl, 2));
434852558Sobrien
434950615Sobrien      TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
435052558Sobrien
435118334Speter      if (dbr_sched_dump)
435252558Sobrien	{
435352558Sobrien	  close_dump_file (print_rtl_with_bb, insns);
435452558Sobrien	  if (graph_dump_format != no_graph)
435552558Sobrien	    print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
435652558Sobrien	}
435718334Speter    }
435818334Speter#endif
435918334Speter
436018334Speter  /* Shorten branches.  */
436118334Speter  TIMEVAR (shorten_branch_time,
436218334Speter	   {
436318334Speter	     shorten_branches (get_insns ());
436418334Speter	   });
436518334Speter
436618334Speter#ifdef STACK_REGS
436752558Sobrien  if (stack_reg_dump)
436852558Sobrien    open_dump_file (".stack", decl_printable_name (decl, 2));
436952558Sobrien
437050615Sobrien  TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
437150615Sobrien
437218334Speter  if (stack_reg_dump)
437352558Sobrien    {
437452558Sobrien      dump_rtl (".stack", decl, print_rtl_with_bb, insns);
437552558Sobrien      if (graph_dump_format != no_graph)
437652558Sobrien	print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
437752558Sobrien    }
437818334Speter#endif
437918334Speter
438018334Speter  /* Now turn the rtl into assembler code.  */
438118334Speter
438218334Speter  TIMEVAR (final_time,
438318334Speter	   {
438418334Speter	     rtx x;
438518334Speter	     char *fnname;
438618334Speter
438718334Speter	     /* Get the function's name, as described by its RTL.
438818334Speter		This may be different from the DECL_NAME name used
438918334Speter		in the source file.  */
439018334Speter
439118334Speter	     x = DECL_RTL (decl);
439218334Speter	     if (GET_CODE (x) != MEM)
439318334Speter	       abort ();
439418334Speter	     x = XEXP (x, 0);
439518334Speter	     if (GET_CODE (x) != SYMBOL_REF)
439618334Speter	       abort ();
439718334Speter	     fnname = XSTR (x, 0);
439818334Speter
439918334Speter	     assemble_start_function (decl, fnname);
440018334Speter	     final_start_function (insns, asm_out_file, optimize);
440118334Speter	     final (insns, asm_out_file, optimize, 0);
440218334Speter	     final_end_function (insns, asm_out_file, optimize);
440318334Speter	     assemble_end_function (decl, fnname);
440450615Sobrien	     if (! quiet_flag)
440550615Sobrien	       fflush (asm_out_file);
440650615Sobrien
440752558Sobrien	     /* Release all memory allocated by flow.  */
440852558Sobrien	     free_basic_block_vars (0);
440952558Sobrien
441050615Sobrien	     /* Release all memory held by regsets now */
441150615Sobrien	     regset_release_memory ();
441218334Speter	   });
441318334Speter
441418334Speter  /* Write DBX symbols if requested */
441518334Speter
441618334Speter  /* Note that for those inline functions where we don't initially
441718334Speter     know for certain that we will be generating an out-of-line copy,
441818334Speter     the first invocation of this routine (rest_of_compilation) will
441918334Speter     skip over this code by doing a `goto exit_rest_of_compilation;'.
442018334Speter     Later on, finish_compilation will call rest_of_compilation again
442118334Speter     for those inline functions that need to have out-of-line copies
442218334Speter     generated.  During that call, we *will* be routed past here.  */
442318334Speter
442418334Speter#ifdef DBX_DEBUGGING_INFO
442518334Speter  if (write_symbols == DBX_DEBUG)
442618334Speter    TIMEVAR (symout_time, dbxout_function (decl));
442718334Speter#endif
442818334Speter
442918334Speter#ifdef DWARF_DEBUGGING_INFO
443018334Speter  if (write_symbols == DWARF_DEBUG)
443118334Speter    TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
443218334Speter#endif
443318334Speter
443450615Sobrien#ifdef DWARF2_DEBUGGING_INFO
443550615Sobrien  if (write_symbols == DWARF2_DEBUG)
443650615Sobrien    TIMEVAR (symout_time, dwarf2out_decl (decl));
443750615Sobrien#endif
443850615Sobrien
443918334Speter exit_rest_of_compilation:
444018334Speter
444152558Sobrien  free_bb_mem ();
444252558Sobrien
444318334Speter  /* In case the function was not output,
444418334Speter     don't leave any temporary anonymous types
444518334Speter     queued up for sdb output.  */
444618334Speter#ifdef SDB_DEBUGGING_INFO
444718334Speter  if (write_symbols == SDB_DEBUG)
444818334Speter    sdbout_types (NULL_TREE);
444918334Speter#endif
445018334Speter
445118334Speter  /* Put back the tree of subblocks and list of arguments
445218334Speter     from before we copied them.
445318334Speter     Code generation and the output of debugging info may have modified
445418334Speter     the copy, but the original is unchanged.  */
445518334Speter
445618334Speter  if (saved_block_tree != 0)
445750615Sobrien    {
445850615Sobrien      DECL_INITIAL (decl) = saved_block_tree;
445950615Sobrien      DECL_ARGUMENTS (decl) = saved_arguments;
446050615Sobrien      DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
446150615Sobrien    }
446218334Speter
446318334Speter  reload_completed = 0;
446452558Sobrien  flow2_completed = 0;
446552558Sobrien  no_new_pseudos = 0;
446618334Speter
446750615Sobrien  TIMEVAR (final_time,
446850615Sobrien	   {
446950615Sobrien	      /* Clear out the insn_length contents now that they are no
447050615Sobrien		 longer valid.  */
447150615Sobrien	      init_insn_lengths ();
447218334Speter
447350615Sobrien	      /* Clear out the real_constant_chain before some of the rtx's
447450615Sobrien		 it runs through become garbage.  */
447550615Sobrien	      clear_const_double_mem ();
447618334Speter
447750615Sobrien	      /* Cancel the effect of rtl_in_current_obstack.  */
447850615Sobrien	      resume_temporary_allocation ();
447918334Speter
448050615Sobrien	      /* Show no temporary slots allocated.  */
448150615Sobrien	      init_temp_slots ();
448250615Sobrien	   });
448318334Speter
448450615Sobrien  /* Make sure volatile mem refs aren't considered valid operands for
448550615Sobrien     arithmetic insns.  We must call this here if this is a nested inline
448650615Sobrien     function, since the above code leaves us in the init_recog state
448750615Sobrien     (from final.c), and the function context push/pop code does not
448850615Sobrien     save/restore volatile_ok.
448918334Speter
449050615Sobrien     ??? Maybe it isn't necessary for expand_start_function to call this
449150615Sobrien     anymore if we do it here?  */
449250615Sobrien
449350615Sobrien  init_recog_no_volatile ();
449450615Sobrien
449518334Speter  /* The parsing time is all the time spent in yyparse
449618334Speter     *except* what is spent in this function.  */
449718334Speter
449818334Speter  parse_time -= get_run_time () - start_time;
449952558Sobrien
450052558Sobrien  /* Reset global variables.  */
450152558Sobrien  free_basic_block_vars (0);
450218334Speter}
450318334Speter
450450615Sobrienstatic void
450550615Sobriendisplay_help ()
450650615Sobrien{
450750615Sobrien  int    undoc;
450852558Sobrien  unsigned long	 i;
450952558Sobrien  const char * lang;
451052558Sobrien
451152558Sobrien#ifndef USE_CPPLIB
451250615Sobrien  printf ("Usage: %s input [switches]\n", progname);
451350615Sobrien  printf ("Switches:\n");
451450615Sobrien#endif
451550615Sobrien  printf ("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n");
451650615Sobrien  printf ("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n");
451750615Sobrien  printf ("  -fcall-saved-<register> Mark <register> as being preserved across functions\n");
451852558Sobrien  printf ("  -finline-limit-<number> Limits the size of inlined functions to <number>\n");
451950615Sobrien
452050615Sobrien  for (i = NUM_ELEM (f_options); i--;)
452150615Sobrien    {
452252558Sobrien      const char * description = f_options[i].description;
452350615Sobrien
452450615Sobrien      if (description != NULL && * description != 0)
452550615Sobrien	printf ("  -f%-21s %s\n",
452650615Sobrien		f_options[i].string, description);
452750615Sobrien    }
452850615Sobrien
452950615Sobrien  printf ("  -O[number]              Set optimisation level to [number]\n");
453050615Sobrien  printf ("  -Os                     Optimise for space rather than speed\n");
453150615Sobrien  printf ("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n");
453250615Sobrien  printf ("  -pedantic-errors        Like -pedantic except that errors are produced\n");
453350615Sobrien  printf ("  -w                      Suppress warnings\n");
453450615Sobrien  printf ("  -W                      Enable extra warnings\n");
453550615Sobrien
453650615Sobrien  for (i = NUM_ELEM (W_options); i--;)
453750615Sobrien    {
453852558Sobrien      const char * description = W_options[i].description;
453950615Sobrien
454050615Sobrien      if (description != NULL && * description != 0)
454150615Sobrien	printf ("  -W%-21s %s\n",
454250615Sobrien		W_options[i].string, description);
454350615Sobrien    }
454450615Sobrien
454550615Sobrien  printf ("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n");
454650615Sobrien  printf ("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n");
454750615Sobrien  printf ("  -p                      Enable function profiling\n");
454850615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
454950615Sobrien  printf ("  -a                      Enable block profiling \n");
455050615Sobrien#endif
455150615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
455250615Sobrien  printf ("  -ax                     Enable jump profiling \n");
455350615Sobrien#endif
455450615Sobrien  printf ("  -o <file>               Place output into <file> \n");
455550615Sobrien  printf ("  -G <number>             Put global and static data smaller than <number>\n");
455650615Sobrien  printf ("                           bytes into a special section (on some targets)\n");
455750615Sobrien
455850615Sobrien  for (i = NUM_ELEM (debug_args); i--;)
455950615Sobrien    {
456050615Sobrien      if (debug_args[i].description != NULL)
456150615Sobrien	printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
456250615Sobrien    }
456350615Sobrien
456450615Sobrien  printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
456550615Sobrien  printf ("  -quiet                  Do not display functions compiled or elapsed time\n");
456650615Sobrien  printf ("  -version                Display the compiler's version\n");
456750615Sobrien  printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
456850615Sobrien  printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
456950615Sobrien#if defined HAIFA || defined INSN_SCHEDULING
457050615Sobrien  printf ("  -sched-verbose-<number> Set the verbosity level of the scheduler\n");
457150615Sobrien#endif
457250615Sobrien  printf ("  --help                  Display this information\n");
457350615Sobrien
457450615Sobrien  undoc = 0;
457550615Sobrien  lang  = "language";
457650615Sobrien
457750615Sobrien  /* Display descriptions of language specific options.
457850615Sobrien     If there is no description, note that there is an undocumented option.
457950615Sobrien     If the description is empty, do not display anything.  (This allows
458050615Sobrien     options to be deliberately undocumented, for whatever reason).
458150615Sobrien     If the option string is missing, then this is a marker, indicating
458252558Sobrien     that the description string is in fact the name of a language, whose
458350615Sobrien     language specific options are to follow.  */
458450615Sobrien
458550615Sobrien  if (NUM_ELEM (documented_lang_options) > 1)
458650615Sobrien    {
458750615Sobrien      printf ("\nLanguage specific options:\n");
458850615Sobrien
458950615Sobrien      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
459050615Sobrien	{
459152558Sobrien	  const char * description = documented_lang_options[i].description;
459252558Sobrien	  const char * option      = documented_lang_options[i].option;
459350615Sobrien
459450615Sobrien	  if (description == NULL)
459552558Sobrien	    {
459652558Sobrien	      undoc = 1;
459752558Sobrien
459852558Sobrien	      if (extra_warnings)
459952558Sobrien		printf ("  %-23.23s [undocumented]\n", option);
460052558Sobrien	    }
460150615Sobrien	  else if (* description == 0)
460250615Sobrien	    continue;
460350615Sobrien	  else if (option == NULL)
460450615Sobrien	    {
460550615Sobrien	      if (undoc)
460650615Sobrien		printf
460750615Sobrien		  ("\nThere are undocumented %s specific options as well.\n",
460850615Sobrien			lang);
460950615Sobrien	      undoc = 0;
461050615Sobrien
461150615Sobrien	      printf ("\n Options for %s:\n", description);
461250615Sobrien
461350615Sobrien	      lang = description;
461450615Sobrien	    }
461550615Sobrien	  else
461650615Sobrien	    printf ("  %-23.23s %s\n", option, description);
461750615Sobrien	}
461850615Sobrien    }
461950615Sobrien
462050615Sobrien  if (undoc)
462150615Sobrien    printf ("\nThere are undocumented %s specific options as well.\n", lang);
462250615Sobrien
462350615Sobrien  if (NUM_ELEM (target_switches) > 1
462450615Sobrien#ifdef TARGET_OPTIONS
462550615Sobrien      || NUM_ELEM (target_options) > 1
462650615Sobrien#endif
462750615Sobrien      )
462850615Sobrien    {
462950615Sobrien      int doc = 0;
463050615Sobrien
463150615Sobrien      undoc = 0;
463250615Sobrien
463350615Sobrien      printf ("\nTarget specific options:\n");
463450615Sobrien
463550615Sobrien      for (i = NUM_ELEM (target_switches); i--;)
463650615Sobrien	{
463752558Sobrien	  const char * option      = target_switches[i].name;
463852558Sobrien	  const char * description = target_switches[i].description;
463950615Sobrien
464052558Sobrien	  if (option == NULL || * option == 0)
464150615Sobrien	    continue;
464250615Sobrien	  else if (description == NULL)
464352558Sobrien	    {
464452558Sobrien	      undoc = 1;
464552558Sobrien
464652558Sobrien	      if (extra_warnings)
464752558Sobrien		printf ("  -m%-21.21s [undocumented]\n", option);
464852558Sobrien	    }
464950615Sobrien	  else if (* description != 0)
465052558Sobrien	    doc += printf ("  -m%-21.21s %s\n", option, description);
465150615Sobrien	}
465250615Sobrien
465350615Sobrien#ifdef TARGET_OPTIONS
465450615Sobrien      for (i = NUM_ELEM (target_options); i--;)
465550615Sobrien	{
465652558Sobrien	  const char * option      = target_options[i].prefix;
465752558Sobrien	  const char * description = target_options[i].description;
465850615Sobrien
465952558Sobrien	  if (option == NULL || * option == 0)
466050615Sobrien	    continue;
466150615Sobrien	  else if (description == NULL)
466252558Sobrien	    {
466352558Sobrien	      undoc = 1;
466452558Sobrien
466552558Sobrien	      if (extra_warnings)
466652558Sobrien		printf ("  -m%-21.21s [undocumented]\n", option);
466752558Sobrien	    }
466850615Sobrien	  else if (* description != 0)
466952558Sobrien	    doc += printf ("  -m%-21.21s %s\n", option, description);
467050615Sobrien	}
467150615Sobrien#endif
467250615Sobrien      if (undoc)
467352558Sobrien	{
467452558Sobrien	  if (doc)
467552558Sobrien	    printf ("\nThere are undocumented target specific options as well.\n");
467652558Sobrien	  else
467752558Sobrien	    printf ("  They exist, but they are not documented.\n");
467852558Sobrien	}
467950615Sobrien    }
468050615Sobrien}
468150615Sobrien
468250615Sobrien/* Compare the user specified 'option' with the language
468350615Sobrien   specific 'lang_option'.  Return true if they match, or
468450615Sobrien   if 'option' is a viable prefix of 'lang_option'.  */
468550615Sobrien
468650615Sobrienstatic int
468750615Sobriencheck_lang_option (option, lang_option)
468850615Sobrien     char * option;
468950615Sobrien     char * lang_option;
469050615Sobrien{
469150615Sobrien  lang_independent_options * indep_options;
469250615Sobrien  int    len;
469350615Sobrien  long    k;
469452558Sobrien  char * space;
469552558Sobrien
469650615Sobrien  /* Ignore NULL entries.  */
469750615Sobrien  if (option == NULL || lang_option == NULL)
469850615Sobrien    return 0;
469950615Sobrien
470052558Sobrien  if ((space = strchr (lang_option, ' ')) != NULL)
470152558Sobrien    len = space - lang_option;
470252558Sobrien  else
470352558Sobrien    len = strlen (lang_option);
470452558Sobrien
470550615Sobrien  /* If they do not match to the first n characters then fail.  */
470650615Sobrien  if (strncmp (option, lang_option, len) != 0)
470750615Sobrien    return 0;
470852558Sobrien
470950615Sobrien  /* Do not accept a lang option, if it matches a normal -f or -W
471050615Sobrien     option.  Chill defines a -fpack, but we want to support
471150615Sobrien     -fpack-struct.  */
471252558Sobrien
471350615Sobrien  /* An exact match is OK  */
471452558Sobrien  if ((int) strlen (option) == len)
471550615Sobrien    return 1;
471652558Sobrien
471750615Sobrien  /* If it is not an -f or -W option allow the match */
471850615Sobrien  if (option[0] != '-')
471950615Sobrien    return 1;
472052558Sobrien
472150615Sobrien  switch (option[1])
472250615Sobrien    {
472350615Sobrien    case 'f': indep_options = f_options; break;
472450615Sobrien    case 'W': indep_options = W_options; break;
472550615Sobrien    default:  return 1;
472650615Sobrien    }
472752558Sobrien
472850615Sobrien  /* The option is a -f or -W option.
472950615Sobrien     Skip past the prefix and search for the remainder in the
473050615Sobrien     appropriate table of options.  */
473150615Sobrien  option += 2;
473252558Sobrien
473350615Sobrien  if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
473450615Sobrien    option += 3;
473552558Sobrien
473650615Sobrien  for (k = NUM_ELEM (indep_options); k--;)
473750615Sobrien    {
473850615Sobrien      if (!strcmp (option, indep_options[k].string))
473950615Sobrien	{
474050615Sobrien	  /* The option matched a language independent option,
474150615Sobrien	     do not allow the language specific match.  */
474252558Sobrien
474350615Sobrien	  return 0;
474450615Sobrien	}
474550615Sobrien    }
474652558Sobrien
474750615Sobrien  /* The option matches the start of the langauge specific option
474850615Sobrien     and it is not an exact match for a language independent option.  */
474950615Sobrien  return 1;
475050615Sobrien}
475150615Sobrien
475218334Speter/* Entry point of cc1/c++.  Decode command args, then call compile_file.
475318334Speter   Exit code is 35 if can't open files, 34 if fatal error,
475418334Speter   33 if had nonfatal errors, else success.  */
475518334Speter
475618334Speterint
475752558Sobrienmain (argc, argv)
475818334Speter     int argc;
475918334Speter     char **argv;
476018334Speter{
476118334Speter  register int i;
476218334Speter  char *filename = 0;
476318334Speter  int flag_print_mem = 0;
476418334Speter  int version_flag = 0;
476518334Speter  char *p;
476618334Speter
476718334Speter  /* save in case md file wants to emit args as a comment.  */
476818334Speter  save_argc = argc;
476918334Speter  save_argv = argv;
477018334Speter
477118334Speter  p = argv[0] + strlen (argv[0]);
477218334Speter  while (p != argv[0] && p[-1] != '/'
477318334Speter#ifdef DIR_SEPARATOR
477418334Speter	 && p[-1] != DIR_SEPARATOR
477518334Speter#endif
477618334Speter	 )
477718334Speter    --p;
477818334Speter  progname = p;
477918334Speter
478050615Sobrien#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
478118334Speter  /* Get rid of any avoidable limit on stack size.  */
478218334Speter  {
478318334Speter    struct rlimit rlim;
478418334Speter
478550615Sobrien    /* Set the stack limit huge so that alloca does not fail.  */
478618334Speter    getrlimit (RLIMIT_STACK, &rlim);
478718334Speter    rlim.rlim_cur = rlim.rlim_max;
478818334Speter    setrlimit (RLIMIT_STACK, &rlim);
478918334Speter  }
479050615Sobrien#endif
479118334Speter
479252558Sobrien#ifdef HAVE_LC_MESSAGES
479352558Sobrien  setlocale (LC_MESSAGES, "");
479452558Sobrien#endif
479552558Sobrien  (void) bindtextdomain (PACKAGE, localedir);
479652558Sobrien  (void) textdomain (PACKAGE);
479752558Sobrien
479818334Speter  signal (SIGFPE, float_signal);
479918334Speter
480018334Speter#ifdef SIGPIPE
480118334Speter  signal (SIGPIPE, pipe_closed);
480218334Speter#endif
480318334Speter
480418334Speter  decl_printable_name = decl_name;
480552558Sobrien  lang_expand_expr = (lang_expand_expr_t) do_abort;
480618334Speter
480718334Speter  /* Initialize whether `char' is signed.  */
480818334Speter  flag_signed_char = DEFAULT_SIGNED_CHAR;
480918334Speter#ifdef DEFAULT_SHORT_ENUMS
481018334Speter  /* Initialize how much space enums occupy, by default.  */
481118334Speter  flag_short_enums = DEFAULT_SHORT_ENUMS;
481218334Speter#endif
481318334Speter
481450615Sobrien  /* Perform language-specific options intialization.  */
481550615Sobrien  lang_init_options ();
481650615Sobrien
481718334Speter  /* Scan to see what optimization level has been specified.  That will
481818334Speter     determine the default value of many flags.  */
481918334Speter  for (i = 1; i < argc; i++)
482018334Speter    {
482118334Speter      if (!strcmp (argv[i], "-O"))
482218334Speter	{
482318334Speter	  optimize = 1;
482452558Sobrien	  optimize_size = 0;
482518334Speter	}
482618334Speter      else if (argv[i][0] == '-' && argv[i][1] == 'O')
482718334Speter	{
482850615Sobrien	  /* Handle -Os, -O2, -O3, -O69, ...  */
482918334Speter	  char *p = &argv[i][2];
483050615Sobrien
483150615Sobrien	  if ((p[0] == 's') && (p[1] == 0))
483252558Sobrien	    {
483352558Sobrien	      optimize_size = 1;
483452558Sobrien
483552558Sobrien	      /* Optimizing for size forces optimize to be 2. */
483652558Sobrien	      optimize = 2;
483752558Sobrien	    }
483850615Sobrien	  else
483950615Sobrien	    {
484052558Sobrien	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
484152558Sobrien	      if (optimize_val != -1)
484252558Sobrien		{
484352558Sobrien		  optimize = optimize_val;
484452558Sobrien		  optimize_size = 0;
484552558Sobrien		}
484650615Sobrien	    }
484718334Speter	}
484818334Speter    }
484918334Speter
485018334Speter  obey_regdecls = (optimize == 0);
485118334Speter
485218334Speter  if (optimize >= 1)
485318334Speter    {
485418334Speter      flag_defer_pop = 1;
485518334Speter      flag_thread_jumps = 1;
485618334Speter#ifdef DELAY_SLOTS
485718334Speter      flag_delayed_branch = 1;
485818334Speter#endif
485918334Speter#ifdef CAN_DEBUG_WITHOUT_FP
486018334Speter      flag_omit_frame_pointer = 1;
486118334Speter#endif
486218334Speter    }
486318334Speter
486418334Speter  if (optimize >= 2)
486518334Speter    {
486618334Speter      flag_cse_follow_jumps = 1;
486718334Speter      flag_cse_skip_blocks = 1;
486850615Sobrien      flag_gcse = 1;
486918334Speter      flag_expensive_optimizations = 1;
487018334Speter      flag_strength_reduce = 1;
487118334Speter      flag_rerun_cse_after_loop = 1;
487250615Sobrien      flag_rerun_loop_opt = 1;
487318334Speter      flag_caller_saves = 1;
487418334Speter      flag_force_mem = 1;
487518334Speter#ifdef INSN_SCHEDULING
487618334Speter      flag_schedule_insns = 1;
487718334Speter      flag_schedule_insns_after_reload = 1;
487818334Speter#endif
487950615Sobrien      flag_regmove = 1;
488052558Sobrien      flag_strict_aliasing = 1;
488118334Speter    }
488218334Speter
488318334Speter  if (optimize >= 3)
488418334Speter    {
488518334Speter      flag_inline_functions = 1;
488618334Speter    }
488718334Speter
488850615Sobrien  /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
488950615Sobrien     modify it.  */
489050615Sobrien  target_flags = 0;
489150615Sobrien  set_target_switch ("");
489250615Sobrien
489318334Speter#ifdef OPTIMIZATION_OPTIONS
489418334Speter  /* Allow default optimizations to be specified on a per-machine basis.  */
489550615Sobrien  OPTIMIZATION_OPTIONS (optimize, optimize_size);
489618334Speter#endif
489718334Speter
489818334Speter  /* Initialize register usage now so switches may override.  */
489918334Speter  init_reg_sets ();
490018334Speter
490118334Speter  for (i = 1; i < argc; i++)
490218334Speter    {
490350615Sobrien      size_t j;
490450615Sobrien
490518334Speter      /* If this is a language-specific option,
490618334Speter	 decode it in a language-specific way.  */
490750615Sobrien      for (j = NUM_ELEM (documented_lang_options); j--;)
490850615Sobrien	if (check_lang_option (argv[i], documented_lang_options[j].option))
490918334Speter	  break;
491050615Sobrien
491152558Sobrien      if (j != (size_t)-1)
491250615Sobrien	{
491350615Sobrien	  /* If the option is valid for *some* language,
491450615Sobrien	     treat it as valid even if this language doesn't understand it.  */
491550615Sobrien	  int strings_processed = lang_decode_option (argc - i, argv + i);
491650615Sobrien
491750615Sobrien	  if (!strcmp (argv[i], "--help"))
491850615Sobrien	    {
491950615Sobrien	      display_help ();
492050615Sobrien	      exit (0);
492150615Sobrien	    }
492250615Sobrien
492350615Sobrien	  if (strings_processed != 0)
492450615Sobrien	    i += strings_processed - 1;
492550615Sobrien	}
492618334Speter      else if (argv[i][0] == '-' && argv[i][1] != 0)
492718334Speter	{
492818334Speter	  register char *str = argv[i] + 1;
492918334Speter	  if (str[0] == 'Y')
493018334Speter	    str++;
493118334Speter
493218334Speter	  if (str[0] == 'm')
493318334Speter	    set_target_switch (&str[1]);
493418334Speter	  else if (!strcmp (str, "dumpbase"))
493518334Speter	    {
493618334Speter	      dump_base_name = argv[++i];
493718334Speter	    }
493818334Speter	  else if (str[0] == 'd')
493918334Speter	    {
494018334Speter	      register char *p = &str[1];
494118334Speter	      while (*p)
494218334Speter		switch (*p++)
494318334Speter		  {
494418334Speter 		  case 'a':
494550615Sobrien		    branch_prob_dump = 1;
494618334Speter 		    combine_dump = 1;
494750615Sobrien#ifdef DELAY_SLOTS
494818334Speter 		    dbr_sched_dump = 1;
494950615Sobrien#endif
495018334Speter 		    flow_dump = 1;
495152558Sobrien 		    flow2_dump = 1;
495218334Speter 		    global_reg_dump = 1;
495318334Speter 		    jump_opt_dump = 1;
495450615Sobrien 		    addressof_dump = 1;
495518334Speter 		    jump2_opt_dump = 1;
495618334Speter 		    local_reg_dump = 1;
495718334Speter 		    loop_dump = 1;
495850615Sobrien		    regmove_dump = 1;
495918334Speter 		    rtl_dump = 1;
496018334Speter 		    cse_dump = 1, cse2_dump = 1;
496150615Sobrien		    gcse_dump = 1;
496218334Speter 		    sched_dump = 1;
496318334Speter 		    sched2_dump = 1;
496450615Sobrien#ifdef STACK_REGS
496518334Speter		    stack_reg_dump = 1;
496650615Sobrien#endif
496750615Sobrien#ifdef MACHINE_DEPENDENT_REORG
496850615Sobrien		    mach_dep_reorg_dump = 1;
496950615Sobrien#endif
497018334Speter		    break;
497150615Sobrien		  case 'A':
497250615Sobrien		    flag_debug_asm = 1;
497318334Speter		    break;
497450615Sobrien		  case 'b':
497550615Sobrien		    branch_prob_dump = 1;
497650615Sobrien		    break;
497718334Speter		  case 'c':
497818334Speter		    combine_dump = 1;
497918334Speter		    break;
498050615Sobrien#ifdef DELAY_SLOTS
498118334Speter		  case 'd':
498218334Speter		    dbr_sched_dump = 1;
498318334Speter		    break;
498450615Sobrien#endif
498518334Speter		  case 'f':
498618334Speter		    flow_dump = 1;
498718334Speter		    break;
498850615Sobrien		  case 'F':
498950615Sobrien		    addressof_dump = 1;
499050615Sobrien		    break;
499118334Speter		  case 'g':
499218334Speter		    global_reg_dump = 1;
499318334Speter		    break;
499450615Sobrien		  case 'G':
499550615Sobrien		    gcse_dump = 1;
499650615Sobrien		    break;
499718334Speter		  case 'j':
499818334Speter		    jump_opt_dump = 1;
499918334Speter		    break;
500018334Speter		  case 'J':
500118334Speter		    jump2_opt_dump = 1;
500218334Speter		    break;
500350615Sobrien#ifdef STACK_REGS
500450615Sobrien		  case 'k':
500550615Sobrien		    stack_reg_dump = 1;
500650615Sobrien		    break;
500750615Sobrien#endif
500818334Speter		  case 'l':
500918334Speter		    local_reg_dump = 1;
501018334Speter		    break;
501118334Speter		  case 'L':
501218334Speter		    loop_dump = 1;
501318334Speter		    break;
501418334Speter		  case 'm':
501518334Speter		    flag_print_mem = 1;
501618334Speter		    break;
501750615Sobrien#ifdef MACHINE_DEPENDENT_REORG
501850615Sobrien		  case 'M':
501950615Sobrien		    mach_dep_reorg_dump = 1;
502050615Sobrien		    break;
502150615Sobrien#endif
502218334Speter		  case 'p':
502318334Speter		    flag_print_asm_name = 1;
502418334Speter		    break;
502518334Speter		  case 'r':
502618334Speter		    rtl_dump = 1;
502718334Speter		    break;
502850615Sobrien		  case 'R':
502950615Sobrien		    sched2_dump = 1;
503050615Sobrien		    break;
503118334Speter		  case 's':
503218334Speter		    cse_dump = 1;
503318334Speter		    break;
503450615Sobrien		  case 'S':
503550615Sobrien		    sched_dump = 1;
503650615Sobrien		    break;
503718334Speter		  case 't':
503818334Speter		    cse2_dump = 1;
503918334Speter		    break;
504050615Sobrien		  case 'N':
504150615Sobrien		    regmove_dump = 1;
504218334Speter		    break;
504352558Sobrien		  case 'v':
504452558Sobrien		    graph_dump_format = vcg;
504552558Sobrien		    break;
504652558Sobrien		  case 'w':
504752558Sobrien		    flow2_dump = 1;
504852558Sobrien		    break;
504918334Speter		  case 'y':
505018334Speter		    set_yydebug (1);
505118334Speter		    break;
505218334Speter		  case 'x':
505318334Speter		    rtl_dump_and_exit = 1;
505418334Speter		    break;
505552558Sobrien		  case 'D':	/* these are handled by the preprocessor */
505652558Sobrien		  case 'I':
505752558Sobrien		    break;
505850615Sobrien		  default:
505950615Sobrien		    warning ("unrecognised gcc debugging option: %c", p[-1]);
506050615Sobrien		    break;
506118334Speter		  }
506218334Speter	    }
506318334Speter	  else if (str[0] == 'f')
506418334Speter	    {
506518334Speter	      register char *p = &str[1];
506618334Speter	      int found = 0;
506718334Speter
506818334Speter	      /* Some kind of -f option.
506918334Speter		 P's value is the option sans `-f'.
507018334Speter		 Search for it in the table of options.  */
507118334Speter
507218334Speter	      for (j = 0;
507318334Speter		   !found && j < sizeof (f_options) / sizeof (f_options[0]);
507418334Speter		   j++)
507518334Speter		{
507618334Speter		  if (!strcmp (p, f_options[j].string))
507718334Speter		    {
507818334Speter		      *f_options[j].variable = f_options[j].on_value;
507918334Speter		      /* A goto here would be cleaner,
508018334Speter			 but breaks the vax pcc.  */
508118334Speter		      found = 1;
508218334Speter		    }
508318334Speter		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
508418334Speter		      && ! strcmp (p+3, f_options[j].string))
508518334Speter		    {
508618334Speter		      *f_options[j].variable = ! f_options[j].on_value;
508718334Speter		      found = 1;
508818334Speter		    }
508918334Speter		}
509018334Speter
509118334Speter	      if (found)
509218334Speter		;
509352558Sobrien	      else if (!strncmp (p, "inline-limit-", 13))
509452558Sobrien	        inline_max_insns =
509552558Sobrien		  read_integral_parameter (p + 13, p - 2, inline_max_insns);
509650615Sobrien#ifdef HAIFA
509750615Sobrien#ifdef INSN_SCHEDULING
509850615Sobrien	      else if (!strncmp (p, "sched-verbose-",14))
509950615Sobrien		fix_sched_param("verbose",&p[14]);
510050615Sobrien#endif
510150615Sobrien#endif  /* HAIFA */
510218334Speter	      else if (!strncmp (p, "fixed-", 6))
510318334Speter		fix_register (&p[6], 1, 1);
510418334Speter	      else if (!strncmp (p, "call-used-", 10))
510518334Speter		fix_register (&p[10], 0, 1);
510618334Speter	      else if (!strncmp (p, "call-saved-", 11))
510718334Speter		fix_register (&p[11], 0, 0);
510818334Speter	      else
510918334Speter		error ("Invalid option `%s'", argv[i]);
511018334Speter	    }
511118334Speter	  else if (str[0] == 'O')
511218334Speter	    {
511352558Sobrien	      /* Already been treated above. Do nothing.  */
511418334Speter	    }
511518334Speter	  else if (!strcmp (str, "pedantic"))
511618334Speter	    pedantic = 1;
511718334Speter	  else if (!strcmp (str, "pedantic-errors"))
511818334Speter	    flag_pedantic_errors = pedantic = 1;
511918334Speter	  else if (!strcmp (str, "quiet"))
512018334Speter	    quiet_flag = 1;
512118334Speter	  else if (!strcmp (str, "version"))
512218334Speter	    version_flag = 1;
512318334Speter	  else if (!strcmp (str, "w"))
512418334Speter	    inhibit_warnings = 1;
512518334Speter	  else if (!strcmp (str, "W"))
512618334Speter	    {
512718334Speter	      extra_warnings = 1;
512818334Speter	      /* We save the value of warn_uninitialized, since if they put
512918334Speter		 -Wuninitialized on the command line, we need to generate a
513018334Speter		 warning about not using it without also specifying -O.  */
513118334Speter	      if (warn_uninitialized != 1)
513218334Speter		warn_uninitialized = 2;
513318334Speter	    }
513418334Speter	  else if (str[0] == 'W')
513518334Speter	    {
513618334Speter	      register char *p = &str[1];
513718334Speter	      int found = 0;
513818334Speter
513918334Speter	      /* Some kind of -W option.
514018334Speter		 P's value is the option sans `-W'.
514118334Speter		 Search for it in the table of options.  */
514218334Speter
514318334Speter	      for (j = 0;
514418334Speter		   !found && j < sizeof (W_options) / sizeof (W_options[0]);
514518334Speter		   j++)
514618334Speter		{
514718334Speter		  if (!strcmp (p, W_options[j].string))
514818334Speter		    {
514918334Speter		      *W_options[j].variable = W_options[j].on_value;
515018334Speter		      /* A goto here would be cleaner,
515118334Speter			 but breaks the vax pcc.  */
515218334Speter		      found = 1;
515318334Speter		    }
515418334Speter		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
515518334Speter		      && ! strcmp (p+3, W_options[j].string))
515618334Speter		    {
515718334Speter		      *W_options[j].variable = ! W_options[j].on_value;
515818334Speter		      found = 1;
515918334Speter		    }
516018334Speter		}
516118334Speter
516218334Speter	      if (found)
516318334Speter		;
516418334Speter	      else if (!strncmp (p, "id-clash-", 9))
516518334Speter		{
516652558Sobrien		  const int id_clash_val
516752558Sobrien		    = read_integral_parameter (p + 9, p - 2, -1);
516852558Sobrien		  if (id_clash_val != -1)
516918334Speter		    {
517052558Sobrien		      id_clash_len = id_clash_val;
517152558Sobrien		      warn_id_clash = 1;
517218334Speter		    }
517318334Speter		}
517418334Speter	      else if (!strncmp (p, "larger-than-", 12))
517518334Speter		{
517652558Sobrien		  const int larger_than_val
517752558Sobrien		    = read_integral_parameter (p + 12, p - 2, -1);
517852558Sobrien		  if (larger_than_val != -1)
517918334Speter		    {
518052558Sobrien		      larger_than_size = larger_than_val;
518152558Sobrien		      warn_larger_than = 1;
518218334Speter		    }
518318334Speter		}
518418334Speter	      else
518518334Speter		error ("Invalid option `%s'", argv[i]);
518618334Speter	    }
518718334Speter	  else if (!strcmp (str, "p"))
518818334Speter	    {
518950615Sobrien	      profile_flag = 1;
519018334Speter	    }
519118334Speter	  else if (!strcmp (str, "a"))
519218334Speter	    {
519318334Speter#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
519418334Speter	      warning ("`-a' option (basic block profile) not supported");
519518334Speter#else
519650615Sobrien              profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
519718334Speter#endif
519818334Speter	    }
519950615Sobrien	  else if (!strcmp (str, "ax"))
520050615Sobrien	    {
520150615Sobrien#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
520250615Sobrien	      warning ("`-ax' option (jump profiling) not supported");
520350615Sobrien#else
520450615Sobrien	      profile_block_flag = (!profile_block_flag
520550615Sobrien	                               || profile_block_flag == 2) ? 2 : 3;
520650615Sobrien#endif
520750615Sobrien	    }
520818334Speter	  else if (str[0] == 'g')
520918334Speter	    {
521018334Speter	      unsigned level;
521150615Sobrien	      /* A lot of code assumes write_symbols == NO_DEBUG if the
521250615Sobrien		 debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
521350615Sobrien		 of what debugging type has been selected).  This records the
521450615Sobrien		 selected type.  It is an error to specify more than one
521550615Sobrien		 debugging type.  */
521650615Sobrien	      static enum debug_info_type selected_debug_type = NO_DEBUG;
521750615Sobrien	      /* Non-zero if debugging format has been explicitly set.
521850615Sobrien		 -g and -ggdb don't explicitly set the debugging format so
521950615Sobrien		 -gdwarf -g3 is equivalent to -gdwarf3.  */
522050615Sobrien	      static int type_explicitly_set_p = 0;
522150615Sobrien	      /* Indexed by enum debug_info_type.  */
522252558Sobrien	      static const char *debug_type_names[] =
522350615Sobrien	      {
522450615Sobrien		"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
522550615Sobrien	      };
522618334Speter
522752558Sobrien	      /* The maximum admissible debug level value.  */
522852558Sobrien	      static const unsigned max_debug_level = 3;
522952558Sobrien
523050615Sobrien	      /* Look up STR in the table.  */
523150615Sobrien	      for (da = debug_args; da->arg; da++)
523218334Speter		{
523352558Sobrien		  const int da_len = strlen (da->arg);
523452558Sobrien
523552558Sobrien		  if (! strncmp (str, da->arg, da_len))
523650615Sobrien		    {
523750615Sobrien		      enum debug_info_type type = da->debug_type;
523852558Sobrien		      const char *p = str + da_len;
523918334Speter
524050615Sobrien		      if (*p && (*p < '0' || *p > '9'))
524150615Sobrien			continue;
524252558Sobrien
524352558Sobrien		      /* A debug flag without a level defaults to level 2.
524452558Sobrien			 Note we do not want to call read_integral_parameter
524552558Sobrien			 for that case since it will call atoi which
524652558Sobrien			 will return zero.
524752558Sobrien
524852558Sobrien			 ??? We may want to generalize the interface to
524952558Sobrien			 read_integral_parameter to better handle this case
525052558Sobrien			 if this case shows up often.  */
525150615Sobrien		      if (*p)
525252558Sobrien			level = read_integral_parameter (p, 0,
525352558Sobrien							 max_debug_level + 1);
525452558Sobrien		      else
525552558Sobrien			level = 2;
525652558Sobrien
525752558Sobrien		      if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
525850615Sobrien			{
525952558Sobrien			  error ("use -gdwarf -g%d for DWARF v1, level %d",
526052558Sobrien				 level, level);
526152558Sobrien			  if (level == 2)
526252558Sobrien			    error ("use -gdwarf-2   for DWARF v2");
526350615Sobrien			}
526452558Sobrien
526552558Sobrien		      if (level > max_debug_level)
526650615Sobrien			{
526752558Sobrien			  warning ("ignoring option `%s' due to invalid debug level specification",
526852558Sobrien				   str - 1);
526952558Sobrien			  level = debug_info_level;
527050615Sobrien			}
527150615Sobrien
527250615Sobrien		      if (type == NO_DEBUG)
527350615Sobrien			{
527450615Sobrien			  type = PREFERRED_DEBUGGING_TYPE;
527552558Sobrien			  if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
527650615Sobrien			    {
527750615Sobrien#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
527850615Sobrien			      type = DWARF2_DEBUG;
527950615Sobrien#else
528018334Speter#ifdef DBX_DEBUGGING_INFO
528150615Sobrien			      type = DBX_DEBUG;
528250615Sobrien#endif
528350615Sobrien#endif
528450615Sobrien			    }
528550615Sobrien			}
528618334Speter
528750615Sobrien		      if (type == NO_DEBUG)
528850615Sobrien			warning ("`-%s' not supported by this configuration of GCC",
528950615Sobrien				 str);
529018334Speter
529150615Sobrien		      /* Does it conflict with an already selected type?  */
529250615Sobrien		      if (type_explicitly_set_p
529350615Sobrien			  /* -g/-ggdb don't conflict with anything */
529450615Sobrien			  && da->debug_type != NO_DEBUG
529550615Sobrien			  && type != selected_debug_type)
529650615Sobrien			warning ("`-%s' ignored, conflicts with `-g%s'",
529750615Sobrien				 str, debug_type_names[(int) selected_debug_type]);
529850615Sobrien		      else
529950615Sobrien			{
530050615Sobrien			  /* If the format has already been set, -g/-ggdb
530150615Sobrien			     only change the debug level.  */
530250615Sobrien			  if (type_explicitly_set_p
530350615Sobrien			      && da->debug_type == NO_DEBUG)
530450615Sobrien			    ; /* don't change debugging type */
530550615Sobrien			  else
530650615Sobrien			    {
530750615Sobrien			      selected_debug_type = type;
530850615Sobrien			      type_explicitly_set_p = da->debug_type != NO_DEBUG;
530950615Sobrien			    }
531050615Sobrien			  write_symbols = (level == 0
531150615Sobrien					   ? NO_DEBUG
531250615Sobrien					   : selected_debug_type);
531350615Sobrien			  use_gnu_debug_info_extensions = da->use_extensions_p;
531450615Sobrien			  debug_info_level = (enum debug_info_level) level;
531550615Sobrien			}
531650615Sobrien		      break;
531750615Sobrien		    }
531850615Sobrien		}
531950615Sobrien	      if (! da->arg)
532018334Speter		warning ("`-%s' not supported by this configuration of GCC",
532118334Speter			 str);
532218334Speter	    }
532318334Speter	  else if (!strcmp (str, "o"))
532418334Speter	    {
532518334Speter	      asm_file_name = argv[++i];
532618334Speter	    }
532718334Speter	  else if (str[0] == 'G')
532818334Speter	    {
532952558Sobrien	      const int g_switch_val = (str[1] != '\0') ?
533052558Sobrien	                               read_integral_parameter(str + 1, 0, -1) :
533152558Sobrien			               read_integral_parameter(argv[++i], 0, -1);
533252558Sobrien
533352558Sobrien	      if (g_switch_val != -1)
533452558Sobrien	        {
533552558Sobrien		  g_switch_set = TRUE;
533652558Sobrien		  g_switch_value = g_switch_val;
533752558Sobrien		}
533852558Sobrien	      else
533952558Sobrien	        {
534052558Sobrien		  error("Invalid option `-%s'",str);
534152558Sobrien		}
534218334Speter	    }
534318334Speter	  else if (!strncmp (str, "aux-info", 8))
534418334Speter	    {
534518334Speter	      flag_gen_aux_info = 1;
534618334Speter	      aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
534718334Speter	    }
534850615Sobrien	  else if (!strcmp (str, "-help"))
534950615Sobrien	    {
535050615Sobrien	      display_help ();
535150615Sobrien	      exit (0);
535250615Sobrien	    }
535318334Speter	  else
535418334Speter	    error ("Invalid option `%s'", argv[i]);
535518334Speter	}
535618334Speter      else if (argv[i][0] == '+')
535718334Speter	error ("Invalid option `%s'", argv[i]);
535818334Speter      else
535918334Speter	filename = argv[i];
536018334Speter    }
536118334Speter
536250615Sobrien  /* Checker uses the frame pointer.  */
536350615Sobrien  if (flag_check_memory_usage)
536450615Sobrien    flag_omit_frame_pointer = 0;
536518334Speter
536618334Speter  if (optimize == 0)
536718334Speter    {
536818334Speter      /* Inlining does not work if not optimizing,
536918334Speter	 so force it not to be done.  */
537018334Speter      flag_no_inline = 1;
537118334Speter      warn_inline = 0;
537218334Speter
537318334Speter      /* The c_decode_option and lang_decode_option functions set
537418334Speter	 this to `2' if -Wall is used, so we can avoid giving out
537518334Speter	 lots of errors for people who don't realize what -Wall does.  */
537618334Speter      if (warn_uninitialized == 1)
537718334Speter	warning ("-Wuninitialized is not supported without -O");
537818334Speter    }
537918334Speter
538018334Speter#ifdef OVERRIDE_OPTIONS
538118334Speter  /* Some machines may reject certain combinations of options.  */
538218334Speter  OVERRIDE_OPTIONS;
538318334Speter#endif
538418334Speter
538550615Sobrien  if (exceptions_via_longjmp == 2)
538650615Sobrien    {
538750615Sobrien#ifdef DWARF2_UNWIND_INFO
538850615Sobrien      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
538950615Sobrien#else
539050615Sobrien      exceptions_via_longjmp = 1;
539150615Sobrien#endif
539250615Sobrien    }
539350615Sobrien
539450615Sobrien  if (profile_block_flag == 3)
539550615Sobrien    {
539650615Sobrien      warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
539750615Sobrien      profile_block_flag = 2;
539850615Sobrien    }
539950615Sobrien
540018334Speter  /* Unrolling all loops implies that standard loop unrolling must also
540118334Speter     be done.  */
540218334Speter  if (flag_unroll_all_loops)
540318334Speter    flag_unroll_loops = 1;
540418334Speter  /* Loop unrolling requires that strength_reduction be on also.  Silently
540518334Speter     turn on strength reduction here if it isn't already on.  Also, the loop
540618334Speter     unrolling code assumes that cse will be run after loop, so that must
540718334Speter     be turned on also.  */
540818334Speter  if (flag_unroll_loops)
540918334Speter    {
541018334Speter      flag_strength_reduce = 1;
541118334Speter      flag_rerun_cse_after_loop = 1;
541218334Speter    }
541318334Speter
541418334Speter  /* Warn about options that are not supported on this machine.  */
541518334Speter#ifndef INSN_SCHEDULING
541618334Speter  if (flag_schedule_insns || flag_schedule_insns_after_reload)
541718334Speter    warning ("instruction scheduling not supported on this target machine");
541818334Speter#endif
541918334Speter#ifndef DELAY_SLOTS
542018334Speter  if (flag_delayed_branch)
542118334Speter    warning ("this target machine does not have delayed branches");
542218334Speter#endif
542318334Speter
542452558Sobrien  user_label_prefix = USER_LABEL_PREFIX;
542552558Sobrien  if (flag_leading_underscore != -1)
542652558Sobrien    {
542752558Sobrien      /* If the default prefix is more complicated than "" or "_",
542852558Sobrien	 issue a warning and ignore this option.  */
542952558Sobrien      if (user_label_prefix[0] == 0 ||
543052558Sobrien	  (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
543152558Sobrien	{
543252558Sobrien	  user_label_prefix = flag_leading_underscore ? "_" : "";
543352558Sobrien	}
543452558Sobrien      else
543552558Sobrien	warning ("-f%sleading-underscore not supported on this target machine",
543652558Sobrien		 flag_leading_underscore ? "" : "no-");
543752558Sobrien    }
543852558Sobrien
543918334Speter  /* If we are in verbose mode, write out the version and maybe all the
544018334Speter     option flags in use.  */
544118334Speter  if (version_flag)
544218334Speter    {
544350615Sobrien      print_version (stderr, "");
544418334Speter      if (! quiet_flag)
544550615Sobrien	print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
544618334Speter    }
544718334Speter
544818334Speter  compile_file (filename);
544918334Speter
545052558Sobrien#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
545118334Speter  if (flag_print_mem)
545218334Speter    {
545318334Speter      char *lim = (char *) sbrk (0);
545418334Speter
545552558Sobrien      notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
545618334Speter      fflush (stderr);
545718334Speter
545850615Sobrien#ifndef __MSDOS__
545918334Speter#ifdef USG
546018334Speter      system ("ps -l 1>&2");
546118334Speter#else /* not USG */
546218334Speter      system ("ps v");
546318334Speter#endif /* not USG */
546450615Sobrien#endif
546518334Speter    }
546652558Sobrien#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
546718334Speter
546818334Speter  if (errorcount)
546918334Speter    exit (FATAL_EXIT_CODE);
547018334Speter  if (sorrycount)
547118334Speter    exit (FATAL_EXIT_CODE);
547218334Speter  exit (SUCCESS_EXIT_CODE);
547318334Speter  return 0;
547418334Speter}
547518334Speter
547618334Speter/* Decode -m switches.  */
547718334Speter/* Decode the switch -mNAME.  */
547818334Speter
547952558Sobrienstatic void
548018334Speterset_target_switch (name)
548152558Sobrien  const char *name;
548218334Speter{
548350615Sobrien  register size_t j;
548452558Sobrien  int valid_target_option = 0;
548518334Speter
548618334Speter  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
548718334Speter    if (!strcmp (target_switches[j].name, name))
548818334Speter      {
548918334Speter	if (target_switches[j].value < 0)
549018334Speter	  target_flags &= ~-target_switches[j].value;
549118334Speter	else
549218334Speter	  target_flags |= target_switches[j].value;
549352558Sobrien	valid_target_option = 1;
549418334Speter      }
549518334Speter
549618334Speter#ifdef TARGET_OPTIONS
549752558Sobrien  if (!valid_target_option)
549818334Speter    for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
549918334Speter      {
550018334Speter	int len = strlen (target_options[j].prefix);
550118334Speter	if (!strncmp (target_options[j].prefix, name, len))
550218334Speter	  {
550318334Speter	    *target_options[j].variable = name + len;
550452558Sobrien	    valid_target_option = 1;
550518334Speter	  }
550618334Speter      }
550718334Speter#endif
550818334Speter
550952558Sobrien  if (!valid_target_option)
551018334Speter    error ("Invalid option `%s'", name);
551118334Speter}
551218334Speter
551350615Sobrien/* Print version information to FILE.
551450615Sobrien   Each line begins with INDENT (for the case where FILE is the
551550615Sobrien   assembler output file).  */
551618334Speter
551752558Sobrienstatic void
551850615Sobrienprint_version (file, indent)
551950615Sobrien     FILE *file;
552052558Sobrien     const char *indent;
552150615Sobrien{
552250615Sobrien#ifndef __VERSION__
552352558Sobrien#define __VERSION__ "[?]"
552450615Sobrien#endif
552552558Sobrien  fnotice (file,
552652558Sobrien#ifdef __GNUC__
552752558Sobrien	   "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
552850615Sobrien#else
552952558Sobrien	   "%s%s%s version %s (%s) compiled by CC.\n"
553050615Sobrien#endif
553152558Sobrien	   , indent, *indent != 0 ? " " : "",
553252558Sobrien	   language_string, version_string, TARGET_NAME, __VERSION__);
553350615Sobrien}
553418334Speter
553550615Sobrien/* Print an option value and return the adjusted position in the line.
553650615Sobrien   ??? We don't handle error returns from fprintf (disk full); presumably
553750615Sobrien   other code will catch a disk full though.  */
553818334Speter
553952558Sobrienstatic int
554050615Sobrienprint_single_switch (file, pos, max, indent, sep, term, type, name)
554150615Sobrien     FILE *file;
554250615Sobrien     int pos, max;
554352558Sobrien     const char *indent, *sep, *term, *type, *name;
554418334Speter{
554550615Sobrien  /* The ultrix fprintf returns 0 on success, so compute the result we want
554650615Sobrien     here since we need it for the following test.  */
554750615Sobrien  int len = strlen (sep) + strlen (type) + strlen (name);
554818334Speter
554950615Sobrien  if (pos != 0
555050615Sobrien      && pos + len > max)
555118334Speter    {
555250615Sobrien      fprintf (file, "%s", term);
555350615Sobrien      pos = 0;
555418334Speter    }
555550615Sobrien  if (pos == 0)
555650615Sobrien    {
555750615Sobrien      fprintf (file, "%s", indent);
555850615Sobrien      pos = strlen (indent);
555950615Sobrien    }
556050615Sobrien  fprintf (file, "%s%s%s", sep, type, name);
556150615Sobrien  pos += len;
556250615Sobrien  return pos;
556318334Speter}
556418334Speter
556550615Sobrien/* Print active target switches to FILE.
556650615Sobrien   POS is the current cursor position and MAX is the size of a "line".
556750615Sobrien   Each line begins with INDENT and ends with TERM.
556850615Sobrien   Each switch is separated from the next by SEP.  */
556918334Speter
557052558Sobrienstatic void
557150615Sobrienprint_switch_values (file, pos, max, indent, sep, term)
557250615Sobrien     FILE *file;
557350615Sobrien     int pos, max;
557452558Sobrien     const char *indent, *sep, *term;
557518334Speter{
557650615Sobrien  size_t j;
557750615Sobrien  char **p;
557818334Speter
557950615Sobrien  /* Print the options as passed.  */
558018334Speter
558150615Sobrien  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
558252558Sobrien			     _("options passed: "), "");
558350615Sobrien
558450615Sobrien  for (p = &save_argv[1]; *p != NULL; p++)
558550615Sobrien    if (**p == '-')
558650615Sobrien      {
558750615Sobrien	/* Ignore these.  */
558850615Sobrien	if (strcmp (*p, "-o") == 0)
558950615Sobrien	  {
559050615Sobrien	    if (p[1] != NULL)
559150615Sobrien	      p++;
559250615Sobrien	    continue;
559350615Sobrien	  }
559450615Sobrien	if (strcmp (*p, "-quiet") == 0)
559550615Sobrien	  continue;
559650615Sobrien	if (strcmp (*p, "-version") == 0)
559750615Sobrien	  continue;
559850615Sobrien	if ((*p)[1] == 'd')
559950615Sobrien	  continue;
560050615Sobrien
560150615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
560250615Sobrien      }
560350615Sobrien  if (pos > 0)
560450615Sobrien    fprintf (file, "%s", term);
560550615Sobrien
560650615Sobrien  /* Print the -f and -m options that have been enabled.
560750615Sobrien     We don't handle language specific options but printing argv
560850615Sobrien     should suffice.  */
560950615Sobrien
561050615Sobrien  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
561152558Sobrien			     _("options enabled: "), "");
561250615Sobrien
561318334Speter  for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
561418334Speter    if (*f_options[j].variable == f_options[j].on_value)
561550615Sobrien      pos = print_single_switch (file, pos, max, indent, sep, term,
561650615Sobrien				 "-f", f_options[j].string);
561718334Speter
561850615Sobrien  /* Print target specific options.  */
561918334Speter
562018334Speter  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
562118334Speter    if (target_switches[j].name[0] != '\0'
562218334Speter	&& target_switches[j].value > 0
562318334Speter	&& ((target_switches[j].value & target_flags)
562418334Speter	    == target_switches[j].value))
562550615Sobrien      {
562650615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term,
562750615Sobrien				   "-m", target_switches[j].name);
562850615Sobrien      }
562918334Speter
563050615Sobrien#ifdef TARGET_OPTIONS
563150615Sobrien  for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
563250615Sobrien    if (*target_options[j].variable != NULL)
563350615Sobrien      {
563450615Sobrien	char prefix[256];
563550615Sobrien	sprintf (prefix, "-m%s", target_options[j].prefix);
563650615Sobrien	pos = print_single_switch (file, pos, max, indent, sep, term,
563750615Sobrien				   prefix, *target_options[j].variable);
563850615Sobrien      }
563950615Sobrien#endif
564050615Sobrien
564150615Sobrien  fprintf (file, "%s", term);
564218334Speter}
564350615Sobrien
564450615Sobrien/* Record the beginning of a new source file, named FILENAME.  */
564550615Sobrien
564650615Sobrienvoid
564750615Sobriendebug_start_source_file (filename)
564852558Sobrien     register char *filename ATTRIBUTE_UNUSED;
564950615Sobrien{
565050615Sobrien#ifdef DBX_DEBUGGING_INFO
565150615Sobrien  if (write_symbols == DBX_DEBUG)
565250615Sobrien    dbxout_start_new_source_file (filename);
565350615Sobrien#endif
565450615Sobrien#ifdef DWARF_DEBUGGING_INFO
565550615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
565650615Sobrien      && write_symbols == DWARF_DEBUG)
565750615Sobrien    dwarfout_start_new_source_file (filename);
565850615Sobrien#endif /* DWARF_DEBUGGING_INFO */
565950615Sobrien#ifdef DWARF2_DEBUGGING_INFO
566050615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
566150615Sobrien      && write_symbols == DWARF2_DEBUG)
566250615Sobrien    dwarf2out_start_source_file (filename);
566350615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
566450615Sobrien#ifdef SDB_DEBUGGING_INFO
566550615Sobrien  if (write_symbols == SDB_DEBUG)
566650615Sobrien    sdbout_start_new_source_file (filename);
566750615Sobrien#endif
566850615Sobrien}
566950615Sobrien
567050615Sobrien/* Record the resumption of a source file.  LINENO is the line number in
567150615Sobrien   the source file we are returning to.  */
567250615Sobrien
567350615Sobrienvoid
567450615Sobriendebug_end_source_file (lineno)
567552558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
567650615Sobrien{
567750615Sobrien#ifdef DBX_DEBUGGING_INFO
567850615Sobrien  if (write_symbols == DBX_DEBUG)
567950615Sobrien    dbxout_resume_previous_source_file ();
568050615Sobrien#endif
568150615Sobrien#ifdef DWARF_DEBUGGING_INFO
568250615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
568350615Sobrien      && write_symbols == DWARF_DEBUG)
568450615Sobrien    dwarfout_resume_previous_source_file (lineno);
568550615Sobrien#endif /* DWARF_DEBUGGING_INFO */
568650615Sobrien#ifdef DWARF2_DEBUGGING_INFO
568750615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
568850615Sobrien      && write_symbols == DWARF2_DEBUG)
568950615Sobrien    dwarf2out_end_source_file ();
569050615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
569150615Sobrien#ifdef SDB_DEBUGGING_INFO
569250615Sobrien  if (write_symbols == SDB_DEBUG)
569350615Sobrien    sdbout_resume_previous_source_file ();
569450615Sobrien#endif
569550615Sobrien}
569650615Sobrien
569750615Sobrien/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
569850615Sobrien   the tail part of the directive line, i.e. the part which is past the
569950615Sobrien   initial whitespace, #, whitespace, directive-name, whitespace part.  */
570050615Sobrien
570150615Sobrienvoid
570250615Sobriendebug_define (lineno, buffer)
570352558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
570452558Sobrien     register char *buffer ATTRIBUTE_UNUSED;
570550615Sobrien{
570650615Sobrien#ifdef DWARF_DEBUGGING_INFO
570750615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
570850615Sobrien      && write_symbols == DWARF_DEBUG)
570950615Sobrien    dwarfout_define (lineno, buffer);
571050615Sobrien#endif /* DWARF_DEBUGGING_INFO */
571150615Sobrien#ifdef DWARF2_DEBUGGING_INFO
571250615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
571350615Sobrien      && write_symbols == DWARF2_DEBUG)
571450615Sobrien    dwarf2out_define (lineno, buffer);
571550615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
571650615Sobrien}
571750615Sobrien
571850615Sobrien/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
571950615Sobrien   the tail part of the directive line, i.e. the part which is past the
572050615Sobrien   initial whitespace, #, whitespace, directive-name, whitespace part.  */
572150615Sobrien
572250615Sobrienvoid
572350615Sobriendebug_undef (lineno, buffer)
572452558Sobrien     register unsigned lineno ATTRIBUTE_UNUSED;
572552558Sobrien     register char *buffer ATTRIBUTE_UNUSED;
572650615Sobrien{
572750615Sobrien#ifdef DWARF_DEBUGGING_INFO
572850615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
572950615Sobrien      && write_symbols == DWARF_DEBUG)
573050615Sobrien    dwarfout_undef (lineno, buffer);
573150615Sobrien#endif /* DWARF_DEBUGGING_INFO */
573250615Sobrien#ifdef DWARF2_DEBUGGING_INFO
573350615Sobrien  if (debug_info_level == DINFO_LEVEL_VERBOSE
573450615Sobrien      && write_symbols == DWARF2_DEBUG)
573550615Sobrien    dwarf2out_undef (lineno, buffer);
573650615Sobrien#endif /* DWARF2_DEBUGGING_INFO */
573750615Sobrien}
5738