toplev.c 146 KB
Newer Older
Richard Stallman committed
1
/* Top level of GNU C compiler
2 3
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000 Free Software Foundation, Inc.
Richard Stallman committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
Richard Kenner committed
19 20
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */
Richard Stallman committed
21 22 23 24 25 26 27

/* This is the top level of cc1/c++.
   It parses command args, opens files, invokes the various passes
   in the proper order, and counts the time used by each.
   Error messages and low-level interface to malloc also handled here.  */

#include "config.h"
28 29 30
#undef FLOAT /* This is for hpux. They should change hpux.  */
#undef FFS  /* Some systems define this in param.h.  */
#include "system.h"
Richard Stallman committed
31 32
#include <signal.h>
#include <setjmp.h>
Jeff Law committed
33 34 35 36 37 38 39

#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif

#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
40
#endif
Richard Stallman committed
41 42 43 44

#include "input.h"
#include "tree.h"
#include "rtl.h"
45
#include "tm_p.h"
Richard Stallman committed
46 47
#include "flags.h"
#include "insn-attr.h"
48 49
#include "insn-codes.h"
#include "insn-config.h"
50
#include "hard-reg-set.h"
51
#include "recog.h"
52
#include "defaults.h"
Richard Kenner committed
53
#include "output.h"
Mike Stump committed
54
#include "except.h"
55
#include "function.h"
Jim Wilson committed
56
#include "toplev.h"
57
#include "expr.h"
Kaveh R. Ghazi committed
58
#include "basic-block.h"
59
#include "intl.h"
60
#include "ggc.h"
61
#include "graph.h"
62
#include "loop.h"
63
#include "regs.h"
64
#include "timevar.h"
65
#include "diagnostic.h"
66

67 68 69 70
#ifndef ACCUMULATE_OUTGOING_ARGS
#define ACCUMULATE_OUTGOING_ARGS 0
#endif

71 72 73 74 75 76 77 78
#ifdef DWARF_DEBUGGING_INFO
#include "dwarfout.h"
#endif

#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
#endif

Kaveh R. Ghazi committed
79
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
80 81 82 83 84 85 86
#include "dbxout.h"
#endif

#ifdef SDB_DEBUGGING_INFO
#include "sdbout.h"
#endif

87 88 89
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
#endif
Richard Stallman committed
90 91 92 93

#ifdef VMS
/* The extra parameters substantially improve the I/O performance.  */
static FILE *
94
vms_fopen (fname, type)
Richard Stallman committed
95 96 97
     char * fname;
     char * type;
{
98 99 100 101 102 103 104 105 106 107
  /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
     fixed arguments, which matches ANSI's specification but not VAXCRTL's
     pre-ANSI implementation.  This hack circumvents the mismatch problem.  */
  FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;

  if (*type == 'w')
    return (*vmslib_fopen) (fname, type, "mbc=32",
			    "deq=64", "fop=tef", "shr=nil");
  else
    return (*vmslib_fopen) (fname, type, "mbc=32");
Richard Stallman committed
108
}
109 110
#define fopen vms_fopen
#endif	/* VMS */
Richard Stallman committed
111 112 113 114 115

#ifndef DEFAULT_GDB_EXTENSIONS
#define DEFAULT_GDB_EXTENSIONS 1
#endif

116 117 118 119
/* If more than one debugging type is supported, you must define
   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. 

   This is one long line cause VAXC can't handle a \-newline.  */
x  
Jason Merrill committed
120
#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
121 122 123 124 125 126 127 128 129 130 131 132 133 134
#ifndef PREFERRED_DEBUGGING_TYPE
You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
#endif /* no PREFERRED_DEBUGGING_TYPE */
#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
	 so the following code needn't care.  */
#ifdef DBX_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#endif
#ifdef SDB_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
#endif
#ifdef DWARF_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
#endif
x  
Jason Merrill committed
135 136 137
#ifdef DWARF2_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#endif
138 139 140 141 142 143 144 145 146 147 148
#ifdef XCOFF_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
#endif
#endif /* More than one debugger format enabled.  */

/* If still not defined, must have been because no debugging formats
   are supported.  */
#ifndef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
#endif

149
#if defined (HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
Richard Stallman committed
150
extern char **environ;
151
#endif
Richard Stallman committed
152

153 154 155 156
/* Carry information from ASM_DECLARE_OBJECT_NAME
   to ASM_FINISH_DECLARE_OBJECT.  */

extern int size_directive_output;
157
extern tree last_assemble_variable_decl;
158

159 160
static void set_target_switch PARAMS ((const char *));
static const char *decl_name PARAMS ((tree, int));
161

162 163
static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
164
#ifdef ASM_IDENTIFY_LANGUAGE
Kaveh R. Ghazi committed
165
/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
166
static void output_lang_identify PARAMS ((FILE *)) ATTRIBUTE_UNUSED;
167
#endif
Zack Weinberg committed
168
static void compile_file PARAMS ((const char *));
169 170 171 172
static void display_help PARAMS ((void));
static void mark_file_stack PARAMS ((void *));

static void decode_d_option PARAMS ((const char *));
173 174 175
static int decode_f_option PARAMS ((const char *));
static int decode_W_option PARAMS ((const char *));
static int decode_g_option PARAMS ((const char *));
176 177
static unsigned int independent_decode_option PARAMS ((int, char **,
						       unsigned int));
178 179 180

static void print_version PARAMS ((FILE *, const char *));
static int print_single_switch PARAMS ((FILE *, int, int, const char *,
181 182
				      const char *, const char *,
				      const char *, const char *));
183
static void print_switch_values PARAMS ((FILE *, int, int, const char *,
184
				       const char *, const char *));
185

186 187 188
/* Length of line when printing switch values.  */
#define MAX_LINE 75

Richard Stallman committed
189 190
/* Name of program invoked, sans directories.  */

191
const char *progname;
Richard Stallman committed
192 193 194 195 196 197 198 199

/* Copy of arguments to main.  */
int save_argc;
char **save_argv;

/* Name of current original source file (what was input to cpp).
   This comes from each #-command in the actual input.  */

Zack Weinberg committed
200
const char *input_filename;
Richard Stallman committed
201 202 203 204 205

/* Name of top-level original source file (what was input to cpp).
   This comes from the #-command at the beginning of the actual input.
   If there isn't any there, then this is the cc1 input file name.  */

Zack Weinberg committed
206
const char *main_input_filename;
Richard Stallman committed
207 208 209 210 211

/* Current line number in real source file.  */

int lineno;

212 213 214
/* Nonzero if it is unsafe to create any new pseudo registers.  */
int no_new_pseudos;

Richard Stallman committed
215 216 217 218 219 220 221 222 223
/* Stack of currently pending input files.  */

struct file_stack *input_file_stack;

/* Incremented on each change to input_file_stack.  */
int input_file_stack_tick;

/* Name to use as base of names for dump output files.  */

224
const char *dump_base_name;
Richard Stallman committed
225 226 227 228 229 230 231

/* Bit flags that specify the machine subtype we are compiling for.
   Bits are tested using macros TARGET_... defined in the tm.h file
   and set by `-m...' switches.  Must be defined in rtlanal.c.  */

extern int target_flags;

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
/* Describes a dump file.  */

struct dump_file_info
{
  /* The unique extension to apply, e.g. ".jump".  */
  const char * const extension;

  /* The -d<c> character that enables this dump file.  */
  char const debug_switch;

  /* True if there is a corresponding graph dump file.  */
  char const graph_dump_p;

  /* True if the user selected this dump.  */
  char enabled;

  /* True if the files have been initialized (ie truncated).  */
  char initialized;
};

/* Enumerate the extant dump files.  */

enum dump_file_index
{
  DFI_rtl,
257
  DFI_sibling,
258 259 260 261 262 263 264 265
  DFI_jump,
  DFI_cse,
  DFI_addressof,
  DFI_ssa,
  DFI_ussa,
  DFI_gcse,
  DFI_loop,
  DFI_cse2,
266
  DFI_cfg,
267
  DFI_bp,
268
  DFI_life,
269
  DFI_combine,
Richard Henderson committed
270
  DFI_ce,
271 272 273 274 275
  DFI_regmove,
  DFI_sched,
  DFI_lreg,
  DFI_greg,
  DFI_flow2,
Richard Henderson committed
276
  DFI_ce2,
277
  DFI_peephole2,
278
  DFI_rnreg,
279 280 281 282 283 284 285 286 287 288
  DFI_sched2,
  DFI_bbro,
  DFI_jump2,
  DFI_mach,
  DFI_dbr,
  DFI_stack,
  DFI_MAX
};

/* Describes all the dump files.  Should be kept in order of the
Richard Henderson committed
289 290 291 292 293 294 295
   pass and in sync with dump_file_index above.

   Remaining -d letters:

	"       h      o q   u     "
	"       H  K   OPQ  TUVWXYZ"
*/
296 297 298 299

struct dump_file_info dump_file[DFI_MAX] = 
{
  { "rtl",	'r', 0, 0, 0 },
300
  { "sibling",  'i', 0, 0, 0 },
301 302 303 304 305 306 307 308
  { "jump",	'j', 0, 0, 0 },
  { "cse",	's', 0, 0, 0 },
  { "addressof", 'F', 0, 0, 0 },
  { "ssa",	'e', 1, 0, 0 },
  { "ussa",	'e', 1, 0, 0 },	/* Yes, duplicate enable switch.  */
  { "gcse",	'G', 1, 0, 0 },
  { "loop",	'L', 1, 0, 0 },
  { "cse2",	't', 1, 0, 0 },
309
  { "cfg",	'f', 1, 0, 0 },
310
  { "bp",	'b', 1, 0, 0 },
311
  { "life",	'f', 1, 0, 0 },	/* Yes, duplicate enable switch.  */
312
  { "combine",	'c', 1, 0, 0 },
Richard Henderson committed
313
  { "ce",	'C', 1, 0, 0 },
314 315 316 317 318
  { "regmove",	'N', 1, 0, 0 },
  { "sched",	'S', 1, 0, 0 },
  { "lreg",	'l', 1, 0, 0 },
  { "greg",	'g', 1, 0, 0 },
  { "flow2",	'w', 1, 0, 0 },
Richard Henderson committed
319
  { "ce2",	'E', 1, 0, 0 },
320
  { "peephole2", 'z', 1, 0, 0 },
321
  { "rnreg",	'n', 1, 0, 0 },
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  { "sched2",	'R', 1, 0, 0 },
  { "bbro",	'B', 1, 0, 0 },
  { "jump2",	'J', 1, 0, 0 },
  { "mach",	'M', 1, 0, 0 },
  { "dbr",	'd', 0, 0, 0 },
  { "stack",	'k', 1, 0, 0 },
};

static int open_dump_file PARAMS ((enum dump_file_index, tree));
static void close_dump_file PARAMS ((enum dump_file_index,
				     void (*) (FILE *, rtx), rtx));

/* Other flags saying which kinds of debugging dump have been requested.  */

int rtl_dump_and_exit;
int flag_print_asm_name;
static int flag_print_mem;
static int version_flag;
static char * filename;
341
enum graph_dump_types graph_dump_format;
Richard Stallman committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359

/* Name for output file of assembly code, specified with -o.  */

char *asm_file_name;

/* Value of the -G xx switch, and whether it was passed or not.  */
int g_switch_value;
int g_switch_set;

/* Type(s) of debugging information we are producing (if any).
   See flags.h for the definitions of the different possible
   types of debugging information.  */
enum debug_info_type write_symbols = NO_DEBUG;

/* Level of debugging information we are producing.  See flags.h
   for the definitions of the different possible levels.  */
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;

360 361 362 363 364
/* Nonzero means use GNU-only extensions in the generated symbolic
   debugging information.  */
/* Currently, this only has an effect when write_symbols is set to
   DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
int use_gnu_debug_info_extensions = 0;
Richard Stallman committed
365 366 367 368 369 370 371 372 373 374

/* Nonzero means do optimizations.  -O.
   Particular numeric values stand for particular amounts of optimization;
   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
   ones are not controlled directly by this variable.  Instead, they are
   controlled by individual `flag_...' variables that are defaulted
   based on this variable.  */

int optimize = 0;

375 376 377 378 379 380 381
/* Nonzero means optimize for size.  -Os.
   The only valid values are zero and non-zero. When optimize_size is
   non-zero, optimize defaults to 2, but certain individual code
   bloating optimizations are disabled.  */

int optimize_size = 0;

Richard Stallman committed
382 383 384 385 386 387
/* Number of error messages and warning messages so far.  */

int errorcount = 0;
int warningcount = 0;
int sorrycount = 0;

388 389 390 391 392 393 394 395
/* The FUNCTION_DECL for the function currently being compiled,
   or 0 if between functions.  */
tree current_function_decl;

/* Set to the FUNC_BEGIN label of the current function, or NULL_TREE
   if none.  */
tree current_function_func_begin_label;

x  
Jason Merrill committed
396 397 398 399 400 401 402
/* Pointer to function to compute the name to use to print a declaration.
   DECL is the declaration in question.
   VERBOSITY determines what information will be printed:
     0: DECL_NAME, demangled as necessary.
     1: and scope information.
     2: and any other information that might be interesting, such as function
        parameter types in C++.  */
Richard Stallman committed
403

404
const char *(*decl_printable_name)	PARAMS ((tree, int));
Richard Stallman committed
405 406 407

/* Pointer to function to compute rtl for a language-specific tree code.  */

408
typedef rtx (*lang_expand_expr_t)
409
  PARAMS ((union tree_node *, rtx, enum machine_mode,
410 411 412
	  enum expand_modifier modifier));

lang_expand_expr_t lang_expand_expr = 0;
Richard Stallman committed
413

414
tree (*lang_expand_constant) PARAMS ((tree)) = 0;
415

416 417 418
/* Pointer to function to finish handling an incomplete decl at the
   end of compilation.  */

419
void (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0;
420

Richard Stallman committed
421 422 423 424 425 426 427 428
/* Nonzero if generating code to do profiling.  */

int profile_flag = 0;

/* Nonzero if generating code to do profiling on a line-by-line basis.  */

int profile_block_flag;

429 430 431 432 433 434 435 436 437 438 439 440
/* Nonzero if generating code to profile program flow graph arcs.  */

int profile_arc_flag = 0;

/* Nonzero if generating info for gcov to calculate line test coverage.  */

int flag_test_coverage = 0;

/* Nonzero indicates that branch taken probabilities should be calculated.  */

int flag_branch_probabilities = 0;

441 442 443 444
/* Nonzero if basic blocks should be reordered. */

int flag_reorder_blocks = 0;

445 446 447 448
/* Nonzero if registers should be renamed */

int flag_rename_registers = 0;

Richard Stallman committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
/* Nonzero for -pedantic switch: warn about anything
   that standard spec forbids.  */

int pedantic = 0;

/* Temporarily suppress certain warnings.
   This is set while reading code from a system header file.  */

int in_system_header = 0;

/* Don't print functions as they are compiled and don't print
   times taken by the various passes.  -quiet.  */

int quiet_flag = 0;

/* -f flags.  */

/* Nonzero means `char' should be signed.  */

int flag_signed_char;

/* Nonzero means give an enum type only as many bytes as it needs.  */

int flag_short_enums;

/* Nonzero for -fcaller-saves: allocate values in regs that need to
   be saved across function calls, if that produces overall better code.
   Optional now, so people can test it.  */

#ifdef DEFAULT_CALLER_SAVES
int flag_caller_saves = 1;
#else
int flag_caller_saves = 0;
#endif

484 485 486 487 488 489 490 491 492
/* Nonzero if structures and unions should be returned in memory.

   This should only be defined if compatibility with another compiler or
   with an ABI is needed, because it results in slower code.  */

#ifndef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
#endif

Richard Stallman committed
493 494
/* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */

495
int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
Richard Stallman committed
496 497 498 499 500 501 502 503 504 505 506 507 508 509

/* Nonzero for -fforce-mem: load memory value into a register
   before arithmetic on it.  This makes better cse but slower compilation.  */

int flag_force_mem = 0;

/* Nonzero for -fforce-addr: load memory address into a register before
   reference to memory.  This makes better cse but slower compilation.  */

int flag_force_addr = 0;

/* Nonzero for -fdefer-pop: don't pop args after each function call;
   instead save them up to pop many calls' args with one insns.  */

510
int flag_defer_pop = 0;
Richard Stallman committed
511 512 513 514 515 516 517 518 519 520 521

/* Nonzero for -ffloat-store: don't allocate floats and doubles
   in extended-precision registers.  */

int flag_float_store = 0;

/* Nonzero for -fcse-follow-jumps:
   have cse follow jumps to do a more extensive job.  */

int flag_cse_follow_jumps;

522 523 524 525
/* Nonzero for -fcse-skip-blocks:
   have cse follow a branch around a block.  */
int flag_cse_skip_blocks;

Richard Stallman committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
/* Nonzero for -fexpensive-optimizations:
   perform miscellaneous relatively-expensive optimizations.  */
int flag_expensive_optimizations;

/* Nonzero for -fthread-jumps:
   have jump optimize output of loop.  */

int flag_thread_jumps;

/* Nonzero enables strength-reduction in loop.c.  */

int flag_strength_reduce = 0;

/* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
   number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
   UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
   unrolled.  */

int flag_unroll_loops;

/* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
   This is generally not a win.  */

int flag_unroll_all_loops;

551 552 553 554 555 556 557 558 559 560
/* Nonzero forces all invariant computations in loops to be moved
   outside the loop. */

int flag_move_all_movables = 0;

/* Nonzero forces all general induction variables in loops to be
   strength reduced. */

int flag_reduce_all_givs = 0;

561 562 563 564 565
/* Nonzero to perform full register move optimization passes.  This is the
   default for -O2.  */

int flag_regmove = 0;

Richard Stallman committed
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
/* Nonzero for -fwritable-strings:
   store string constants in data segment and don't uniquize them.  */

int flag_writable_strings = 0;

/* Nonzero means don't put addresses of constant functions in registers.
   Used for compiling the Unix kernel, where strange substitutions are
   done on the assembly output.  */

int flag_no_function_cse = 0;

/* Nonzero for -fomit-frame-pointer:
   don't make a frame pointer in simple functions that don't require one.  */

int flag_omit_frame_pointer = 0;

582 583 584 585 586
/* Nonzero means place each function into its own section on those platforms
   which support arbitrary section names and unlimited numbers of sections.  */

int flag_function_sections = 0;

Catherine Moore committed
587 588 589 590
/* ... and similar for data.  */
 
int flag_data_sections = 0;

Richard Stallman committed
591 592 593 594
/* Nonzero to inhibit use of define_optimization peephole opts.  */

int flag_no_peephole = 0;

Jeff Law committed
595 596 597
/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
   operations in the interest of optimization.  For example it allows
   GCC to assume arguments to sqrt are nonnegative numbers, allowing
Mike Stump committed
598
   faster code for sqrt to be generated.  */
Jeff Law committed
599 600 601

int flag_fast_math = 0;

602 603 604 605
/* Nonzero allows GCC to optimize sibling and tail recursive calls.  */

int flag_optimize_sibling_calls = 0;

606 607 608 609 610
/* Nonzero means the front end generally wants `errno' maintained by math
   operations, like built-in SQRT, unless overridden by flag_fast_math.  */

int flag_errno_math = 1;

611 612 613 614 615 616
/* 0 means straightforward implementation of complex divide acceptable.
   1 means wide ranges of inputs must work for complex divide.
   2 means C9X-like requirements for complex divide (not yet implemented).  */

int flag_complex_divide_method = 0;

Richard Stallman committed
617 618 619
/* Nonzero means all references through pointers are volatile.  */

int flag_volatile;
Richard Stallman committed
620

621
/* Nonzero means treat all global and extern variables as volatile.  */
Richard Stallman committed
622

623
int flag_volatile_global;
Richard Stallman committed
624

625 626 627 628
/* Nonzero means treat all static variables as volatile.  */

int flag_volatile_static;

Richard Stallman committed
629 630 631 632
/* Nonzero means just do syntax checking; don't output anything.  */

int flag_syntax_only = 0;

633 634 635 636
/* Nonzero means perform global cse.  */

static int flag_gcse;

637 638 639 640 641
/* Nonzero means to use global dataflow analysis to eliminate
   useless null pointer tests.  */

static int flag_delete_null_pointer_checks;

Richard Stallman committed
642 643 644 645 646
/* Nonzero means to rerun cse after loop optimization.  This increases
   compilation time about 20% and picks up a few more common expressions.  */

static int flag_rerun_cse_after_loop;

647 648
/* Nonzero means to run loop optimizations twice.  */

649
int flag_rerun_loop_opt;
650

Richard Stallman committed
651 652 653 654 655 656
/* Nonzero for -finline-functions: ok to inline functions that look like
   good inline candidates.  */

int flag_inline_functions;

/* Nonzero for -fkeep-inline-functions: even if we make a function
657
   go inline everywhere, keep its definition around for debugging
Richard Stallman committed
658 659 660 661
   purposes.  */

int flag_keep_inline_functions;

Jason Merrill committed
662
/* Nonzero means that functions will not be inlined.  */
Richard Stallman committed
663 664 665

int flag_no_inline;

666 667 668 669 670
/* Nonzero means that we should emit static const variables
   regardless of whether or not optimization is turned on.  */

int flag_keep_static_consts = 1;

Richard Stallman committed
671 672 673 674
/* Nonzero means we should be saving declaration info into a .X file.  */

int flag_gen_aux_info = 0;

675 676 677 678
/* Specified name of aux-info file.  */

static char *aux_info_file_name;

Richard Stallman committed
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
/* Nonzero means make the text shared if supported.  */

int flag_shared_data;

/* Nonzero means schedule into delayed branch slots if supported.  */

int flag_delayed_branch;

/* Nonzero if we are compiling pure (sharable) code.
   Value is 1 if we are doing reasonable (i.e. simple
   offset into offset table) pic.  Value is 2 if we can
   only perform register offsets.  */

int flag_pic;

Mike Stump committed
694 695 696
/* Nonzero means generate extra code for exception handling and enable
   exception handling.  */

697
int flag_exceptions;
Mike Stump committed
698

Andrew MacLeod committed
699 700 701
/* Nonzero means use the new model for exception handling. Replaces 
   -DNEW_EH_MODEL as a compile option. */

702
int flag_new_exceptions = 1;
Andrew MacLeod committed
703

Richard Kenner committed
704 705 706 707
/* Nonzero means generate frame unwind info table when supported */

int flag_unwind_tables = 0;

Jason Merrill committed
708
/* Nonzero means don't place uninitialized global data in common storage
Mike Stump committed
709
   by default.  */
Richard Stallman committed
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731

int flag_no_common;

/* Nonzero means pretend it is OK to examine bits of target floats,
   even if that isn't true.  The resulting code will have incorrect constants,
   but the same series of instructions that the native compiler would make.  */

int flag_pretend_float;

/* Nonzero means change certain warnings into errors.
   Usually these are warnings about failure to conform to some standard.  */

int flag_pedantic_errors = 0;

/* flag_schedule_insns means schedule insns within basic blocks (before
   local_alloc).
   flag_schedule_insns_after_reload means schedule insns after
   global_alloc.  */

int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;

732 733 734 735 736 737 738 739
/* The following flags have effect only for scheduling before register
   allocation:

   flag_schedule_interblock means schedule insns accross basic blocks.
   flag_schedule_speculative means allow speculative motion of non-load insns.
   flag_schedule_speculative_load means allow speculative motion of some
   load insns.
   flag_schedule_speculative_load_dangerous allows speculative motion of more
740
   load insns.  */
741 742 743 744 745 746

int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;

747 748
int flag_single_precision_constant;

749 750 751 752
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
   by a cheaper branch, on a count register. */
int flag_branch_on_count_reg;

Richard Stallman committed
753 754 755 756 757 758
/* -finhibit-size-directive inhibits output of .size for ELF.
   This is used only for compiling crtstuff.c, 
   and it may be extended to other effects
   needed for crtstuff.c on other systems.  */
int flag_inhibit_size_directive = 0;

759 760 761
/* -fverbose-asm causes extra commentary information to be produced in
   the generated assembly code (to make it more readable).  This option
   is generally only of use to those who actually need to read the
762
   generated assembly code (perhaps while debugging the compiler itself).
763
   -fno-verbose-asm, the default, causes the extra information
764 765
   to be omitted and is useful when comparing two assembler files.  */

766
int flag_verbose_asm = 0;
767

768 769 770 771 772 773 774 775
/* -dA causes debug commentary information to be produced in
   the generated assembly code (to make it more readable).  This option
   is generally only of use to those who actually need to read the
   generated assembly code (perhaps while debugging the compiler itself).
   Currently, this switch is only used by dwarfout.c; however, it is intended
   to be a catchall for printing debug information in the assembler file.  */

int flag_debug_asm = 0;
776

Richard Stallman committed
777
/* -fgnu-linker specifies use of the GNU linker for initializations.
778 779 780 781 782
   (Or, more generally, a linker that handles initializations.)
   -fno-gnu-linker says that collect2 will be used.  */
#ifdef USE_COLLECT2
int flag_gnu_linker = 0;
#else
Richard Stallman committed
783
int flag_gnu_linker = 1;
784
#endif
Richard Stallman committed
785

Alex Samuel committed
786 787 788
/* Enable SSA.  */
int flag_ssa = 0;

Michael Meissner committed
789 790 791
/* Tag all structures with __attribute__(packed) */
int flag_pack_struct = 0;

792 793 794 795
/* Emit code to check for stack overflow; also may cause large objects
   to be allocated dynamically.  */
int flag_stack_check;

796 797 798 799 800 801 802 803 804
/* When non-NULL, indicates that whenever space is allocated on the
   stack, the resulting stack pointer must not pass this
   address---that is, for stacks that grow downward, the stack pointer
   must always be greater than or equal to this address; for stacks
   that grow upward, the stack pointer must be less than this address.
   At present, the rtx may be either a REG or a SYMBOL_REF, although
   the support provided depends on the backend.  */
rtx stack_limit_rtx;

805 806 807 808 809 810 811 812 813 814
/* -fcheck-memory-usage causes extra code to be generated in order to check
   memory accesses.  This is used by a detector of bad memory accesses such
   as Checker.  */
int flag_check_memory_usage = 0;

/* -fprefix-function-name causes function name to be prefixed.  This
   can be used with -fcheck-memory-usage to isolate code compiled with
   -fcheck-memory-usage.  */
int flag_prefix_function_name = 0;

815 816 817 818 819 820 821 822
/* 0 if pointer arguments may alias each other.  True in C.
   1 if pointer arguments may not alias each other but may alias
   global variables.
   2 if pointer arguments may not alias each other and may not
   alias global variables.  True in Fortran.
   This defaults to 0 for C.  */
int flag_argument_noalias = 0;

823 824 825 826 827 828
/* Nonzero if we should do (language-dependent) alias analysis.
   Typically, this analysis will assume that expressions of certain
   types do not alias expressions of certain other types.  Only used
   if alias analysis (in general) is enabled.  */
int flag_strict_aliasing = 0;

829 830 831
/* Instrument functions with calls at entry and exit, for profiling.  */
int flag_instrument_function_entry_exit = 0;

832 833 834 835 836
/* Nonzero means ignore `#ident' directives.  0 means handle them.
   On SVR4 targets, it also controls whether or not to emit a
   string identifying the compiler.  */

int flag_no_ident = 0;
Nick Clifton committed
837

838 839 840
/* This will perform a peephole pass before sched2. */
int flag_peephole2 = 0;

841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
/* -fbounded-pointers causes gcc to compile pointers as composite
   objects occupying three words: the pointer value, the base address
   of the referent object, and the address immediately beyond the end
   of the referent object.  The base and extent allow us to perform
   runtime bounds checking.  -fbounded-pointers implies -fcheck-bounds.  */
int flag_bounded_pointers = 0;

/* -fcheck-bounds causes gcc to generate array bounds checks.
   For C, C++: defaults to value of flag_bounded_pointers.
   For ObjC: defaults to off.
   For Java: defaults to on.
   For Fortran: defaults to off.
   For CHILL: defaults to off.  */
int flag_bounds_check = 0;

856 857 858 859 860
/* If one, renumber instruction UIDs to reduce the number of
   unused UIDs if there are a lot of instructions.  If greater than
   one, unconditionally renumber instruction UIDs.  */
int flag_renumber_insns = 1;

861 862 863 864 865 866 867 868 869 870 871 872 873 874
/* Values of the -falign-* flags: how much to align labels in code. 
   0 means `use default', 1 means `don't align'.  
   For each variable, there is an _log variant which is the power
   of two not less than the variable, for .align output.  */

int align_loops;
int align_loops_log;
int align_jumps;
int align_jumps_log;
int align_labels;
int align_labels_log;
int align_functions;
int align_functions_log;

Nick Clifton committed
875 876 877
/* Table of supported debugging formats.  */
static struct
{
878
  const char * arg;
Nick Clifton committed
879 880 881 882
  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
     constant expression, we use NO_DEBUG in its place.  */
  enum debug_info_type debug_type;
  int use_extensions_p;
883
  const char * description;
Nick Clifton committed
884 885 886
} *da,
debug_args[] =
{
887
  { "",       NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
Nick Clifton committed
888
    "Generate default debug format output" },
889
  { "gdb",    NO_DEBUG, 1, "Generate default extended debug format output" },
Nick Clifton committed
890
#ifdef DBX_DEBUGGING_INFO
891 892
  { "stabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
  { "stabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
Nick Clifton committed
893 894
#endif
#ifdef DWARF_DEBUGGING_INFO
895 896
  { "dwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
  { "dwarf+", DWARF_DEBUG, 1,
Nick Clifton committed
897 898 899
    "Generated extended DWARF-1 format debug output" },
#endif
#ifdef DWARF2_DEBUGGING_INFO
900
  { "dwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
Nick Clifton committed
901 902
#endif
#ifdef XCOFF_DEBUGGING_INFO
903 904
  { "xcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
  { "xcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
Nick Clifton committed
905 906
#endif
#ifdef SDB_DEBUGGING_INFO
907
  { "coff", SDB_DEBUG, 0, "Generate COFF format debug output" },
Nick Clifton committed
908
#endif
Kaveh R. Ghazi committed
909
  { 0, 0, 0, 0 }
Nick Clifton committed
910 911 912 913
};

typedef struct
{
914
  const char * string;
Nick Clifton committed
915 916
  int *  variable;
  int    on_value;
917
  const char * description;
Nick Clifton committed
918 919 920
}
lang_independent_options;

921 922 923 924
/* Add or remove a leading underscore from user symbols.  */
int flag_leading_underscore = -1;

/* The user symbol prefix after having resolved same.  */
925
const char *user_label_prefix;
926 927 928 929 930 931

/* A default for same.  */
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
#endif

Richard Stallman committed
932 933 934 935 936 937
/* Table of language-independent -f options.
   STRING is the option name.  VARIABLE is the address of the variable.
   ON_VALUE is the value to store in VARIABLE
    if `-fSTRING' is seen as an option.
   (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */

Nick Clifton committed
938
lang_independent_options f_options[] =
Richard Stallman committed
939
{
Nick Clifton committed
940 941 942 943 944 945
  {"float-store", &flag_float_store, 1,
   "Do not store floats in registers" },
  {"volatile", &flag_volatile, 1,
   "Consider all mem refs through pointers as volatile"},
  {"volatile-global", &flag_volatile_global, 1,
   "Consider all mem refs to global data to be volatile" },
946 947
  {"volatile-static", &flag_volatile_static, 1,
   "Consider all mem refs to static data to be volatile" },
Nick Clifton committed
948 949 950 951
  {"defer-pop", &flag_defer_pop, 1,
   "Defer popping functions args from stack until later" },
  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
   "When possible do not generate stack frames"},
952 953
  {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
   "Optimize sibling and tail recursive calls" },
Nick Clifton committed
954 955 956 957 958 959 960 961 962 963 964
  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
   "When running CSE, follow jumps to their targets" },
  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
   "When running CSE, follow conditional jumps" },
  {"expensive-optimizations", &flag_expensive_optimizations, 1,
   "Perform a number of minor, expensive optimisations" },
  {"thread-jumps", &flag_thread_jumps, 1,
   "Perform jump threading optimisations"},
  {"strength-reduce", &flag_strength_reduce, 1,
   "Perform strength reduction optimisations" },
  {"unroll-loops", &flag_unroll_loops, 1,
965
   "Perform loop unrolling when iteration count is known" },
Nick Clifton committed
966
  {"unroll-all-loops", &flag_unroll_all_loops, 1,
967
   "Perform loop unrolling for all loops" },
Nick Clifton committed
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
  {"move-all-movables", &flag_move_all_movables, 1,
   "Force all loop invariant computations out of loops" },
  {"reduce-all-givs", &flag_reduce_all_givs, 1,
   "Strength reduce all loop general induction variables" },
  {"writable-strings", &flag_writable_strings, 1,
   "Store strings in writable data section" },
  {"peephole", &flag_no_peephole, 0,
   "Enable machine specific peephole optimisations" },
  {"force-mem", &flag_force_mem, 1,
   "Copy memory operands into registers before using" },
  {"force-addr", &flag_force_addr, 1,
   "Copy memory address constants into regs before using" },
  {"function-cse", &flag_no_function_cse, 0,
   "Allow function addresses to be held in registers" },
  {"inline-functions", &flag_inline_functions, 1,
   "Integrate simple functions into their callers" },
  {"keep-inline-functions", &flag_keep_inline_functions, 1,
   "Generate code for funcs even if they are fully inlined" },
  {"inline", &flag_no_inline, 0,
   "Pay attention to the 'inline' keyword"},
  {"keep-static-consts", &flag_keep_static_consts, 1,
   "Emit static const variables even if they are not used" },
  {"syntax-only", &flag_syntax_only, 1,
   "Check for syntax errors, then stop" },
  {"shared-data", &flag_shared_data, 1,
   "Mark data as shared rather than private" },
  {"caller-saves", &flag_caller_saves, 1,
   "Enable saving registers around function calls" },
  {"pcc-struct-return", &flag_pcc_struct_return, 1,
   "Return 'short' aggregates in memory, not registers" },
  {"reg-struct-return", &flag_pcc_struct_return, 0,
   "Return 'short' aggregates in registers" },
  {"delayed-branch", &flag_delayed_branch, 1,
   "Attempt to fill delay slots of branch instructions" },
  {"gcse", &flag_gcse, 1,
   "Perform the global common subexpression elimination" },
  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
   "Run CSE pass after loop optimisations"},
  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
   "Run the loop optimiser twice"},
1008 1009
  {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1,
   "Delete useless null pointer checks" },
Nick Clifton committed
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
  {"pretend-float", &flag_pretend_float, 1,
   "Pretend that host and target use the same FP format"},
  {"schedule-insns", &flag_schedule_insns, 1,
   "Reschedule instructions to avoid pipeline stalls"},
  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
  "Run two passes of the instruction scheduler"},
  {"sched-interblock",&flag_schedule_interblock, 1,
   "Enable scheduling across basic blocks" },
  {"sched-spec",&flag_schedule_speculative, 1,
   "Allow speculative motion of non-loads" },
  {"sched-spec-load",&flag_schedule_speculative_load, 1,
   "Allow speculative motion of some loads" },
  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
   "Allow speculative motion of more loads" },
  {"branch-count-reg",&flag_branch_on_count_reg, 1,
Nick Clifton committed
1025
   "Replace add,compare,branch with branch on count reg"},
Nick Clifton committed
1026 1027 1028 1029 1030 1031 1032
  {"pic", &flag_pic, 1,
   "Generate position independent code, if possible"},
  {"PIC", &flag_pic, 2, ""},
  {"exceptions", &flag_exceptions, 1,
   "Enable exception handling" },
  {"new-exceptions", &flag_new_exceptions, 1,
   "Use the new model for exception handling" },
Richard Kenner committed
1033 1034
  {"unwind-tables", &flag_unwind_tables, 1,
    "Just generate unwind tables for exception handling" },
Nick Clifton committed
1035 1036 1037 1038 1039 1040 1041 1042 1043
  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
   "Use setjmp/longjmp to handle exceptions" },
  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
   "Support asynchronous exceptions" },
  {"profile-arcs", &profile_arc_flag, 1,
   "Insert arc based program profiling code" },
  {"test-coverage", &flag_test_coverage, 1,
   "Create data files needed by gcov" },
  {"branch-probabilities", &flag_branch_probabilities, 1,
1044
   "Use profiling information for branch probabilities" },
1045 1046
  {"reorder-blocks", &flag_reorder_blocks, 1,
   "Reorder basic blocks to improve code placement" },
1047 1048
  {"rename-registers", &flag_rename_registers, 1,
   "Do the register renaming optimization pass"},
Nick Clifton committed
1049 1050 1051 1052 1053 1054 1055 1056
  {"fast-math", &flag_fast_math, 1,
   "Improve FP speed by violating ANSI & IEEE rules" },
  {"common", &flag_no_common, 0,
   "Do not put unitialised globals in the common section" },
  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
   "Do not generate .size directives" },
  {"function-sections", &flag_function_sections, 1,
   "place each function into its own section" },
Catherine Moore committed
1057 1058
  {"data-sections", &flag_data_sections, 1,
   "place data items into their own section" },
Nick Clifton committed
1059 1060 1061 1062 1063
  {"verbose-asm", &flag_verbose_asm, 1,
   "Add extra commentry to assembler output"},
  {"gnu-linker", &flag_gnu_linker, 1,
   "Output GNU ld formatted global initialisers"},
  {"regmove", &flag_regmove, 1,
Kaveh R. Ghazi committed
1064 1065 1066
   "Enables a register move optimisation"},
  {"optimize-register-move", &flag_regmove, 1,
   "Do the full regmove optimization pass"},
Nick Clifton committed
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
  {"pack-struct", &flag_pack_struct, 1,
   "Pack structure members together without holes" },
  {"stack-check", &flag_stack_check, 1,
   "Insert stack checking code into the program" },
  {"argument-alias", &flag_argument_noalias, 0,
   "Specify that arguments may alias each other & globals"},
  {"argument-noalias", &flag_argument_noalias, 1,
   "Assume arguments may alias globals but not each other"},
  {"argument-noalias-global", &flag_argument_noalias, 2,
   "Assume arguments do not alias each other or globals" },
  {"strict-aliasing", &flag_strict_aliasing, 1,
   "Assume strict aliasing rules apply" },
1079 1080 1081 1082 1083 1084 1085 1086
  {"align-loops", &align_loops, 0, 
   "Align the start of loops" },
  {"align-jumps", &align_jumps, 0, 
   "Align labels which are only reached by jumping" },
  {"align-labels", &align_labels, 0,
   "Align all labels" },
  {"align-functions", &align_functions, 0,
   "Align the start of functions" },
Nick Clifton committed
1087 1088 1089 1090
  {"check-memory-usage", &flag_check_memory_usage, 1,
   "Generate code to check every memory access" },
  {"prefix-function-name", &flag_prefix_function_name, 1,
   "Add a prefix to all function names" },
Kaveh R. Ghazi committed
1091 1092
  {"dump-unnumbered", &flag_dump_unnumbered, 1,
   "Suppress output of instruction numbers and line number notes in debugging dumps"},
1093 1094
  {"instrument-functions", &flag_instrument_function_entry_exit, 1,
   "Instrument function entry/exit with profiling calls"},
Alex Samuel committed
1095 1096
  {"ssa", &flag_ssa, 1,
   "Enable SSA optimizations" },
1097
  {"leading-underscore", &flag_leading_underscore, 1,
1098 1099
   "External symbols have a leading underscore" },
  {"ident", &flag_no_ident, 0,
1100 1101
   "Process #ident directives"},
  { "peephole2", &flag_peephole2, 1,
1102 1103
    "Enables an rtl peephole pass run before sched2" },
  {"math-errno", &flag_errno_math, 1,
1104 1105 1106 1107
   "Set errno after built-in math functions"},
  {"bounded-pointers", &flag_bounded_pointers, 1,
   "Compile pointers as triples: value, base & end" },
  {"bounds-check", &flag_bounds_check, 1,
1108 1109 1110
   "Generate code to check bounds before dereferencing pointers and arrays" },
  {"single-precision-constant", &flag_single_precision_constant, 1,
  "Convert floating point constant to single precision constant"}
Richard Stallman committed
1111
};
1112

Nick Clifton committed
1113 1114
#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))

1115 1116
/* Table of language-specific options.  */

Nick Clifton committed
1117 1118
static struct lang_opt
{
1119 1120
  const char * option;
  const char * description;
Nick Clifton committed
1121 1122
}
documented_lang_options[] =
1123
{
Nick Clifton committed
1124 1125 1126 1127 1128 1129 1130
  /* In order not to overload the --help output, the convention
     used here is to only describe those options which are not
     enabled by default.  */

  { "-ansi", "Compile just for ANSI C" },
  { "-fallow-single-precision",
    "Do not promote floats to double if using -traditional" },
1131
  { "-std= ", "Determine language standard"},
Nick Clifton committed
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157

  { "-fsigned-bitfields", "" },
  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
  { "-fno-signed-bitfields", "" },
  { "-fno-unsigned-bitfields","" },
  { "-fsigned-char", "Make 'char' be signed by default"},
  { "-funsigned-char", "Make 'char' be unsigned by default"},
  { "-fno-signed-char", "" },
  { "-fno-unsigned-char", "" },

  { "-ftraditional", "" },
  { "-traditional", "Attempt to support traditional K&R style C"},
  { "-fnotraditional", "" },
  { "-fno-traditional", "" },

  { "-fasm", "" },
  { "-fno-asm", "Do not recognise the 'asm' keyword" },
  { "-fbuiltin", "" },
  { "-fno-builtin", "Do not recognise any built in functions" },
  { "-fhosted", "Assume normal C execution environment" },
  { "-fno-hosted", "" },
  { "-ffreestanding",
    "Assume that standard libraries & main might not exist" },
  { "-fno-freestanding", "" },
  { "-fcond-mismatch", "Allow different types as args of ? operator"},
  { "-fno-cond-mismatch", "" },
1158
  { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
Nick Clifton committed
1159
  { "-fno-dollars-in-identifiers", "" },
1160 1161
  { "-fpreprocessed", "" },
  { "-fno-preprocessed", "" },
Nick Clifton committed
1162 1163 1164 1165
  { "-fshort-double", "Use the same size for double as for float" },
  { "-fno-short-double", "" },
  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
  { "-fno-short-enums", "" },
1166 1167
  { "-fshort-wchar", "Override the underlying type for wchar_t to `unsigned short'" },
  { "-fno-short-wchar", "" },
Nick Clifton committed
1168 1169 1170 1171 1172

  { "-Wall", "Enable most warning messages" },
  { "-Wbad-function-cast",
    "Warn about casting functions to incompatible types" },
  { "-Wno-bad-function-cast", "" },
1173 1174 1175
  { "-Wmissing-noreturn",
    "Warn about functions which might be candidates for attribute noreturn" },
  { "-Wno-missing-noreturn", "" },
Nick Clifton committed
1176 1177
  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
  { "-Wno-cast-qual", "" },
1178
  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
Nick Clifton committed
1179 1180
  { "-Wno-char-subscripts", "" },
  { "-Wcomment", "Warn if nested comments are detected" },
Kaveh R. Ghazi committed
1181 1182 1183
  { "-Wno-comment", "" },
  { "-Wcomments", "Warn if nested comments are detected" },
  { "-Wno-comments", "" },
Nick Clifton committed
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
  { "-Wconversion", "Warn about possibly confusing type conversions" },
  { "-Wno-conversion", "" },
  { "-Wformat", "Warn about printf format anomalies" },
  { "-Wno-format", "" },
  { "-Wimplicit-function-declaration",
    "Warn about implicit function declarations" },
  { "-Wno-implicit-function-declaration", "" },
  { "-Werror-implicit-function-declaration", "" },
  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
  { "-Wno-implicit-int", "" },
  { "-Wimplicit", "" },
  { "-Wno-implicit", "" },
  { "-Wimport", "Warn about the use of the #import directive" },
  { "-Wno-import", "" },
  { "-Wlong-long","" },
  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
  { "-Wmain", "Warn about suspicious declarations of main" },
  { "-Wno-main", "" },
  { "-Wmissing-braces",
    "Warn about possibly missing braces around initialisers" },
  { "-Wno-missing-braces", "" },
  { "-Wmissing-declarations",
    "Warn about global funcs without previous declarations"},
  { "-Wno-missing-declarations", "" },
  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
  { "-Wno-missing-prototypes", "" },
  { "-Wmultichar", "Warn about use of multicharacter literals"},
  { "-Wno-multichar", "" },
  { "-Wnested-externs", "Warn about externs not at file scope level" },
  { "-Wno-nested-externs", "" },
  { "-Wparentheses", "Warn about possible missing parentheses" },
  { "-Wno-parentheses", "" },
  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
  { "-Wno-pointer-arith", "" },
  { "-Wredundant-decls",
    "Warn about multiple declarations of the same object" },
  { "-Wno-redundant-decls", "" },
  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
  { "-Wno-sign-compare", "" },
1223 1224
  { "-Wfloat-equal", "Warn about testing equality of floating point numbers" },
  { "-Wno-float-equal", "" },
1225
  { "-Wunknown-pragmas", "Warn about unrecognized pragmas" },
Nick Clifton committed
1226 1227 1228
  { "-Wno-unknown-pragmas", "" },
  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
  { "-Wno-strict-prototypes", "" },
1229
  { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
Nick Clifton committed
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239
  { "-Wno-traditional", "" },
  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
  { "-Wno-trigraphs", "" },
  { "-Wundef", "" },
  { "-Wno-undef", "" },
  { "-Wwrite-strings", "Mark strings as 'const char *'"},
  { "-Wno-write-strings", "" },
  
#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
  
1240
  /* These are for Objective C.  */
Nick Clifton committed
1241 1242 1243 1244
  DEFINE_LANG_NAME ("Objective C")
  
  { "-lang-objc", "" },
  { "-gen-decls", "Dump decls to a .decl file" },
1245
  { "-fgnu-runtime", "Generate code for GNU runtime environment" },
Nick Clifton committed
1246 1247 1248 1249 1250 1251 1252 1253 1254
  { "-fno-gnu-runtime", "" },
  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
  { "-fno-next-runtime", "" },
  { "-Wselector", "Warn if a selector has multiple methods" },
  { "-Wno-selector", "" },
  { "-Wprotocol", "" },
  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
  { "-print-objc-runtime-info",
    "Generate C header of platform specific features" },
1255

1256
#include "options.h"
Nick Clifton committed
1257
  
1258
};
Nick Clifton committed
1259 1260 1261 1262 1263 1264 1265 1266 1267

/* Here is a table, controlled by the tm.h file, listing each -m switch
   and which bits in `target_switches' it should set or clear.
   If VALUE is positive, it is bits to set.
   If VALUE is negative, -VALUE is bits to clear.
   (The sign bit is not used so there is no confusion.)  */

struct
{
1268
  const char * name;
Nick Clifton committed
1269
  int    value;
1270
  const char * description;
Nick Clifton committed
1271 1272 1273 1274 1275 1276 1277 1278
}
target_switches [] = TARGET_SWITCHES;

/* This table is similar, but allows the switch to have a value.  */

#ifdef TARGET_OPTIONS
struct
{
1279 1280 1281
  const char *  prefix;
  const char ** variable;
  const char *  description;
Nick Clifton committed
1282 1283 1284
}
target_options [] = TARGET_OPTIONS;
#endif
Richard Stallman committed
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299

/* Options controlling warnings */

/* Don't print warning messages.  -w.  */

int inhibit_warnings = 0;

/* Print various extra warnings.  -W.  */

int extra_warnings = 0;

/* Treat warnings as errors.  -Werror.  */

int warnings_are_errors = 0;

1300
/* Nonzero to warn about unused variables, functions et.al.  */
Richard Stallman committed
1301

1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
int warn_unused_function;
int warn_unused_label;
int warn_unused_parameter;
int warn_unused_variable;
int warn_unused_value;

void
set_Wunused (setting)
     int setting;
{
  warn_unused_function = setting;
  warn_unused_label = setting;
  /* Unused function parameter warnings are reported when either ``-W
     -Wunused'' or ``-Wunused-parameter'' is specified.  Differentiate
     -Wunused by setting WARN_UNUSED_PARAMETER to -1 */
  if (!setting)
    warn_unused_parameter = 0;
  else if (!warn_unused_parameter)
    warn_unused_parameter = -1;
  warn_unused_variable = setting;
  warn_unused_value = setting;
}
Richard Stallman committed
1324

1325 1326 1327 1328
/* Nonzero to warn about code which is never reached.  */

int warn_notreached;

Richard Stallman committed
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
/* Nonzero to warn about variables used before they are initialized.  */

int warn_uninitialized;

/* Nonzero means warn about all declarations which shadow others.   */

int warn_shadow;

/* Warn if a switch on an enum fails to have a case for every enum value.  */

int warn_switch;

/* Nonzero means warn about function definitions that default the return type
   or that use a null return and have a return-type other than void.  */

int warn_return_type;

/* Nonzero means warn about pointer casts that increase the required
   alignment of the target type (and might therefore lead to a crash
   due to a misaligned access).  */

int warn_cast_align;

/* Nonzero means warn about any identifiers that match in the first N
   characters.  The value N is in `id_clash_len'.  */

int warn_id_clash;
1356
int id_clash_len;
1357 1358 1359 1360 1361 1362

/* Nonzero means warn about any objects definitions whose size is larger
   than N bytes.  Also want about function definitions whose returned
   values are larger than N bytes. The value N is in `larger_than_size'.  */
 
int warn_larger_than;
1363
HOST_WIDE_INT larger_than_size;
Richard Stallman committed
1364 1365 1366 1367 1368 1369 1370 1371 1372 1373

/* Nonzero means warn if inline function is too large.  */

int warn_inline;

/* Warn if a function returns an aggregate,
   since there are often incompatible calling conventions for doing this.  */

int warn_aggregate_return;

1374 1375 1376 1377 1378 1379 1380 1381
/* Warn if packed attribute on struct is unnecessary and inefficient.  */

int warn_packed;

/* Warn when gcc pads a structure to an alignment boundary.  */

int warn_padded;

Richard Stallman committed
1382 1383
/* Likewise for -W.  */

Nick Clifton committed
1384
lang_independent_options W_options[] =
Richard Stallman committed
1385
{
1386 1387 1388 1389 1390
  {"unused-function", &warn_unused_function, 1, "Warn when a function is unused" },
  {"unused-label", &warn_unused_label, 1, "Warn when a label is unused" },
  {"unused-parameter", &warn_unused_parameter, 1, "Warn when a function parameter is unused" },
  {"unused-variable", &warn_unused_variable, 1, "Warn when a variable is unused" },
  {"unused-value", &warn_unused_value, 1, "Warn when an expression value is unused" },
Nick Clifton committed
1391 1392 1393 1394 1395 1396 1397 1398
  {"error", &warnings_are_errors, 1, ""},
  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
  {"switch", &warn_switch, 1,
   "Warn about enumerated switches missing a specific case" },
  {"aggregate-return", &warn_aggregate_return, 1,
   "Warn about returning structures, unions or arrays" },
  {"cast-align", &warn_cast_align, 1,
   "Warn about pointer casts which increase alignment" },
1399 1400
  {"unreachable-code", &warn_notreached, 1, 
   "Warn about code that will never be executed" },
Nick Clifton committed
1401 1402 1403
  {"uninitialized", &warn_uninitialized, 1,
   "Warn about unitialized automatic variables"},
  {"inline", &warn_inline, 1,
1404 1405 1406 1407 1408
   "Warn when an inlined function cannot be inlined"},
  {"packed", &warn_packed, 1,
   "Warn when the packed attribute has no effect on struct layout"},
  {"padded", &warn_padded, 1,
   "Warn when padding is required to align struct members"}
Richard Stallman committed
1409 1410 1411 1412 1413 1414 1415
};

/* Output files for assembler code (real compiler output)
   and debugging dumps.  */

FILE *asm_out_file;
FILE *aux_info_file;
1416
FILE *rtl_dump_file = NULL;
Richard Stallman committed
1417

1418 1419
/* Decode the string P as an integral parameter.
   If the string is indeed an integer return its numeric value else
1420 1421
   issue an Invalid Option error for the option PNAME and return DEFVAL.
   If PNAME is zero just return DEFVAL, do not call error.               */
1422 1423 1424
   
int
read_integral_parameter (p, pname, defval)
1425 1426 1427
     const char *p;
     const char *pname;
     const int  defval;
1428
{
1429
  const char *endp = p;
1430 1431 1432 1433 1434 1435

  while (*endp)
    {
      if (*endp >= '0' && *endp <= '9')
	endp++;
      else
1436 1437 1438 1439 1440 1441 1442 1443
	break;
    }

  if (*endp != 0)
    {
      if (pname != 0)
	error ("Invalid option `%s'", pname);
      return defval;
1444 1445 1446 1447 1448
    }

  return atoi (p);
}

Richard Stallman committed
1449 1450 1451

/* This is the default decl_printable_name function.  */

1452
static const char *
x  
Jason Merrill committed
1453
decl_name (decl, verbosity)
Richard Stallman committed
1454
     tree decl;
1455
     int verbosity ATTRIBUTE_UNUSED;
Richard Stallman committed
1456 1457 1458 1459
{
  return IDENTIFIER_POINTER (DECL_NAME (decl));
}

1460
/* Mark P for GC.  Also mark main_input_filename and input_filename.  */
1461

1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
static void
mark_file_stack (p)
     void *p;
{
  struct file_stack *stack = *(struct file_stack **)p;

  /* We're only called for input_file_stack, so we can mark the current
     input_filename here as well.  */
  ggc_mark_string (main_input_filename);
  ggc_mark_string (input_filename);

  while (stack)
    {
      ggc_mark_string (stack->name);
      stack = stack->next;
    }
}
Richard Stallman committed
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494


/* This calls abort and is used to avoid problems when abort if a macro.
   It is used when we need to pass the address of abort.  */

void
do_abort ()
{
  abort ();
}

/* When `malloc.c' is compiled with `rcheck' defined,
   it calls this function to report clobberage.  */

void
botch (s)
1495
  const char * s ATTRIBUTE_UNUSED;
Richard Stallman committed
1496 1497 1498 1499 1500
{
  abort ();
}

/* Return the logarithm of X, base 2, considering X unsigned,
1501 1502 1503
   if X is a power of 2.  Otherwise, returns -1.

   This should be used via the `exact_log2' macro.  */
Richard Stallman committed
1504 1505

int
1506 1507
exact_log2_wide (x)
     register unsigned HOST_WIDE_INT x;
Richard Stallman committed
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
{
  register int log = 0;
  /* Test for 0 or a power of 2.  */
  if (x == 0 || x != (x & -x))
    return -1;
  while ((x >>= 1) != 0)
    log++;
  return log;
}

/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
1519 1520 1521
   If X is 0, return -1.

   This should be used via the floor_log2 macro.  */
Richard Stallman committed
1522 1523

int
1524 1525
floor_log2_wide (x)
     register unsigned HOST_WIDE_INT x;
Richard Stallman committed
1526 1527 1528 1529 1530 1531 1532 1533
{
  register int log = -1;
  while (x != 0)
    log++,
    x >>= 1;
  return log;
}

1534
static int float_handler_set;
Richard Stallman committed
1535 1536 1537
int float_handled;
jmp_buf float_handler;

1538 1539 1540 1541 1542
/* Signals actually come here.  */

static void
float_signal (signo)
     /* If this is missing, some compilers complain.  */
Kaveh R. Ghazi committed
1543
     int signo ATTRIBUTE_UNUSED;
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
{
  if (float_handled == 0)
    abort ();
#if defined (USG) || defined (hpux)
  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
#endif
  float_handled = 0;
  signal (SIGFPE, float_signal);
  longjmp (float_handler, 1);
}

Richard Stallman committed
1555 1556 1557 1558 1559 1560 1561 1562 1563
/* Specify where to longjmp to when a floating arithmetic error happens.
   If HANDLER is 0, it means don't handle the errors any more.  */

void
set_float_handler (handler)
     jmp_buf handler;
{
  float_handled = (handler != 0);
  if (handler)
1564
    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
1565 1566 1567 1568 1569 1570

  if (float_handled && ! float_handler_set)
    {
      signal (SIGFPE, float_signal);
      float_handler_set = 1;
    }
Richard Stallman committed
1571 1572
}

1573 1574 1575 1576 1577 1578 1579 1580 1581
/* This is a wrapper function for code which might elicit an
   arithmetic exception.  That code should be passed in as a function
   pointer FN, and one argument DATA.  DATA is usually a struct which
   contains the real input and output for function FN.  This function
   returns 0 (failure) if longjmp was called (i.e. an exception
   occured.)  It returns 1 (success) otherwise. */

int
do_float_handler (fn, data)
1582
  void (*fn) PARAMS ((PTR));
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
  PTR data;
{
  jmp_buf buf;

  if (setjmp (buf))
    {
      /* We got here via longjmp() caused by an exception in function fn() */
      set_float_handler (NULL);
      return 0;
    }

  set_float_handler (buf);
  (*fn)(data);
  set_float_handler (NULL);
  return 1;
}

1600 1601 1602 1603 1604 1605
/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
   error happens, pushing the previous specification into OLD_HANDLER.
   Return an indication of whether there was a previous handler in effect.  */

int
push_float_handler (handler, old_handler)
1606
     jmp_buf handler, old_handler;
1607 1608 1609 1610 1611
{
  int was_handled = float_handled;

  float_handled = 1;
  if (was_handled)
1612
    memcpy ((char *) old_handler, (char *) float_handler,
1613 1614
	   sizeof (float_handler));

1615
  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628
  return was_handled;
}

/* Restore the previous specification of whether and where to longjmp to
   when a floating arithmetic error happens.  */

void
pop_float_handler (handled, handler)
     int handled;
     jmp_buf handler;
{
  float_handled = handled;
  if (handled)
1629
    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
1630 1631
}

Richard Stallman committed
1632 1633 1634 1635 1636
/* Handler for SIGPIPE.  */

static void
pipe_closed (signo)
     /* If this is missing, some compilers complain.  */
Kaveh R. Ghazi committed
1637
     int signo ATTRIBUTE_UNUSED;
Richard Stallman committed
1638 1639 1640 1641 1642
{
  fatal ("output pipe has been closed");
}

/* Strip off a legitimate source ending from the input string NAME of
1643
   length LEN.  Rather than having to know the names used by all of
Per Bothner committed
1644 1645
   our front ends, we strip off an ending of a period followed by
   up to five characters.  (Java uses ".class".) */
Richard Stallman committed
1646 1647 1648 1649 1650 1651

void
strip_off_ending (name, len)
     char *name;
     int len;
{
Per Bothner committed
1652 1653 1654 1655 1656 1657 1658 1659 1660
  int i;
  for (i = 2;  i < 6 && len > i;  i++)
    {
      if (name[len - i] == '.')
	{
	  name[len - i] = '\0';
	  break;
	}
    }
Richard Stallman committed
1661 1662
}

1663
/* Output a quoted string.  */
Mike Stump committed
1664

1665 1666 1667
void
output_quoted_string (asm_file, string)
     FILE *asm_file;
1668
     const char *string;
1669
{
1670 1671 1672
#ifdef OUTPUT_QUOTED_STRING
  OUTPUT_QUOTED_STRING (asm_file, string);
#else
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
  char c;

  putc ('\"', asm_file);
  while ((c = *string++) != 0)
    {
      if (c == '\"' || c == '\\')
	putc ('\\', asm_file);
      putc (c, asm_file);
    }
  putc ('\"', asm_file);
1683
#endif
1684 1685
}

Richard Stallman committed
1686 1687 1688 1689 1690
/* Output a file name in the form wanted by System V.  */

void
output_file_directive (asm_file, input_name)
     FILE *asm_file;
1691
     const char *input_name;
Richard Stallman committed
1692 1693
{
  int len = strlen (input_name);
1694
  const char *na = input_name + len;
Richard Stallman committed
1695 1696 1697 1698

  /* NA gets INPUT_NAME sans directory names.  */
  while (na > input_name)
    {
1699 1700
      if (IS_DIR_SEPARATOR (na[-1]))
        break;
Richard Stallman committed
1701 1702 1703 1704 1705 1706 1707 1708 1709
      na--;
    }

#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
  ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
#else
#ifdef ASM_OUTPUT_SOURCE_FILENAME
  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
#else
1710 1711 1712
  fprintf (asm_file, "\t.file\t");
  output_quoted_string (asm_file, na);
  fputc ('\n', asm_file);
Richard Stallman committed
1713 1714 1715 1716
#endif
#endif
}

1717
#ifdef ASM_IDENTIFY_LANGUAGE
Mike Stump committed
1718
/* Routine to build language identifier for object file.  */
1719 1720 1721 1722 1723 1724 1725 1726 1727
static void
output_lang_identify (asm_out_file)
     FILE *asm_out_file;
{
  int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
  char *s = (char *) alloca (len);
  sprintf (s, "__gnu_compiled_%s", lang_identify ());
  ASM_OUTPUT_LABEL (asm_out_file, s);
}
1728
#endif
1729

1730 1731 1732 1733 1734 1735
/* Routine to open a dump file.  Return true if the dump file is enabled.  */

static int
open_dump_file (index, decl)
     enum dump_file_index index;
     tree decl;
1736
{
1737 1738 1739 1740 1741 1742
  char *dump_name;
  const char *open_arg;
  char seq[16];

  if (! dump_file[index].enabled)
    return 0;
Mike Stump committed
1743

1744 1745 1746
  timevar_push (TV_DUMP);
  if (rtl_dump_file != NULL)
    fclose (rtl_dump_file);
1747
  
1748
  sprintf (seq, ".%02d.", index);
1749

1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764
  if (! dump_file[index].initialized)
    {
      /* If we've not initialized the files, do so now.  */
      if (graph_dump_format != no_graph
	  && dump_file[index].graph_dump_p)
	{
	  dump_name = concat (seq, dump_file[index].extension, NULL);
	  clean_graph_dump_file (dump_base_name, dump_name);
	  free (dump_name);
	}
      dump_file[index].initialized = 1;
      open_arg = "w";
    }
  else
    open_arg = "a";
1765

1766 1767
  dump_name = concat (dump_base_name, seq,
		      dump_file[index].extension, NULL);
1768

1769 1770 1771
  rtl_dump_file = fopen (dump_name, open_arg);
  if (rtl_dump_file == NULL)
    pfatal_with_name (dump_name);
1772
       
1773
  free (dump_name);
1774

1775 1776 1777 1778 1779
  if (decl)
    fprintf (rtl_dump_file, "\n;; Function %s\n\n",
	     decl_printable_name (decl, 2));

  timevar_pop (TV_DUMP);
1780
  return 1;
1781 1782 1783
}

/* Routine to close a dump file.  */
1784

1785
static void
1786 1787
close_dump_file (index, func, insns)
     enum dump_file_index index;
1788
     void (*func) PARAMS ((FILE *, rtx));
1789 1790
     rtx    insns;
{
1791 1792 1793
  if (! rtl_dump_file)
    return;

1794 1795 1796 1797 1798 1799 1800
  timevar_push (TV_DUMP);
  if (insns
      && graph_dump_format != no_graph
      && dump_file[index].graph_dump_p)
    {
      char seq[16];
      char *suffix;
1801

1802 1803 1804 1805 1806
      sprintf (seq, ".%02d.", index);
      suffix = concat (seq, dump_file[index].extension, NULL);
      print_rtl_graph_with_bb (dump_base_name, suffix, insns);
      free (suffix);
    }
1807

1808 1809
  if (func && insns)
    func (rtl_dump_file, insns);
1810
       
1811 1812
  fflush (rtl_dump_file);
  fclose (rtl_dump_file);
1813
       
1814 1815
  rtl_dump_file = NULL;
  timevar_pop (TV_DUMP);
1816 1817
}

1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
/* Do any final processing required for the declarations in VEC, of
   which there are LEN.  We write out inline functions and variables
   that have been deferred until this point, but which are required.
   Returns non-zero if anything was put out.  */ 
int
wrapup_global_declarations (vec, len)
     tree *vec;
     int len;
{
  tree decl;
  int i;
  int reconsider;
  int output_something = 0;

  for (i = 0; i < len; i++)
    {
      decl = vec[i];
      
      /* We're not deferring this any longer.  */
      DECL_DEFER_OUTPUT (decl) = 0;
      
      if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
	  && incomplete_decl_finalize_hook != 0)
	(*incomplete_decl_finalize_hook) (decl);
    }

  /* Now emit any global variables or functions that we have been
     putting off.  We need to loop in case one of the things emitted
     here references another one which comes earlier in the list.  */
  do
    {
      reconsider = 0;
      for (i = 0; i < len; i++)
	{
	  decl = vec[i];

	  if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
	    continue;

	  /* Don't write out static consts, unless we still need them.

	     We also keep static consts if not optimizing (for debugging),
	     unless the user specified -fno-keep-static-consts.
	     ??? They might be better written into the debug information.
	     This is possible when using DWARF.

	     A language processor that wants static constants to be always
	     written out (even if it is not used) is responsible for
	     calling rest_of_decl_compilation itself.  E.g. the C front-end
	     calls rest_of_decl_compilation from finish_decl.
	     One motivation for this is that is conventional in some
	     environments to write things like:
	     static const char rcsid[] = "... version string ...";
	     intending to force the string to be in the executable.

	     A language processor that would prefer to have unneeded
	     static constants "optimized away" would just defer writing
	     them out until here.  E.g. C++ does this, because static
	     constants are often defined in header files.

	     ??? A tempting alternative (for both C and C++) would be
	     to force a constant to be written if and only if it is
	     defined in a main file, as opposed to an include file.  */

	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
	      && (! TREE_READONLY (decl)
		  || TREE_PUBLIC (decl)
		  || (!optimize && flag_keep_static_consts)
		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
	    {
	      reconsider = 1;
	      rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
	    }

	  if (TREE_CODE (decl) == FUNCTION_DECL
	      && DECL_INITIAL (decl) != 0
	      && DECL_SAVED_INSNS (decl) != 0
	      && (flag_keep_inline_functions
1896
		  || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940
		  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
	    {
	      reconsider = 1;
	      temporary_allocation ();
	      output_inline_function (decl);
	      permanent_allocation (1);
	    }
	}

      if (reconsider)
	output_something = 1;
    }
  while (reconsider);

  return output_something;
}

/* Issue appropriate warnings for the global declarations in VEC (of
   which there are LEN).  Output debugging information for them.  */
void
check_global_declarations (vec, len)
     tree *vec;
     int len;
{
  tree decl;
  int i;

  for (i = 0; i < len; i++)
    {
      decl = vec[i];

      if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
	  && ! TREE_ASM_WRITTEN (decl))
	/* Cancel the RTL for this decl so that, if debugging info
	   output for global variables is still to come,
	   this one will be omitted.  */
	DECL_RTL (decl) = NULL;

      /* Warn about any function
	 declared static but not defined.
	 We don't warn about variables,
	 because many programs have static variables
	 that exist only to get some text into the object file.  */
      if (TREE_CODE (decl) == FUNCTION_DECL
1941
	  && (warn_unused_function
1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
	  && DECL_INITIAL (decl) == 0
	  && DECL_EXTERNAL (decl)
	  && ! DECL_ARTIFICIAL (decl)
	  && ! TREE_PUBLIC (decl))
	{
	  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
	    pedwarn_with_decl (decl,
			       "`%s' used but never defined");
	  else
	    warning_with_decl (decl,
			       "`%s' declared `static' but never defined");
	  /* This symbol is effectively an "extern" declaration now.  */
	  TREE_PUBLIC (decl) = 1;
	  assemble_external (decl);
	}

      /* Warn about static fns or vars defined but not used,
	 but not about inline functions or static consts
	 since defining those in header files is normal practice.  */
1962 1963 1964 1965
      if (((warn_unused_function
	    && TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
	   || (warn_unused_variable
	       && TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
	  && ! DECL_IN_SYSTEM_HEADER (decl)
	  && ! DECL_EXTERNAL (decl)
	  && ! TREE_PUBLIC (decl)
	  && ! TREE_USED (decl)
	  && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl))
	  /* The TREE_USED bit for file-scope decls
	     is kept in the identifier, to handle multiple
	     external decls in different scopes.  */
	  && ! TREE_USED (DECL_NAME (decl)))
	warning_with_decl (decl, "`%s' defined but not used");

1977
      timevar_push (TV_SYMOUT);
1978 1979 1980 1981 1982 1983 1984 1985 1986
#ifdef SDB_DEBUGGING_INFO
      /* The COFF linker can move initialized global vars to the end.
	 And that can screw up the symbol ordering.
	 By putting the symbols in that order to begin with,
	 we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
	  && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
	  && ! DECL_EXTERNAL (decl)
	  && DECL_RTL (decl) != 0)
1987
	sdbout_symbol (decl, 0);
1988 1989 1990 1991 1992 1993 1994 1995 1996

      /* Output COFF information for non-global
	 file-scope initialized variables.  */
      if (write_symbols == SDB_DEBUG
	  && TREE_CODE (decl) == VAR_DECL
	  && DECL_INITIAL (decl)
	  && ! DECL_EXTERNAL (decl)
	  && DECL_RTL (decl) != 0
	  && GET_CODE (DECL_RTL (decl)) == MEM)
1997
	sdbout_toplevel_data (decl);
1998 1999 2000 2001 2002 2003 2004 2005 2006
#endif /* SDB_DEBUGGING_INFO */
#ifdef DWARF_DEBUGGING_INFO
      /* Output DWARF information for file-scope tentative data object
	 declarations, file-scope (extern) function declarations (which
	 had no corresponding body) and file-scope tagged type declarations
	 and definitions which have not yet been forced out.  */

      if (write_symbols == DWARF_DEBUG
	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
2007
	dwarfout_file_scope_decl (decl, 1);
2008 2009 2010 2011 2012 2013 2014 2015 2016
#endif
#ifdef DWARF2_DEBUGGING_INFO
      /* Output DWARF2 information for file-scope tentative data object
	 declarations, file-scope (extern) function declarations (which
	 had no corresponding body) and file-scope tagged type declarations
	 and definitions which have not yet been forced out.  */

      if (write_symbols == DWARF2_DEBUG
	  && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
2017
	dwarf2out_decl (decl);
2018
#endif
2019
      timevar_pop (TV_SYMOUT);
2020 2021
    }
}
2022

2023 2024 2025 2026 2027 2028
/* Save the current INPUT_FILENAME and LINENO on the top entry in the
   INPUT_FILE_STACK.  Push a new entry for FILE and LINE, and set the
   INPUT_FILENAME and LINENO accordingly.  */

void
push_srcloc (file, line)
Zack Weinberg committed
2029
     const char *file;
2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068
     int line;
{
  struct file_stack *fs;

  if (input_file_stack)
    {
      input_file_stack->name = input_filename;
      input_file_stack->line = lineno;
    }

  fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
  fs->name = input_filename = file;
  fs->line = lineno = line;
  fs->indent_level = 0;
  fs->next = input_file_stack;
  input_file_stack = fs;
  input_file_stack_tick++;
}

/* Pop the top entry off the stack of presently open source files.
   Restore the INPUT_FILENAME and LINENO from the new topmost entry on
   the stack.  */

void
pop_srcloc ()
{
  struct file_stack *fs;
  
  fs = input_file_stack;
  input_file_stack = fs->next;
  free (fs);
  input_file_stack_tick++;
  /* The initial souce file is never popped.  */
  if (!input_file_stack)
    abort ();
  input_filename = input_file_stack->name;
  lineno = input_file_stack->line;
}

Richard Stallman committed
2069 2070 2071 2072 2073
/* Compile an entire file of output from cpp, named NAME.
   Write a file of assembly output and various debugging dumps.  */

static void
compile_file (name)
Zack Weinberg committed
2074
     const char *name;
Richard Stallman committed
2075 2076 2077 2078 2079 2080 2081 2082
{
  tree globals;

  int name_specified = name != 0;

  if (dump_base_name == 0)
    dump_base_name = name ? name : "gccdump";

2083
  /* Start timing total execution time.  */
Richard Stallman committed
2084

2085 2086 2087
  init_timevar ();
  timevar_start (TV_TOTAL);
  
Richard Stallman committed
2088 2089 2090 2091
  /* Initialize data in various passes.  */

  init_obstacks ();
  init_tree_codes ();
2092
  name = init_parse (name);
Richard Stallman committed
2093
  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
2094
		  || debug_info_level == DINFO_LEVEL_VERBOSE
2095 2096
		  || flag_test_coverage
		  || warn_notreached);
2097
  init_regs ();
2098
  init_alias_once ();
Richard Stallman committed
2099 2100 2101
  init_decl_processing ();
  init_optabs ();
  init_stmt ();
2102
  init_eh ();
Richard Stallman committed
2103 2104
  init_loop ();
  init_reload ();
2105
  init_function_once ();
2106
  init_stor_layout_once ();
2107
  init_varasm_once ();
Richard Stallman committed
2108

2109 2110 2111 2112 2113
  /* The following initialization functions need to generate rtl, so
     provide a dummy function context for them.  */
  init_dummy_function_start ();
  init_expmed ();
  init_expr_once ();
Richard Stallman committed
2114 2115
  if (flag_caller_saves)
    init_caller_save ();
2116
  expand_dummy_function_end ();
Richard Stallman committed
2117

2118 2119 2120
  /* If auxiliary info generation is desired, open the output file.
     This goes in the same directory as the source file--unlike
     all the other output files.  */
Richard Stallman committed
2121 2122 2123 2124 2125 2126 2127 2128 2129
  if (flag_gen_aux_info)
    {
      aux_info_file = fopen (aux_info_file_name, "w");
      if (aux_info_file == 0)
	pfatal_with_name (aux_info_file_name);
    }

  /* Open assembler code output file.  */

2130 2131
  if (flag_syntax_only)
    asm_out_file = NULL;
Richard Stallman committed
2132 2133
  else
    {
2134
      if (! name_specified && asm_file_name == 0)
Richard Stallman committed
2135 2136
	asm_out_file = stdout;
      else
2137 2138
	{
	  if (asm_file_name == 0)
2139 2140 2141 2142 2143 2144 2145 2146
	    {
	      int len = strlen (dump_base_name);
	      char *dumpname = (char *) xmalloc (len + 6);
	      memcpy (dumpname, dump_base_name, len + 1);
	      strip_off_ending (dumpname, len);
	      strcat (dumpname, ".s");
	      asm_file_name = dumpname;
	    }
2147 2148 2149 2150 2151 2152 2153
	  if (!strcmp (asm_file_name, "-"))
	    asm_out_file = stdout;
	  else
	    asm_out_file = fopen (asm_file_name, "w");
	  if (asm_out_file == 0)
	    pfatal_with_name (asm_file_name);
	}
Richard Stallman committed
2154

2155
#ifdef IO_BUFFER_SIZE
2156 2157
      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
	       _IOFBF, IO_BUFFER_SIZE);
2158
#endif
2159
    }
2160

2161
  if (ggc_p && name != 0)
2162
    name = ggc_alloc_string (name, strlen (name));
2163

Richard Stallman committed
2164 2165
  input_filename = name;

2166
  /* Put an entry on the input file stack for the main input file.  */
2167
  push_srcloc (input_filename, 0);
2168

Richard Stallman committed
2169 2170 2171 2172 2173 2174 2175 2176 2177
  /* Perform language-specific initialization.
     This may set main_input_filename.  */
  lang_init ();

  /* If the input doesn't start with a #line, use the input name
     as the official input file name.  */
  if (main_input_filename == 0)
    main_input_filename = name;

2178 2179 2180 2181 2182 2183 2184 2185 2186
  if (flag_syntax_only)
    {
      write_symbols = NO_DEBUG;
      profile_flag = 0;
      profile_block_flag = 0;
    }
  else
    {
      ASM_FILE_START (asm_out_file);
2187 2188

#ifdef ASM_COMMENT_START
2189 2190 2191 2192 2193
      if (flag_verbose_asm)
	{
	  /* Print the list of options in effect.  */
	  print_version (asm_out_file, ASM_COMMENT_START);
	  print_switch_values (asm_out_file, 0, MAX_LINE,
2194
			       ASM_COMMENT_START, " ", "\n");
2195 2196 2197 2198
	  /* Add a blank line here so it appears in assembler output but not
	     screen output.  */
	  fprintf (asm_out_file, "\n");
	}
2199
#endif
Richard Stallman committed
2200

2201
      /* Output something to inform GDB that this compilation was by GCC.  */
Richard Stallman committed
2202
#ifndef ASM_IDENTIFY_GCC
2203
      fprintf (asm_out_file, "gcc2_compiled.:\n");
Richard Stallman committed
2204
#else
2205
      ASM_IDENTIFY_GCC (asm_out_file);
Richard Stallman committed
2206
#endif
2207

Mike Stump committed
2208
  /* Output something to identify which front-end produced this file.  */
2209
#ifdef ASM_IDENTIFY_LANGUAGE
2210
      ASM_IDENTIFY_LANGUAGE (asm_out_file);
2211
#endif
2212
    } /* ! flag_syntax_only */
2213

2214 2215 2216 2217 2218 2219
#ifndef ASM_OUTPUT_SECTION_NAME
  if (flag_function_sections)
    {
      warning ("-ffunction-sections not supported for this target.");
      flag_function_sections = 0;
    }
Catherine Moore committed
2220 2221 2222 2223 2224
  if (flag_data_sections)
    {
      warning ("-fdata-sections not supported for this target.");
      flag_data_sections = 0;
    }
2225 2226 2227 2228 2229 2230 2231 2232 2233
#endif

  if (flag_function_sections
      && (profile_flag || profile_block_flag))
    {
      warning ("-ffunction-sections disabled; it makes profiling impossible.");
      flag_function_sections = 0;
    }

2234
#ifndef OBJECT_FORMAT_ELF
2235 2236
  if (flag_function_sections && write_symbols != NO_DEBUG)
    warning ("-ffunction-sections may affect debugging on some targets.");
2237
#endif
2238

2239 2240 2241 2242 2243 2244 2245 2246 2247
  /* ??? Note: There used to be a conditional here
      to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
      This was to guarantee separation between gcc_compiled. and
      the first function, for the sake of dbx on Suns.
      However, having the extra zero here confused the Emacs
      code for unexec, and might confuse other programs too.
      Therefore, I took out that change.
      In future versions we should find another way to solve
      that dbx problem.  -- rms, 23 May 93.  */
Jan Brittenson committed
2248
      
2249 2250 2251
  /* Don't let the first function fall at the same address
     as gcc_compiled., if profiling.  */
  if (profile_flag || profile_block_flag)
2252 2253 2254
    {
      /* It's best if we can write a nop here since some
	 assemblers don't tolerate zeros in the text section.  */
2255
      output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL_PTR);
2256
    }
Richard Stallman committed
2257 2258 2259

  /* If dbx symbol table desired, initialize writing it
     and output the predefined types.  */
2260
  timevar_push (TV_SYMOUT);
2261 2262
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2263
    dbxout_init (asm_out_file, main_input_filename, getdecls ());
Richard Stallman committed
2264 2265 2266
#endif
#ifdef SDB_DEBUGGING_INFO
  if (write_symbols == SDB_DEBUG)
2267
    sdbout_init (asm_out_file, main_input_filename, getdecls ());
Richard Stallman committed
2268 2269 2270
#endif
#ifdef DWARF_DEBUGGING_INFO
  if (write_symbols == DWARF_DEBUG)
2271
    dwarfout_init (asm_out_file, main_input_filename);
Richard Stallman committed
2272
#endif
Jason Merrill committed
2273 2274 2275 2276
#ifdef DWARF2_UNWIND_INFO
  if (dwarf2out_do_frame ())
    dwarf2out_frame_init ();
#endif
x  
Jason Merrill committed
2277 2278
#ifdef DWARF2_DEBUGGING_INFO
  if (write_symbols == DWARF2_DEBUG)
2279
    dwarf2out_init (asm_out_file, main_input_filename);
x  
Jason Merrill committed
2280
#endif
2281
  timevar_pop (TV_SYMOUT);
Richard Stallman committed
2282 2283 2284

  /* Initialize yet another pass.  */

2285
  init_final (main_input_filename);
2286
  init_branch_prob (dump_base_name);
Richard Stallman committed
2287

2288
  timevar_push (TV_PARSE);
Richard Stallman committed
2289 2290 2291 2292 2293

  /* Call the parser, which parses the entire file
     (calling rest_of_compilation for each function).  */

  if (yyparse () != 0)
2294 2295
    {
      if (errorcount == 0)
2296
	fnotice (stderr, "Errors detected in input file (your bison.simple is out of date)\n");
2297 2298 2299 2300 2301 2302

      /* In case there were missing closebraces,
	 get us back to the global binding level.  */
      while (! global_bindings_p ())
	poplevel (0, 0, 0);
    }
Richard Stallman committed
2303 2304 2305 2306

  /* Compilation is now finished except for writing
     what's left of the symbol table output.  */

2307
  timevar_pop (TV_PARSE);
Richard Stallman committed
2308

2309 2310 2311
  if (flag_syntax_only)
    goto finish_syntax;

Richard Stallman committed
2312 2313 2314 2315 2316 2317 2318 2319
  globals = getdecls ();

  /* Really define vars that have had only a tentative definition.
     Really output inline functions that must actually be callable
     and have not been output so far.  */

  {
    int len = list_length (globals);
2320
    tree *vec = (tree *) xmalloc (sizeof (tree) * len);
Richard Stallman committed
2321 2322 2323 2324 2325 2326 2327 2328 2329
    int i;
    tree decl;

    /* Process the decls in reverse order--earliest first.
       Put them into VEC from back to front, then take out from front.  */

    for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
      vec[len - i - 1] = decl;

2330
    wrapup_global_declarations (vec, len);
Richard Stallman committed
2331

2332 2333 2334 2335 2336 2337 2338 2339 2340
    /* This must occur after the loop to output deferred functions.  Else
       the profiler initializer would not be emitted if all the functions
       in this compilation unit were deferred.

       output_func_start_profiler can not cause any additional functions or
       data to need to be output, so it need not be in the deferred function
       loop above.  */
    output_func_start_profiler ();

Mike Stump committed
2341 2342 2343
    /* Now that all possible functions have been output, we can dump
       the exception table.  */

2344
#ifndef IA64_UNWIND_INFO
Jason Merrill committed
2345
    output_exception_table ();
2346 2347 2348
#endif
    free_exception_table ();
    
2349
    check_global_declarations (vec, len);
2350 2351 2352

    /* Clean up.  */
    free (vec);
Richard Stallman committed
2353 2354
  }

2355 2356 2357 2358
  /* Write out any pending weak symbol declarations.  */

  weak_finish ();

Richard Stallman committed
2359
  /* Do dbx symbols */
2360
  timevar_push (TV_SYMOUT);
2361 2362
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2363
    dbxout_finish (asm_out_file, main_input_filename);
Richard Stallman committed
2364 2365 2366 2367
#endif

#ifdef DWARF_DEBUGGING_INFO
  if (write_symbols == DWARF_DEBUG)
2368
    dwarfout_finish ();
Richard Stallman committed
2369 2370
#endif

Jason Merrill committed
2371 2372 2373 2374 2375
#ifdef DWARF2_UNWIND_INFO
  if (dwarf2out_do_frame ())
    dwarf2out_frame_finish ();
#endif

x  
Jason Merrill committed
2376 2377
#ifdef DWARF2_DEBUGGING_INFO
  if (write_symbols == DWARF2_DEBUG)
2378
    dwarf2out_finish ();
x  
Jason Merrill committed
2379
#endif
2380
  timevar_pop (TV_SYMOUT);
x  
Jason Merrill committed
2381

Richard Stallman committed
2382 2383
  /* Output some stuff at end of file if nec.  */

2384
  end_final (dump_base_name);
2385
   
2386
  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
2387
    {
2388
      timevar_push (TV_DUMP);
2389
      open_dump_file (DFI_bp, NULL);
2390 2391 2392

      end_branch_prob ();

2393
      close_dump_file (DFI_bp, NULL, NULL_RTX);
2394
      timevar_pop (TV_DUMP);
2395
    }
2396
   
Richard Stallman committed
2397
#ifdef ASM_FILE_END
2398
  ASM_FILE_END (asm_out_file);
Richard Stallman committed
2399 2400 2401
#endif

  /* Language-specific end of compilation actions.  */
2402
 finish_syntax:
Richard Stallman committed
2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413
  lang_finish ();

  /* Close the dump files.  */

  if (flag_gen_aux_info)
    {
      fclose (aux_info_file);
      if (errorcount)
	unlink (aux_info_file_name);
    }

2414
  if (optimize > 0 && open_dump_file (DFI_combine, NULL))
Richard Stallman committed
2415
    {
2416 2417
      timevar_push (TV_DUMP);
      dump_combine_total_stats (rtl_dump_file);
2418
      close_dump_file (DFI_combine, NULL, NULL_RTX);
2419
      timevar_pop (TV_DUMP);
Richard Stallman committed
2420 2421 2422 2423 2424 2425
    }

  /* Close non-debugging input and output files.  Take special care to note
     whether fclose returns an error, since the pages might still be on the
     buffer chain while the file is open.  */

2426
  finish_parse ();
2427

2428 2429
  if (! flag_syntax_only
      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
Richard Stallman committed
2430 2431
    fatal_io_error (asm_file_name);

2432 2433 2434
  /* Do whatever is necessary to finish printing the graphs.  */
  if (graph_dump_format != no_graph)
    {
2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447
      int i;

      for (i = 0; i < DFI_MAX; ++i)
	if (dump_file[i].initialized && dump_file[i].graph_dump_p)
	  {
	    char seq[16];
	    char *suffix;

	    sprintf (seq, ".%02d.", i);
	    suffix = concat (seq, dump_file[i].extension, NULL);
	    finish_graph_dump_file (dump_base_name, suffix);
	    free (suffix);
	  }
2448 2449
    }

2450 2451 2452
  /* Free up memory for the benefit of leak detectors.  */
  free_reg_info ();

2453 2454 2455
  /* Stop timing total execution time.  */
  timevar_stop (TV_TOTAL);

Richard Stallman committed
2456 2457
  /* Print the times.  */

2458
  timevar_print (stderr);
Richard Stallman committed
2459 2460 2461 2462 2463
}

/* This is called from various places for FUNCTION_DECL, VAR_DECL,
   and TYPE_DECL nodes.

2464 2465 2466 2467 2468
   This does nothing for local (non-static) variables, unless the
   variable is a register variable with an ASMSPEC.  In that case, or
   if the variable is not an automatice, it sets up the RTL and
   outputs any assembler code (label definition, storage allocation
   and initialization).
Richard Stallman committed
2469 2470 2471 2472 2473 2474 2475 2476

   DECL is the declaration.  If ASMSPEC is nonzero, it specifies
   the assembler symbol name to be used.  TOP_LEVEL is nonzero
   if this declaration is not within a function.  */

void
rest_of_decl_compilation (decl, asmspec, top_level, at_end)
     tree decl;
2477
     const char *asmspec;
Richard Stallman committed
2478 2479 2480 2481 2482
     int top_level;
     int at_end;
{
  /* Declarations of variables, and of functions defined elsewhere.  */

2483 2484 2485 2486 2487 2488
/* The most obvious approach, to put an #ifndef around where
   this macro is used, doesn't work since it's inside a macro call.  */
#ifndef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
#endif

Richard Stallman committed
2489 2490
  /* Forward declarations for nested functions are not "external",
     but we need to treat them as if they were.  */
2491
  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
Richard Stallman committed
2492
      || TREE_CODE (decl) == FUNCTION_DECL)
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516
    {
      timevar_push (TV_VARCONST);
      make_decl_rtl (decl, asmspec, top_level);
      /* Initialized extern variable exists to be replaced
	 with its value, or represents something that will be
	 output in another file.  */
      if (! (TREE_CODE (decl) == VAR_DECL
	     && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
	     && DECL_INITIAL (decl) != 0
	     && DECL_INITIAL (decl) != error_mark_node))
	/* Don't output anything
	     when a tentative file-scope definition is seen.
	     But at end of compilation, do output code for them.  */
	if (! (! at_end && top_level
	       && (DECL_INITIAL (decl) == 0
		   || DECL_INITIAL (decl) == error_mark_node)))
	  assemble_variable (decl, top_level, at_end, 0);
      if (decl == last_assemble_variable_decl)
	{
	  ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
				     top_level, at_end);
	}
      timevar_pop (TV_VARCONST);
    }
2517
  else if (DECL_REGISTER (decl) && asmspec != 0)
Richard Stallman committed
2518 2519 2520 2521 2522 2523 2524 2525 2526
    {
      if (decode_reg_name (asmspec) >= 0)
	{
	  DECL_RTL (decl) = 0;
	  make_decl_rtl (decl, asmspec, top_level);
	}
      else
	error ("invalid register name `%s' for register variable", asmspec);
    }
2527 2528 2529
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
	   && TREE_CODE (decl) == TYPE_DECL)
2530 2531 2532 2533 2534
    {
      timevar_push (TV_SYMOUT);
      dbxout_symbol (decl, 0);
      timevar_pop (TV_SYMOUT);
    }
Richard Stallman committed
2535 2536 2537 2538
#endif
#ifdef SDB_DEBUGGING_INFO
  else if (write_symbols == SDB_DEBUG && top_level
	   && TREE_CODE (decl) == TYPE_DECL)
2539 2540 2541 2542 2543
    {
      timevar_push (TV_SYMOUT);
      sdbout_symbol (decl, 0);
      timevar_pop (TV_SYMOUT);
    }
Richard Stallman committed
2544 2545 2546 2547 2548 2549 2550
#endif
}

/* Called after finishing a record, union or enumeral type.  */

void
rest_of_type_compilation (type, toplev)
2551
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
Richard Stallman committed
2552 2553
     tree type;
     int toplev;
2554 2555 2556 2557
#else
     tree type ATTRIBUTE_UNUSED;
     int toplev ATTRIBUTE_UNUSED;
#endif
Richard Stallman committed
2558
{
2559
  timevar_push (TV_SYMOUT);
2560 2561
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2562
    dbxout_symbol (TYPE_STUB_DECL (type), !toplev);
Richard Stallman committed
2563 2564 2565
#endif
#ifdef SDB_DEBUGGING_INFO
  if (write_symbols == SDB_DEBUG)
2566
    sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
Richard Stallman committed
2567
#endif
2568
  timevar_pop (TV_SYMOUT);
Richard Stallman committed
2569 2570
}

2571 2572 2573 2574 2575 2576 2577 2578 2579 2580
/* DECL is an inline function, whose body is present, but which is not
   being output at this point.  (We're putting that off until we need
   to do it.)  If there are any actions that need to take place,
   including the emission of debugging information for the function,
   this is where they should go.  This function may be called by
   language-dependent code for front-ends that do not even generate
   RTL for functions that don't need to be put out.  */

void
note_deferral_of_defined_inline_function (decl)
2581
     tree decl ATTRIBUTE_UNUSED;
2582 2583 2584 2585 2586
{
#ifdef DWARF_DEBUGGING_INFO
  /* Generate the DWARF info for the "abstract" instance of a function
     which we may later generate inlined and/or out-of-line instances
     of.  */
2587
  if (write_symbols == DWARF_DEBUG && DECL_INLINE (decl))
2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606
    {
      /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
	 DWARF code expects it to be set in this case.  Intuitively,
	 DECL is the function we just finished defining, so setting
	 CURRENT_FUNCTION_DECL is sensible.  */
      tree saved_cfd = current_function_decl;
      current_function_decl = decl;

      /* Let the DWARF code do its work.  */
      set_decl_abstract_flags (decl, 1);
      dwarfout_file_scope_decl (decl, 0);
      set_decl_abstract_flags (decl, 0);

      /* Reset CURRENT_FUNCTION_DECL.  */
      current_function_decl = saved_cfd;
    }
#endif
}

Richard Stallman committed
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
/* This is called from finish_function (within yyparse)
   after each top-level definition is parsed.
   It is supposed to compile that function or variable
   and output the assembler code for it.
   After we return, the tree storage is freed.  */

void
rest_of_compilation (decl)
     tree decl;
{
  register rtx insns;
  int tem;
2619
  int failure = 0;
2620
  int rebuild_label_notes_after_reload;
2621
  int register_life_up_to_date;
Richard Stallman committed
2622

2623 2624
  timevar_push (TV_REST_OF_COMPILATION);

2625 2626 2627 2628
  /* When processing delayed functions, prepare_function_start() won't
     have been run to re-initialize it.  */
  cse_not_expected = ! optimize;

2629 2630
  /* First, make sure that NOTE_BLOCK is set correctly for each
     NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
2631 2632
  if (!cfun->x_whole_function_mode_p)
    identify_blocks ();
2633 2634

  /* Then remove any notes we don't need.  That will make iterating
2635 2636
     over the instruction sequence faster, and allow the garbage
     collector to reclaim the memory used by the notes.  */
2637
  remove_unnecessary_notes ();
2638

2639 2640
  /* In function-at-a-time mode, we do not attempt to keep the BLOCK
     tree in sensible shape.  So, we just recalculate it here.  */
Bernd Schmidt committed
2641
  if (cfun->x_whole_function_mode_p)
2642
    reorder_blocks ();
2643

Richard Stallman committed
2644 2645 2646 2647 2648
  /* If we are reconsidering an inline function
     at the end of compilation, skip the stuff for making it inline.  */

  if (DECL_SAVED_INSNS (decl) == 0)
    {
Jeff Law committed
2649
      int inlinable = 0;
Richard Kenner committed
2650
      tree parent;
2651
      const char *lose;
Richard Stallman committed
2652

Richard Kenner committed
2653 2654 2655 2656 2657
      /* If this is nested inside an inlined external function, pretend
	 it was only declared.  Since we cannot inline such functions,
	 generating code for this one is not only not necessary but will
	 confuse some debugging output writers.  */
      for (parent = DECL_CONTEXT (current_function_decl);
2658 2659
	   parent != NULL_TREE; 
	   parent = get_containing_scope (parent))
2660 2661
	if (TREE_CODE (parent) == FUNCTION_DECL
	    && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
Richard Kenner committed
2662 2663 2664 2665 2666
	  {
	    DECL_INITIAL (decl) = 0;
	    goto exit_rest_of_compilation;
	  }

Richard Stallman committed
2667
      /* If requested, consider whether to make this function inline.  */
2668
      if (DECL_INLINE (decl) || flag_inline_functions)
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693
	{
	  timevar_push (TV_INTEGRATION);
	  lose = function_cannot_inline_p (decl);
	  timevar_pop (TV_INTEGRATION);
	  if (lose || ! optimize)
	    {
	      if (warn_inline && DECL_INLINE (decl))
		warning_with_decl (decl, lose);
	      DECL_ABSTRACT_ORIGIN (decl) = 0;
	      /* Don't really compile an extern inline function.
		 If we can't make it inline, pretend
		 it was only declared.  */
	      if (DECL_EXTERNAL (decl))
		{
		  DECL_INITIAL (decl) = 0;
		  goto exit_rest_of_compilation;
		}
	    }
	  else
	    /* ??? Note that this has the effect of making it look
		 like "inline" was specified for a function if we choose
		 to inline it.  This isn't quite right, but it's
		 probably not worth the trouble to fix.  */
	    inlinable = DECL_INLINE (decl) = 1;
	}
Richard Stallman committed
2694 2695 2696 2697 2698

      insns = get_insns ();

      /* Dump the rtl code if we are dumping rtl.  */

2699
      if (open_dump_file (DFI_rtl, decl))
2700 2701 2702
	{
	  if (DECL_SAVED_INSNS (decl))
	    fprintf (rtl_dump_file, ";; (integrable)\n\n");
2703
	  close_dump_file (DFI_rtl, print_rtl, insns);
2704
	}
Richard Stallman committed
2705 2706 2707 2708

      /* If function is inline, and we don't yet know whether to
	 compile it by itself, defer decision till end of compilation.
	 finish_compilation will call rest_of_compilation again
2709
	 for those functions that need to be output.  Also defer those
2710 2711
	 functions that we are supposed to defer.  */

2712
      if (inlinable
2713 2714 2715 2716
	  || (DECL_INLINE (decl)
	      && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
		   && ! flag_keep_inline_functions)
		  || DECL_EXTERNAL (decl))))
2717
	DECL_DEFER_OUTPUT (decl) = 1;
2718

2719 2720 2721 2722 2723 2724 2725 2726
      if (DECL_INLINE (decl))
	/* DWARF wants seperate debugging info for abstract and
	   concrete instances of all inline functions, including those
	   declared inline but not inlined, and those inlined even
	   though they weren't declared inline.  Conveniently, that's
	   what DECL_INLINE means at this point.  */
	note_deferral_of_defined_inline_function (decl);

2727 2728
      if (DECL_DEFER_OUTPUT (decl))
	{
2729 2730 2731 2732 2733 2734 2735 2736 2737
	  /* If -Wreturn-type, we have to do a bit of compilation.
	     However, if we just fall through we will call
	     save_for_inline_copying() which results in excessive
	     memory use.  Instead, we just want to call
	     jump_optimize() to figure out whether or not we can fall
	     off the end of the function; we do the minimum amount of
	     work necessary to make that safe.  And, we set optimize
	     to zero to keep jump_optimize from working too hard.  */
	  if (warn_return_type)
Richard Stallman committed
2738
	    {
2739 2740 2741
	      int saved_optimize = optimize;
	      optimize = 0;
	      find_exception_handler_labels ();
2742
	      jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
2743
			     !JUMP_AFTER_REGSCAN);
2744 2745 2746
	      optimize = saved_optimize;
	    }

2747 2748 2749 2750 2751 2752
	  current_function_nothrow = nothrow_function_p ();
	  if (current_function_nothrow)
	    /* Now we know that this can't throw; set the flag for the benefit
	       of other functions later in this translation unit.  */
	    TREE_NOTHROW (current_function_decl) = 1;

2753 2754 2755
	  timevar_push (TV_INTEGRATION);
	  save_for_inline_nocopy (decl);
	  timevar_pop (TV_INTEGRATION);
2756
	  DECL_SAVED_INSNS (decl)->inlinable = inlinable;
2757
	  goto exit_rest_of_compilation;
Richard Stallman committed
2758 2759
	}

2760
      /* If specified extern inline but we aren't inlining it, we are
2761 2762 2763
	 done.  This goes for anything that gets here with DECL_EXTERNAL
	 set, not just things with DECL_INLINE.  */
      if (DECL_EXTERNAL (decl))
2764 2765
	goto exit_rest_of_compilation;
    }
2766

2767 2768
  init_EXPR_INSN_LIST_cache ();

2769 2770 2771
  if (ggc_p)
    ggc_collect ();

2772 2773 2774
  /* Initialize some variables used by the optimizers.  */
  init_function_for_compilation ();

2775 2776
  if (! DECL_DEFER_OUTPUT (decl))
    TREE_ASM_WRITTEN (decl) = 1;
Richard Stallman committed
2777 2778 2779 2780 2781 2782

  /* Now that integrate will no longer see our rtl, we need not distinguish
     between the return value of this function and the return value of called
     functions.  */
  rtx_equal_function_value_matters = 0;

2783 2784
  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
  if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
2785
    goto exit_rest_of_compilation;
Richard Stallman committed
2786

Teemu Torma committed
2787 2788 2789
  /* Emit code to get eh context, if needed. */
  emit_eh_context ();

2790 2791 2792 2793
  /* We may have potential sibling or tail recursion sites.  Select one
     (of possibly multiple) methods of performing the call.  */
  if (flag_optimize_sibling_calls)
    {
2794
      timevar_push (TV_JUMP);
2795 2796
      open_dump_file (DFI_sibling, decl);

2797
      optimize_sibling_and_tail_recursive_calls ();
2798 2799

      close_dump_file (DFI_sibling, print_rtl, get_insns ());
2800
      timevar_pop (TV_JUMP);
2801
    }
2802

Richard Stallman committed
2803 2804 2805 2806 2807 2808 2809 2810 2811
#ifdef FINALIZE_PIC
  /* If we are doing position-independent code generation, now
     is the time to output special prologues and epilogues.
     We do not want to do this earlier, because it just clutters
     up inline functions with meaningless insns.  */
  if (flag_pic)
    FINALIZE_PIC;
#endif

2812 2813 2814 2815 2816 2817 2818 2819
  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
     Note that that may have been done above, in save_for_inline_copying.
     The call to resume_temporary_allocation near the end of this function
     goes back to the usual state of affairs.  This must be done after
     we've built up any unwinders for exception handling, and done
     the FINALIZE_PIC work, if necessary.  */

  rtl_in_current_obstack ();
Mike Stump committed
2820

Richard Stallman committed
2821 2822 2823
  insns = get_insns ();

  /* Copy any shared structure that should not be shared.  */
2824
  unshare_all_rtl (current_function_decl, insns);
Richard Stallman committed
2825

2826 2827 2828 2829 2830 2831
#ifdef SETJMP_VIA_SAVE_AREA
  /* This must be performed before virutal register instantiation.  */
  if (current_function_calls_alloca)
    optimize_save_area_alloca (insns);
#endif

Richard Stallman committed
2832
  /* Instantiate all virtual registers.  */
2833
  instantiate_virtual_regs (current_function_decl, insns);
Richard Stallman committed
2834

Mike Stump committed
2835 2836 2837
  /* Find all the EH handlers.  */
  find_exception_handler_labels ();

2838
  open_dump_file (DFI_jump, decl);
2839

2840 2841 2842
  /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
     are initialized and to compute whether control can drop off the end
     of the function.  */
2843

2844 2845 2846 2847 2848 2849 2850 2851 2852 2853
  timevar_push (TV_JUMP);
  /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB.  Do this
     before jump optimization switches branch directions.  */
  expected_value_to_br_prob ();

  reg_scan (insns, max_reg_num (), 0);
  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
		 JUMP_AFTER_REGSCAN);

  timevar_pop (TV_JUMP);
2854

2855
  /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
2856
  if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
2857 2858 2859 2860 2861
    {
      close_dump_file (DFI_jump, print_rtl, insns);
      goto exit_rest_of_compilation;
    }

2862
  timevar_push (TV_JUMP);
Richard Henderson committed
2863 2864

  if (optimize > 0)
2865 2866 2867
    {
      find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
      cleanup_cfg (insns);
Richard Henderson committed
2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879

      /* ??? Run if-conversion before delete_null_pointer_checks,
         since the later does not preserve the CFG.  This should
	 be changed -- no since converting if's that are going to
	 be deleted.  */
      timevar_push (TV_IFCVT);
      if_convert (0);
      timevar_pop (TV_IFCVT);

      /* Try to identify useless null pointer tests and delete them.  */
      if (flag_delete_null_pointer_checks)
	delete_null_pointer_checks (insns);
2880 2881 2882 2883 2884 2885 2886 2887 2888
    }

  /* Jump optimization, and the removal of NULL pointer checks, may
     have reduced the number of instructions substantially.  CSE, and
     future passes, allocate arrays whose dimensions involve the
     maximum instruction UID, so if we can reduce the maximum UID
     we'll save big on memory.  */
  renumber_insns (rtl_dump_file);
  timevar_pop (TV_JUMP);
2889 2890

  close_dump_file (DFI_jump, print_rtl, insns);
2891

2892 2893 2894
  if (ggc_p)
    ggc_collect ();

Richard Stallman committed
2895 2896 2897 2898 2899 2900 2901
  /* Perform common subexpression elimination.
     Nonzero value from `cse_main' means that jumps were simplified
     and some code may now be unreachable, so do
     jump optimization again.  */

  if (optimize > 0)
    {
2902
      open_dump_file (DFI_cse, decl);
2903
      timevar_push (TV_CSE);
2904

2905
      reg_scan (insns, max_reg_num (), 1);
Richard Stallman committed
2906 2907

      if (flag_thread_jumps)
2908 2909 2910 2911 2912
	{
	  timevar_push (TV_JUMP);
	  thread_jumps (insns, max_reg_num (), 1);
	  timevar_pop (TV_JUMP);
	}
Richard Stallman committed
2913

2914
      tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
2915

Jeff Law committed
2916 2917 2918 2919
      /* If we are not running the second CSE pass, then we are no longer
	 expecting CSE to be run.  */
      cse_not_expected = !flag_rerun_cse_after_loop;

2920
      if (tem || optimize > 1)
2921 2922 2923 2924 2925 2926
	{
	  timevar_push (TV_JUMP);
	  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
			 !JUMP_AFTER_REGSCAN);
	  timevar_pop (TV_JUMP);
	}
2927
 
Jeffrey A Law committed
2928 2929
      /* Run this after jump optmizations remove all the unreachable code
	 so that unreachable code will not keep values live.  */
2930
      delete_trivially_dead_insns (insns, max_reg_num ());
Jeffrey A Law committed
2931

2932
      /* Try to identify useless null pointer tests and delete them.  */
2933
      if (flag_delete_null_pointer_checks)
2934 2935 2936 2937 2938 2939 2940 2941 2942
	{
	  timevar_push (TV_JUMP);
	  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);

	  cleanup_cfg (insns);

	  delete_null_pointer_checks (insns);
	  timevar_pop (TV_JUMP);
	}
Richard Stallman committed
2943

2944 2945 2946
      /* The second pass of jump optimization is likely to have
         removed a bunch more instructions.  */
      renumber_insns (rtl_dump_file);
2947

2948
      timevar_pop (TV_CSE);
2949
      close_dump_file (DFI_cse, print_rtl, insns);
2950
    }
Richard Stallman committed
2951

2952 2953
  open_dump_file (DFI_addressof, decl);

2954 2955 2956
  purge_addressof (insns);
  reg_scan (insns, max_reg_num (), 1);

2957
  close_dump_file (DFI_addressof, print_rtl, insns);
2958

2959 2960 2961
  if (ggc_p)
    ggc_collect ();

2962
  if (optimize > 0 && flag_ssa)
Alex Samuel committed
2963
    {
2964 2965 2966
      /* Convert to SSA form.  */

      timevar_push (TV_TO_SSA);
2967
      open_dump_file (DFI_ssa, decl);
2968

2969 2970 2971
      find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
      cleanup_cfg (insns);
      convert_to_ssa ();
2972

2973
      close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
2974
      timevar_pop (TV_TO_SSA);
Alex Samuel committed
2975

2976
      /* Currently, there's nothing to do in SSA form.  */
Alex Samuel committed
2977

2978
      /* Convert from SSA form.  */
2979

2980 2981
      timevar_push (TV_FROM_SSA);
      open_dump_file (DFI_ussa, decl);
2982

2983 2984 2985 2986 2987 2988 2989
      convert_from_ssa ();
      /* New registers have been created.  Rescan their usage.  */
      reg_scan (insns, max_reg_num (), 1);
      /* Life analysis used in SSA adds log_links but these
	 shouldn't be there until the flow stage, so clear
	 them away.  */
      clear_log_links (insns);
2990 2991

      close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
2992
      timevar_pop (TV_FROM_SSA);
Alex Samuel committed
2993 2994 2995 2996 2997

      if (ggc_p)
	ggc_collect ();
    }

2998 2999 3000 3001
  /* Perform global cse.  */

  if (optimize > 0 && flag_gcse)
    {
3002
      timevar_push (TV_GCSE);
3003
      open_dump_file (DFI_gcse, decl);
3004

3005 3006 3007
      find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
      cleanup_cfg (insns);
      tem = gcse_main (insns, rtl_dump_file);
3008 3009 3010 3011 3012

      /* If gcse altered any jumps, rerun jump optimizations to clean
	 things up.  */
      if (tem)
	{
3013 3014 3015 3016
	  timevar_push (TV_JUMP);
	  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
			 !JUMP_AFTER_REGSCAN);
	  timevar_pop (TV_JUMP);
3017
        }
3018

3019
      close_dump_file (DFI_gcse, print_rtl, insns);
3020
      timevar_pop (TV_GCSE);
3021 3022 3023

      if (ggc_p)
	ggc_collect ();
3024
    }
3025

Richard Stallman committed
3026 3027 3028 3029
  /* Move constant computations out of loops.  */

  if (optimize > 0)
    {
3030
      timevar_push (TV_LOOP);
3031
      open_dump_file (DFI_loop, decl);
3032 3033 3034 3035
      
      if (flag_rerun_loop_opt)
	{
	  /* We only want to perform unrolling once.  */
3036
	       
3037
	  loop_optimize (insns, rtl_dump_file, 0);
3038

3039 3040 3041 3042 3043
	  /* The first call to loop_optimize makes some instructions
	     trivially dead.  We delete those instructions now in the
	     hope that doing so will make the heuristics in loop work
	     better and possibly speed up compilation.  */
	  delete_trivially_dead_insns (insns, max_reg_num ());
3044

3045
	  /* The regscan pass is currently necessary as the alias
3046
		  analysis code depends on this information.  */
3047 3048
	  reg_scan (insns, max_reg_num (), 1);
	}
3049
      loop_optimize (insns, rtl_dump_file, (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT);
3050

3051
      close_dump_file (DFI_loop, print_rtl, insns);
3052
      timevar_pop (TV_LOOP);
3053 3054 3055

      if (ggc_p)
	ggc_collect ();
Richard Stallman committed
3056 3057
    }

3058
  if (optimize > 0)
3059
    {
3060
      timevar_push (TV_CSE2);
3061
      open_dump_file (DFI_cse2, decl);
3062

3063 3064 3065 3066 3067 3068 3069
      if (flag_rerun_cse_after_loop)
	{
	  /* Running another jump optimization pass before the second
	     cse pass sometimes simplifies the RTL enough to allow
	     the second CSE pass to do a better job.  Jump_optimize can change
	     max_reg_num so we must rerun reg_scan afterwards.
	     ??? Rework to not call reg_scan so often.  */
3070
	  timevar_push (TV_JUMP);
Richard Henderson committed
3071

3072 3073 3074
	  reg_scan (insns, max_reg_num (), 0);
	  jump_optimize (insns, !JUMP_CROSS_JUMP,
			 !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
Richard Henderson committed
3075 3076 3077 3078 3079 3080 3081 3082 3083

	  timevar_push (TV_IFCVT);

	  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
	  cleanup_cfg (insns);
	  if_convert (0);

	  timevar_pop(TV_IFCVT);

3084
	  timevar_pop (TV_JUMP);
3085
	  
3086 3087
	  reg_scan (insns, max_reg_num (), 0);
	  tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
3088

3089
	  if (tem)
3090 3091 3092 3093 3094 3095
	    {
	      timevar_push (TV_JUMP);
	      jump_optimize (insns, !JUMP_CROSS_JUMP,
			     !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
	      timevar_pop (TV_JUMP);
	    }
3096
	}
3097

3098 3099 3100 3101
      if (flag_thread_jumps)
	{
	  /* This pass of jump threading straightens out code
	     that was kinked by loop optimization.  */
3102 3103 3104 3105
	  timevar_push (TV_JUMP);
	  reg_scan (insns, max_reg_num (), 0);
	  thread_jumps (insns, max_reg_num (), 0);
	  timevar_pop (TV_JUMP);
3106
	}
3107

3108
      close_dump_file (DFI_cse2, print_rtl, insns);
3109
      timevar_pop (TV_CSE2);
3110 3111 3112

      if (ggc_p)
	ggc_collect ();
3113
    }
3114

Richard Henderson committed
3115 3116
  cse_not_expected = 1;

Richard Stallman committed
3117 3118
  regclass_init ();

3119
  
3120 3121
  /* Do control and data flow analysis; wrote some of the results to
     the dump file.  */
Richard Stallman committed
3122

3123
  timevar_push (TV_FLOW);
3124 3125
  open_dump_file (DFI_cfg, decl);

3126 3127
  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
  cleanup_cfg (insns);
3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142

  close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
 
  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
    {
      timevar_push (TV_BRANCH_PROB);
      open_dump_file (DFI_bp, decl);

      branch_prob ();

      close_dump_file (DFI_bp, print_rtl_with_bb, insns);
      timevar_pop (TV_BRANCH_PROB);
    }

  open_dump_file (DFI_life, decl);
3143 3144 3145
  if (optimize)
    {
      struct loops loops;
3146

3147 3148 3149
      /* Discover and record the loop depth at the head of each basic
	 block.  The loop infrastructure does the real job for us.  */
      flow_loops_find (&loops);
3150

3151
      /* Estimate using heuristics if no profiling info is available.  */
3152
      estimate_probability (&loops);
3153

3154 3155
      if (rtl_dump_file)
	flow_loops_dump (&loops, rtl_dump_file, 0);
3156

3157 3158 3159 3160 3161
      flow_loops_free (&loops);
    }
  life_analysis (insns, rtl_dump_file, PROP_FINAL);
  mark_constant_function ();
  timevar_pop (TV_FLOW);
3162

3163 3164 3165
  register_life_up_to_date = 1;
  no_new_pseudos = 1;

3166 3167 3168 3169 3170
  if (warn_uninitialized || extra_warnings)
    {
      uninitialized_vars_warning (DECL_INITIAL (decl));
      if (extra_warnings)
	setjmp_args_warning ();
Richard Stallman committed
3171 3172
    }

3173
  close_dump_file (DFI_life, print_rtl_with_bb, insns);
3174

3175 3176 3177
  if (ggc_p)
    ggc_collect ();

Richard Stallman committed
3178 3179 3180
  /* If -opt, try combining insns through substitution.  */

  if (optimize > 0)
3181
    {
3182 3183
      int rebuild_jump_labels_after_combine = 0;

3184
      timevar_push (TV_COMBINE);
3185 3186
      open_dump_file (DFI_combine, decl);

3187 3188
      rebuild_jump_labels_after_combine
	= combine_instructions (insns, max_reg_num ());
3189 3190 3191 3192 3193 3194
      
      /* Combining insns may have turned an indirect jump into a
	 direct jump.  Rebuid the JUMP_LABEL fields of jumping
	 instructions.  */
      if (rebuild_jump_labels_after_combine)
	{
3195 3196 3197
	  timevar_push (TV_JUMP);
	  rebuild_jump_labels (insns);
	  timevar_pop (TV_JUMP);
Richard Henderson committed
3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208

	  timevar_push (TV_FLOW);
	  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
	  cleanup_cfg (insns);

	  /* Blimey.  We've got to have the CFG up to date for the call to
	     if_convert below.  However, the random deletion of blocks
	     without updating life info can wind up with Wierd Stuff in
	     global_live_at_end.  We then run sched1, which updates things
	     properly, discovers the wierdness and aborts.  */
	  update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
3209 3210
			    PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
			    | PROP_SCAN_DEAD_CODE);
Richard Henderson committed
3211 3212

	  timevar_pop (TV_FLOW);
3213
	}
3214

3215
      close_dump_file (DFI_combine, print_rtl_with_bb, insns);
3216
      timevar_pop (TV_COMBINE);
3217 3218 3219

      if (ggc_p)
	ggc_collect ();
3220
    }
3221

Richard Henderson committed
3222 3223 3224 3225 3226 3227 3228
  /* Rerun if-conversion, as combine may have simplified things enough to
     now meet sequence length restrictions.  */
  if (optimize > 0)
    {
      timevar_push (TV_IFCVT);
      open_dump_file (DFI_ce, decl);

3229
      no_new_pseudos = 0;
Richard Henderson committed
3230
      if_convert (1);
3231
      no_new_pseudos = 1;
Richard Henderson committed
3232 3233 3234 3235 3236

      close_dump_file (DFI_ce, print_rtl_with_bb, insns);
      timevar_pop (TV_IFCVT);
    }

3237 3238
  /* Register allocation pre-pass, to reduce number of moves
     necessary for two-address machines.  */
J"orn Rennecke committed
3239
  if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
3240
    {
3241
      timevar_push (TV_REGMOVE);
3242
      open_dump_file (DFI_regmove, decl);
3243

3244
      regmove_optimize (insns, max_reg_num (), rtl_dump_file);
3245

3246
      close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
3247
      timevar_pop (TV_REGMOVE);
3248 3249 3250

      if (ggc_p)
	ggc_collect ();
3251
    }
3252

3253 3254 3255 3256 3257
  /* Any of the several passes since flow1 will have munged register
     lifetime data a bit.  */
  if (optimize > 0)
    register_life_up_to_date = 0;

3258 3259
#ifdef OPTIMIZE_MODE_SWITCHING
  if (optimize)
3260
    {
3261
      timevar_push (TV_GCSE);
3262 3263 3264 3265 3266 3267

      if (optimize_mode_switching (NULL_PTR))
	{
	  /* We did work, and so had to regenerate global life information.
	     Take advantage of this and don't re-recompute register life
	     information below.  */
3268
	  register_life_up_to_date = 1;
3269 3270
	}

3271
      timevar_pop (TV_GCSE);
3272
    }
3273
#endif
3274

3275
#ifdef INSN_SCHEDULING
3276 3277 3278

  /* Print function header into sched dump now
     because doing the sched analysis makes some of the dump.  */
Richard Stallman committed
3279 3280
  if (optimize > 0 && flag_schedule_insns)
    {
3281
      timevar_push (TV_SCHED);
3282
      open_dump_file (DFI_sched, decl);
3283

Richard Stallman committed
3284 3285 3286
      /* Do control and data sched analysis,
	 and write some of the results to dump file.  */

3287
      schedule_insns (rtl_dump_file);
3288

3289
      close_dump_file (DFI_sched, print_rtl_with_bb, insns);
3290
      timevar_pop (TV_SCHED);
3291 3292 3293

      if (ggc_p)
	ggc_collect ();
Richard Henderson committed
3294

3295 3296 3297
      /* Register lifetime information was updated as part of verifying
	 the schedule.  */
      register_life_up_to_date = 1;
Richard Stallman committed
3298
    }
3299
#endif
Richard Stallman committed
3300

3301 3302 3303 3304 3305
  /* Determine if the current function is a leaf before running reload
     since this can impact optimizations done by the prologue and
     epilogue thus changing register elimination offsets.  */
  current_function_is_leaf = leaf_function_p ();

3306
  timevar_push (TV_LOCAL_ALLOC);
3307
  open_dump_file (DFI_lreg, decl);
3308

3309
  /* Allocate pseudo-regs that are used only within 1 basic block. 
3310 3311 3312

     RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
     jump optimizer after register allocation and reloading are finished.  */
Richard Stallman committed
3313

3314 3315
  if (! register_life_up_to_date)
    recompute_reg_usage (insns, ! optimize_size);
3316 3317 3318 3319
  regclass (insns, max_reg_num (), rtl_dump_file);
  rebuild_label_notes_after_reload = local_alloc ();

  timevar_pop (TV_LOCAL_ALLOC);
Richard Stallman committed
3320

3321
  if (dump_file[DFI_lreg].enabled)
3322
    {
3323 3324 3325 3326
      timevar_push (TV_DUMP);

      dump_flow_info (rtl_dump_file);
      dump_local_alloc (rtl_dump_file);
3327

3328
      close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
3329
      timevar_pop (TV_DUMP);
3330
    }
Richard Stallman committed
3331

3332 3333 3334
  if (ggc_p)
    ggc_collect ();

3335
  timevar_push (TV_GLOBAL_ALLOC);
3336
  open_dump_file (DFI_greg, decl);
Richard Stallman committed
3337

3338 3339
  /* If optimizing, allocate remaining pseudo-regs.  Do the reload
     pass fixing up any insns that are invalid.  */
Richard Stallman committed
3340

3341 3342 3343 3344 3345 3346 3347 3348 3349
  if (optimize)
    failure = global_alloc (rtl_dump_file);
  else
    {
      build_insn_chain (insns);
      failure = reload (insns, 0, rtl_dump_file);
    }

  timevar_pop (TV_GLOBAL_ALLOC);
Richard Stallman committed
3350

3351 3352 3353
  if (failure)
    goto exit_rest_of_compilation;

3354 3355 3356
  if (ggc_p)
    ggc_collect ();

3357 3358
  /* Do a very simple CSE pass over just the hard registers.  */
  if (optimize > 0)
3359 3360 3361 3362 3363
    {
      timevar_push (TV_RELOAD_CSE_REGS);
      reload_cse_regs (insns);
      timevar_pop (TV_RELOAD_CSE_REGS); 
    }
3364

3365 3366 3367
  /* If optimizing, then go ahead and split insns now since we are about
     to recompute flow information anyway.  */
  if (optimize > 0)
3368
    split_all_insns (0);
3369

3370 3371 3372 3373
  /* Register allocation and reloading may have turned an indirect jump into
     a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
     jumping instructions.  */
  if (rebuild_label_notes_after_reload)
3374 3375 3376 3377 3378 3379 3380
    {
      timevar_push (TV_JUMP);

      rebuild_jump_labels (insns);

      timevar_pop (TV_JUMP);
    }
3381

3382
  if (dump_file[DFI_greg].enabled)
3383
    {
3384 3385 3386 3387
      timevar_push (TV_DUMP);

      dump_global_regs (rtl_dump_file);

3388
      close_dump_file (DFI_greg, print_rtl_with_bb, insns);
3389
      timevar_pop (TV_DUMP);
3390 3391
    }

3392
  /* Re-create the death notes which were deleted during reload.  */
3393
  timevar_push (TV_FLOW2);
3394
  open_dump_file (DFI_flow2, decl);
3395

3396 3397
  jump_optimize (insns, !JUMP_CROSS_JUMP,
		 !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
3398
  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
3399 3400 3401 3402 3403 3404 3405

  /* On some machines, the prologue and epilogue code, or parts thereof,
     can be represented as RTL.  Doing so lets us schedule insns between
     it and the rest of the code and also allows delayed branch
     scheduling to operate in the epilogue.  */
  thread_prologue_and_epilogue_insns (insns);

3406
  if (optimize)
3407
    {
3408 3409
      cleanup_cfg (insns);
      life_analysis (insns, rtl_dump_file, PROP_FINAL);
3410

3411
      /* This is kind of a heuristic.  We need to run combine_stack_adjustments
3412 3413 3414 3415 3416
         even for machines with possibly nonzero RETURN_POPS_ARGS
         and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
         push instructions will have popping returns.  */
#ifndef PUSH_ROUNDING
      if (!ACCUMULATE_OUTGOING_ARGS)
3417
#endif
3418
	combine_stack_adjustments ();
3419

3420 3421
      if (ggc_p)
	ggc_collect ();
3422
    }
3423

3424 3425
  flow2_completed = 1;

3426
  close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
3427
  timevar_pop (TV_FLOW2);
3428

Richard Henderson committed
3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439
  if (optimize > 0)
    {
      timevar_push (TV_IFCVT2);
      open_dump_file (DFI_ce2, decl);

      if_convert (1);

      close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
      timevar_pop (TV_IFCVT2);
    }

3440 3441 3442
#ifdef HAVE_peephole2
  if (optimize > 0 && flag_peephole2)
    {
3443 3444
      timevar_push (TV_PEEPHOLE2);
      open_dump_file (DFI_peephole2, decl);
Richard Henderson committed
3445

3446
      peephole2_optimize (rtl_dump_file);
3447

3448
      close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
3449
      timevar_pop (TV_PEEPHOLE2);
3450 3451 3452
    }
#endif

3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463
  if (optimize > 0 && flag_rename_registers)
    {
      timevar_push (TV_RENAME_REGISTERS);
      open_dump_file (DFI_rnreg, decl);

      regrename_optimize ();

      close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
      timevar_pop (TV_RENAME_REGISTERS);
    }    

3464
#ifdef INSN_SCHEDULING
Richard Stallman committed
3465 3466
  if (optimize > 0 && flag_schedule_insns_after_reload)
    {
3467
      timevar_push (TV_SCHED2);
3468
      open_dump_file (DFI_sched2, decl);
Richard Stallman committed
3469 3470 3471 3472

      /* Do control and data sched analysis again,
	 and write some more of the results to dump file.  */

3473
      schedule_insns (rtl_dump_file);
Richard Stallman committed
3474

3475
      close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
3476
      timevar_pop (TV_SCHED2);
3477 3478 3479

      if (ggc_p)
	ggc_collect ();
Richard Stallman committed
3480
    }
3481
#endif
Richard Stallman committed
3482 3483

#ifdef LEAF_REGISTERS
3484 3485
  current_function_uses_only_leaf_regs
    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
Richard Stallman committed
3486 3487
#endif

3488 3489
  if (optimize > 0 && flag_reorder_blocks)
    {
3490
      timevar_push (TV_REORDER_BLOCKS);
3491
      open_dump_file (DFI_bbro, decl);
3492

3493
      reorder_basic_blocks ();
3494

3495
      close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
3496
      timevar_pop (TV_REORDER_BLOCKS);
3497 3498
    }    

3499 3500
  /* One more attempt to remove jumps to .+1 left by dead-store elimination. 
     Also do cross-jumping this time and delete no-op move insns.  */
Richard Stallman committed
3501 3502 3503

  if (optimize > 0)
    {
3504
      timevar_push (TV_JUMP);
3505 3506
      open_dump_file (DFI_jump2, decl);

3507 3508
      jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES, 
		     !JUMP_AFTER_REGSCAN);
3509

Richard Henderson committed
3510 3511
      /* CFG no longer kept up to date.  */

3512
      close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
3513
      timevar_pop (TV_JUMP);
3514
    }
Richard Stallman committed
3515

3516 3517
  /* If a machine dependent reorganization is needed, call it.  */
#ifdef MACHINE_DEPENDENT_REORG
3518
  open_dump_file (DFI_mach, decl);
3519

3520
  MACHINE_DEPENDENT_REORG (insns);
3521

3522
  close_dump_file (DFI_mach, print_rtl_with_bb, insns);
3523

3524 3525
  if (ggc_p)
    ggc_collect ();
3526 3527
#endif

Richard Stallman committed
3528
  /* If a scheduling pass for delayed branches is to be done,
Mike Stump committed
3529
     call the scheduling code.  */
Richard Stallman committed
3530 3531 3532 3533

#ifdef DELAY_SLOTS
  if (optimize > 0 && flag_delayed_branch)
    {
3534
      timevar_push (TV_DBR_SCHED);
3535
      open_dump_file (DFI_dbr, decl);
3536

3537
      dbr_schedule (insns, rtl_dump_file);
3538

3539
      close_dump_file (DFI_dbr, print_rtl_with_bb, insns);
3540
      timevar_pop (TV_DBR_SCHED);
3541

3542 3543 3544
      if (ggc_p)
	ggc_collect ();
    }
Richard Stallman committed
3545 3546
#endif

3547 3548 3549 3550
  /* Shorten branches. 

     Note this must run before reg-stack because of death note (ab)use
     in the ia32 backend.  */
3551 3552 3553
  timevar_push (TV_SHORTEN_BRANCH);
  shorten_branches (get_insns ());
  timevar_pop (TV_SHORTEN_BRANCH);
3554

Richard Stallman committed
3555
#ifdef STACK_REGS
3556
  timevar_push (TV_REG_STACK);
3557
  open_dump_file (DFI_stack, decl);
3558

3559
  reg_to_stack (insns, rtl_dump_file);
3560

3561
  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
3562
  timevar_pop (TV_REG_STACK);
3563

3564 3565
  if (ggc_p)
    ggc_collect ();
Richard Stallman committed
3566 3567
#endif

3568
  current_function_nothrow = nothrow_function_p ();
3569 3570 3571 3572
  if (current_function_nothrow)
    /* Now we know that this can't throw; set the flag for the benefit
       of other functions later in this translation unit.  */
    TREE_NOTHROW (current_function_decl) = 1;
3573

Richard Stallman committed
3574 3575
  /* Now turn the rtl into assembler code.  */

3576 3577 3578 3579
  timevar_push (TV_FINAL);
  {
    rtx x;
    const char *fnname;
Richard Stallman committed
3580

3581 3582
    /* Get the function's name, as described by its RTL.  This may be
       different from the DECL_NAME name used in the source file.  */
Richard Stallman committed
3583

3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598
    x = DECL_RTL (decl);
    if (GET_CODE (x) != MEM)
      abort ();
    x = XEXP (x, 0);
    if (GET_CODE (x) != SYMBOL_REF)
      abort ();
    fnname = XSTR (x, 0);

    assemble_start_function (decl, fnname);
    final_start_function (insns, asm_out_file, optimize);
    final (insns, asm_out_file, optimize, 0);
    final_end_function (insns, asm_out_file, optimize);
    assemble_end_function (decl, fnname);
    if (! quiet_flag)
      fflush (asm_out_file);
3599

3600
	     /* Release all memory allocated by flow.  */
3601
    free_basic_block_vars (0);
3602

3603 3604 3605 3606
    /* Release all memory held by regsets now */
    regset_release_memory ();
  }
  timevar_pop (TV_FINAL);
Richard Stallman committed
3607

3608 3609
  if (ggc_p)
    ggc_collect ();
3610

Richard Stallman committed
3611 3612 3613 3614 3615 3616 3617 3618 3619 3620
  /* Write DBX symbols if requested */

  /* Note that for those inline functions where we don't initially
     know for certain that we will be generating an out-of-line copy,
     the first invocation of this routine (rest_of_compilation) will
     skip over this code by doing a `goto exit_rest_of_compilation;'.
     Later on, finish_compilation will call rest_of_compilation again
     for those inline functions that need to have out-of-line copies
     generated.  During that call, we *will* be routed past here.  */

3621
  timevar_push (TV_SYMOUT);
Richard Stallman committed
3622 3623
#ifdef DBX_DEBUGGING_INFO
  if (write_symbols == DBX_DEBUG)
3624
    dbxout_function (decl);
Richard Stallman committed
3625 3626 3627 3628
#endif

#ifdef DWARF_DEBUGGING_INFO
  if (write_symbols == DWARF_DEBUG)
3629
    dwarfout_file_scope_decl (decl, 0);
Richard Stallman committed
3630 3631
#endif

x  
Jason Merrill committed
3632 3633
#ifdef DWARF2_DEBUGGING_INFO
  if (write_symbols == DWARF2_DEBUG)
3634
    dwarf2out_decl (decl);
x  
Jason Merrill committed
3635
#endif
3636
  timevar_pop (TV_SYMOUT);
x  
Jason Merrill committed
3637

Richard Stallman committed
3638 3639
 exit_rest_of_compilation:

3640 3641 3642 3643 3644
  /* In case the function was not output,
     don't leave any temporary anonymous types
     queued up for sdb output.  */
#ifdef SDB_DEBUGGING_INFO
  if (write_symbols == SDB_DEBUG)
3645
    sdbout_types (NULL_TREE);
3646 3647
#endif

Richard Stallman committed
3648
  reload_completed = 0;
3649
  flow2_completed = 0;
3650
  no_new_pseudos = 0;
Richard Stallman committed
3651

3652
  timevar_push (TV_FINAL);
Richard Stallman committed
3653

3654 3655 3656 3657 3658
  /* Clear out the insn_length contents now that they are no
     longer valid.  */
  init_insn_lengths ();

  /* Clear out the real_constant_chain before some of the rtx's
3659
		 it runs through become garbage.  */
3660 3661 3662 3663
  clear_const_double_mem ();

  /* Cancel the effect of rtl_in_current_obstack.  */
  resume_temporary_allocation ();
Richard Stallman committed
3664

3665 3666
  /* Show no temporary slots allocated.  */
  init_temp_slots ();
3667

3668
  free_basic_block_vars (0);
3669

3670
  timevar_pop (TV_FINAL);
3671

3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682
  /* Make sure volatile mem refs aren't considered valid operands for
     arithmetic insns.  We must call this here if this is a nested inline
     function, since the above code leaves us in the init_recog state
     (from final.c), and the function context push/pop code does not
     save/restore volatile_ok.

     ??? Maybe it isn't necessary for expand_start_function to call this
     anymore if we do it here?  */

  init_recog_no_volatile ();

3683
  /* We're done with this function.  Free up memory if we can.  */
Bernd Schmidt committed
3684
  free_after_parsing (cfun);
3685
  if (! DECL_DEFER_OUTPUT (decl))
Bernd Schmidt committed
3686 3687
    free_after_compilation (cfun);
  cfun = 0;
3688

3689 3690
  if (ggc_p)
    ggc_collect ();
3691

3692
  timevar_pop (TV_REST_OF_COMPILATION);
Richard Stallman committed
3693 3694
}

Nick Clifton committed
3695 3696 3697 3698
static void
display_help ()
{
  int    undoc;
3699
  unsigned long	 i;
3700
  const char * lang;
Nick Clifton committed
3701
  
Nick Clifton committed
3702
#ifndef USE_CPPLIB  
3703 3704
  printf (_("Usage: %s input [switches]\n"), progname);
  printf (_("Switches:\n"));
Nick Clifton committed
3705
#endif
3706 3707 3708 3709 3710 3711
  printf (_("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n"));
  printf (_("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n"));
  printf (_("  -fcall-saved-<register> Mark <register> as being preserved across functions\n"));
  printf (_("  -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
  printf (_("  -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line.  0 suppresses line-wrapping\n"));
  printf (_("  -fdiagnostics-show-location=[once | never] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
Nick Clifton committed
3712 3713 3714

  for (i = NUM_ELEM (f_options); i--;)
    {
3715
      const char * description = f_options[i].description;
Nick Clifton committed
3716 3717 3718 3719 3720 3721
      
      if (description != NULL && * description != 0)
	printf ("  -f%-21s %s\n",
		f_options[i].string, description);
    }
  
3722 3723 3724 3725 3726 3727
  printf (_("  -O[number]              Set optimisation level to [number]\n"));
  printf (_("  -Os                     Optimise for space rather than speed\n"));
  printf (_("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n"));
  printf (_("  -pedantic-errors        Like -pedantic except that errors are produced\n"));
  printf (_("  -w                      Suppress warnings\n"));
  printf (_("  -W                      Enable extra warnings\n"));
Nick Clifton committed
3728 3729 3730
  
  for (i = NUM_ELEM (W_options); i--;)
    {
3731
      const char * description = W_options[i].description;
Nick Clifton committed
3732 3733 3734 3735 3736 3737
      
      if (description != NULL && * description != 0)
	printf ("  -W%-21s %s\n",
		W_options[i].string, description);
    }
  
3738 3739 3740 3741
  printf (_("  -Wunused                Enable unused warnings\n"));
  printf (_("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n"));
  printf (_("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n"));
  printf (_("  -p                      Enable function profiling\n"));
Nick Clifton committed
3742
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
3743
  printf (_("  -a                      Enable block profiling \n"));
Nick Clifton committed
3744 3745
#endif  
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
3746
  printf (_("  -ax                     Enable jump profiling \n"));
Nick Clifton committed
3747
#endif  
3748 3749 3750 3751
  printf (_("  -o <file>               Place output into <file> \n"));
  printf (_("\
  -G <number>             Put global and static data smaller than <number>\n\
                          bytes into a special section (on some targets)\n"));
Nick Clifton committed
3752 3753 3754 3755
  
  for (i = NUM_ELEM (debug_args); i--;)
    {
      if (debug_args[i].description != NULL)
3756
	printf ("  -g%-21s %s\n", debug_args[i].arg, debug_args[i].description);
Nick Clifton committed
3757 3758
    }
  
3759 3760 3761 3762 3763
  printf (_("  -aux-info <file>        Emit declaration info into <file>.X\n"));
  printf (_("  -quiet                  Do not display functions compiled or elapsed time\n"));
  printf (_("  -version                Display the compiler's version\n"));
  printf (_("  -d[letters]             Enable dumps from specific passes of the compiler\n"));
  printf (_("  -dumpbase <file>        Base name to be used for dumps from specific passes\n"));
3764
#if defined INSN_SCHEDULING
3765
  printf (_("  -fsched-verbose=<number> Set the verbosity level of the scheduler\n"));
Nick Clifton committed
3766
#endif
3767
  printf (_("  --help                  Display this information\n"));
Nick Clifton committed
3768 3769 3770 3771 3772 3773 3774 3775 3776

  undoc = 0;
  lang  = "language";
  
  /* Display descriptions of language specific options.
     If there is no description, note that there is an undocumented option.
     If the description is empty, do not display anything.  (This allows
     options to be deliberately undocumented, for whatever reason).
     If the option string is missing, then this is a marker, indicating
3777
     that the description string is in fact the name of a language, whose
Nick Clifton committed
3778 3779 3780 3781
     language specific options are to follow.  */
  
  if (NUM_ELEM (documented_lang_options) > 1)
    {
3782
      printf (_("\nLanguage specific options:\n"));
Nick Clifton committed
3783 3784 3785

      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
	{
3786 3787
	  const char * description = documented_lang_options[i].description;
	  const char * option      = documented_lang_options[i].option;
Nick Clifton committed
3788 3789

	  if (description == NULL)
3790 3791 3792 3793
	    {
	      undoc = 1;

	      if (extra_warnings)
3794
		printf (_("  %-23.23s [undocumented]\n"), option);
3795
	    }
Nick Clifton committed
3796 3797 3798 3799 3800 3801
	  else if (* description == 0)
	    continue;
	  else if (option == NULL)
	    {
	      if (undoc)
		printf
3802
		  (_("\nThere are undocumented %s specific options as well.\n"),
Nick Clifton committed
3803 3804 3805
			lang);
	      undoc = 0;
	      
3806
	      printf (_("\n Options for %s:\n"), description);
Nick Clifton committed
3807 3808 3809 3810 3811 3812 3813 3814 3815

	      lang = description;
	    }
	  else
	    printf ("  %-23.23s %s\n", option, description);
	}
    }

  if (undoc)
3816
    printf (_("\nThere are undocumented %s specific options as well.\n"), lang);
Nick Clifton committed
3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827

  if (NUM_ELEM (target_switches) > 1
#ifdef TARGET_OPTIONS
      || NUM_ELEM (target_options) > 1
#endif
      )
    {
      int doc = 0;
      
      undoc = 0;
  
3828
      printf (_("\nTarget specific options:\n"));
Nick Clifton committed
3829 3830 3831

      for (i = NUM_ELEM (target_switches); i--;)
	{
3832 3833
	  const char * option      = target_switches[i].name;
	  const char * description = target_switches[i].description;
Nick Clifton committed
3834

3835
	  if (option == NULL || * option == 0)
Nick Clifton committed
3836 3837
	    continue;
	  else if (description == NULL)
3838 3839 3840 3841
	    {
	      undoc = 1;
	      
	      if (extra_warnings)
3842
		printf (_("  -m%-21.21s [undocumented]\n"), option);
3843
	    }
Nick Clifton committed
3844
	  else if (* description != 0)
3845
	    doc += printf ("  -m%-21.21s %s\n", option, description);
Nick Clifton committed
3846 3847 3848 3849 3850
	}
      
#ifdef TARGET_OPTIONS      
      for (i = NUM_ELEM (target_options); i--;)
	{
3851 3852
	  const char * option      = target_options[i].prefix;
	  const char * description = target_options[i].description;
Nick Clifton committed
3853

3854
	  if (option == NULL || * option == 0)
Nick Clifton committed
3855 3856
	    continue;
	  else if (description == NULL)
3857 3858 3859 3860
	    {
	      undoc = 1;
	      
	      if (extra_warnings)
3861
		printf (_("  -m%-21.21s [undocumented]\n"), option);
3862
	    }
Nick Clifton committed
3863
	  else if (* description != 0)
3864
	    doc += printf ("  -m%-21.21s %s\n", option, description);
Nick Clifton committed
3865 3866 3867
	}
#endif
      if (undoc)
3868 3869
	{
	  if (doc)
3870
	    printf (_("\nThere are undocumented target specific options as well.\n"));
3871
	  else
3872
	    printf (_("  They exist, but they are not documented.\n"));
3873
	}
Nick Clifton committed
3874 3875
    }
}
3876 3877 3878 3879 3880 3881 3882

/* Parse a -d... comand line switch.  */

static void
decode_d_option (arg)
     const char * arg;
{
3883 3884 3885 3886
  int i, c, matched;

  while (*arg)
    switch (c = *arg++)
3887 3888
      {
      case 'a':
3889 3890
	for (i = 0; i < DFI_MAX; ++i)
	  dump_file[i].enabled = 1;
3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912
	break;
      case 'A':
	flag_debug_asm = 1;
	break;
      case 'm':
	flag_print_mem = 1;
	break;
      case 'p':
	flag_print_asm_name = 1;
	break;
      case 'v':
	graph_dump_format = vcg;
	break;
      case 'x':
	rtl_dump_and_exit = 1;
	break;
      case 'y':
	set_yydebug (1);
	break;
      case 'D':	/* These are handled by the preprocessor.  */
      case 'I':
	break;
3913

3914
      default:
3915 3916 3917 3918 3919 3920 3921 3922 3923 3924
	matched = 0;
	for (i = 0; i < DFI_MAX; ++i)
	  if (c == dump_file[i].debug_switch)
	    {
	      dump_file[i].enabled = 1;
	      matched = 1;
	    }

	if (! matched)
	  warning ("unrecognized gcc debugging option: %c", c);
3925 3926 3927
	break;
      }
}
Nick Clifton committed
3928

3929 3930 3931
/* Parse a -f... comand line switch.  ARG is the value after the -f.
   It is safe to access 'ARG - 2' to generate the full switch name.
   Return the number of strings consumed.  */
Nick Clifton committed
3932 3933

static int
3934 3935
decode_f_option (arg)
     const char * arg;
Nick Clifton committed
3936
{
3937
  int j;
3938
  const char *option_value = NULL;
3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955

  /* Search for the option in the table of binary f options.  */
  for (j = sizeof (f_options) / sizeof (f_options[0]); j--;)
    {
      if (!strcmp (arg, f_options[j].string))
	{
	  *f_options[j].variable = f_options[j].on_value;
	  return 1;
	}
    
      if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
	  && ! strcmp (arg + 3, f_options[j].string))
	{
	  *f_options[j].variable = ! f_options[j].on_value;
	  return 1;
	}
    }
Nick Clifton committed
3956

3957 3958
  if ((option_value = skip_leading_substring (arg, "inline-limit-"))
      || (option_value = skip_leading_substring (arg, "inline-limit=")))
3959
    inline_max_insns =
3960
      read_integral_parameter (option_value, arg - 2, inline_max_insns);
3961
#ifdef INSN_SCHEDULING
3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973
  else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
    fix_sched_param ("verbose", option_value);
#endif
  else if ((option_value = skip_leading_substring (arg, "fixed-")))
    fix_register (option_value, 1, 1);
  else if ((option_value = skip_leading_substring (arg, "call-used-")))
    fix_register (option_value, 0, 1);
  else if ((option_value = skip_leading_substring (arg, "call-saved-")))
    fix_register (option_value, 0, 0);
  else if ((option_value = skip_leading_substring (arg, "align-loops=")))
    align_loops = read_integral_parameter (option_value, arg - 2, align_loops);
  else if ((option_value = skip_leading_substring (arg, "align-functions=")))
3974
    align_functions
3975 3976 3977 3978 3979 3980 3981 3982 3983 3984
      = read_integral_parameter (option_value, arg - 2, align_functions);
  else if ((option_value = skip_leading_substring (arg, "align-jumps=")))
    align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps);
  else if ((option_value = skip_leading_substring (arg, "align-labels=")))
    align_labels
      = read_integral_parameter (option_value, arg - 2, align_labels);
  else if ((option_value
            = skip_leading_substring (arg, "stack-limit-register=")))
    {
      int reg = decode_reg_name (option_value);
3985
      if (reg < 0)
3986
	error ("unrecognized register name `%s'", option_value);
3987 3988 3989
      else
	stack_limit_rtx = gen_rtx_REG (Pmode, reg);
    }
3990 3991
  else if ((option_value
            = skip_leading_substring (arg, "stack-limit-symbol=")))
3992 3993 3994
    {
      char *nm;
      if (ggc_p)
3995
	nm = ggc_alloc_string (option_value, strlen (option_value));
3996
      else
3997
	nm = xstrdup (option_value);
3998 3999
      stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
    }
4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014
  else if ((option_value
            = skip_leading_substring (arg, "message-length=")))
    diagnostic_message_length_per_line = 
      read_integral_parameter (option_value, arg - 2,
                               diagnostic_message_length_per_line);
  else if ((option_value
            = skip_leading_substring (arg, "diagnostics-show-location=")))
    {
      if (!strcmp (option_value, "once"))
        set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
      else if (!strcmp (option_value, "every-line"))
        set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE);
      else
        error ("Unrecognized option `%s'", arg - 2);
    }
4015 4016
  else if (!strcmp (arg, "no-stack-limit"))
    stack_limit_rtx = NULL_RTX;
4017 4018
  else if (!strcmp (arg, "preprocessed"))
    /* Recognise this switch but do nothing.  This prevents warnings
4019
       about an unrecognized switch if cpplib has not been linked in.  */
4020
    ;
4021
  else
4022 4023 4024 4025 4026 4027 4028 4029
    return 0;

  return 1;
}

/* Parse a -W... comand line switch.  ARG is the value after the -W.
   It is safe to access 'ARG - 2' to generate the full switch name.
   Return the number of strings consumed.  */
4030

4031 4032 4033 4034
static int
decode_W_option (arg)
     const char * arg;
{
4035
  const char *option_value = NULL;
4036
  int j;
4037
  
4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055
  /* Search for the option in the table of binary W options.  */

  for (j = sizeof (W_options) / sizeof (W_options[0]); j--;)
    {
      if (!strcmp (arg, W_options[j].string))
	{
	  *W_options[j].variable = W_options[j].on_value;
	  return 1;
	}

      if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
	  && ! strcmp (arg + 3, W_options[j].string))
	{
	  *W_options[j].variable = ! W_options[j].on_value;
	  return 1;
	}
    }

4056
  if ((option_value = skip_leading_substring (arg, "id-clash-")))
4057
    {
4058
      id_clash_len = read_integral_parameter (option_value, arg - 2, -1);
4059
      
4060 4061
      if (id_clash_len != -1)
	warn_id_clash = 1;
4062
    }
4063
  else if ((option_value = skip_leading_substring (arg, "larger-than-")))
4064
    {
4065
      larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
4066 4067 4068

      if (larger_than_size != -1)
	warn_larger_than = 1;
4069
    }
4070 4071 4072 4073 4074 4075 4076 4077
  else if (!strcmp (arg, "unused"))
    {
      set_Wunused (1);
    }
  else if (!strcmp (arg, "no-unused"))
    {
      set_Wunused (0);
    }
4078
  else
Nick Clifton committed
4079
    return 0;
4080 4081 4082 4083 4084 4085 4086

  return 1;
}

/* Parse a -g... comand line switch.  ARG is the value after the -g.
   It is safe to access 'ARG - 2' to generate the full switch name.
   Return the number of strings consumed.  */
Richard Kenner committed
4087

4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107
static int
decode_g_option (arg)
     const char * arg;
{
  unsigned level;
  /* A lot of code assumes write_symbols == NO_DEBUG if the
     debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
     of what debugging type has been selected).  This records the
     selected type.  It is an error to specify more than one
     debugging type.  */
  static enum debug_info_type selected_debug_type = NO_DEBUG;
  /* Non-zero if debugging format has been explicitly set.
     -g and -ggdb don't explicitly set the debugging format so
     -gdwarf -g3 is equivalent to -gdwarf3.  */
  static int type_explicitly_set_p = 0;
  /* Indexed by enum debug_info_type.  */
  static const char * debug_type_names[] =
  {
    "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
  };
4108
  
4109 4110
  /* The maximum admissible debug level value.  */
  static const unsigned max_debug_level = 3;
4111
  
4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170
  /* Look up ARG in the table.  */
  for (da = debug_args; da->arg; da++)
    {
      const int da_len = strlen (da->arg);

      if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
	{
	  enum debug_info_type type = da->debug_type;
	  const char * p = arg + da_len;
	  
	  if (*p && (*p < '0' || *p > '9'))
	    continue;
	  
	  /* A debug flag without a level defaults to level 2.
	     Note we do not want to call read_integral_parameter
	     for that case since it will call atoi which 
	     will return zero.
	     
	     ??? We may want to generalize the interface to 
	     read_integral_parameter to better handle this case
	     if this case shows up often.  */
	  if (*p)
	    level = read_integral_parameter (p, 0, max_debug_level + 1);
	  else
	    level = 2;
	  
	  if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
	    {
	      error ("use -gdwarf -g%d for DWARF v1, level %d",
		     level, level);
	      if (level == 2)
		error ("use -gdwarf-2   for DWARF v2");
	    }
	  
	  if (level > max_debug_level)
	    {
	      warning ("\
ignoring option `%s' due to invalid debug level specification",
		       arg - 2);
	      level = debug_info_level;
	    }

	  if (type == NO_DEBUG)
	    {
	      type = PREFERRED_DEBUGGING_TYPE;
	      
	      if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
		{
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
		  type = DWARF2_DEBUG;
#else
#ifdef DBX_DEBUGGING_INFO
		  type = DBX_DEBUG;
#endif
#endif
		}
	    }
	  
	  if (type == NO_DEBUG)
Richard Kenner committed
4171
	    warning ("`%s': unknown or unsupported -g option", arg - 2);
4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201

	  /* Does it conflict with an already selected type?  */
	  if (type_explicitly_set_p
	      /* -g/-ggdb don't conflict with anything */
	      && da->debug_type != NO_DEBUG
	      && type != selected_debug_type)
	    warning ("`%s' ignored, conflicts with `-g%s'",
		     arg - 2, debug_type_names[(int) selected_debug_type]);
	  else
	    {
	      /* If the format has already been set, -g/-ggdb
		 only change the debug level.  */
	      if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
		; /* don't change debugging type */
	      else
		{
		  selected_debug_type = type;
		  type_explicitly_set_p = da->debug_type != NO_DEBUG;
		}
	      
	      write_symbols = (level == 0
			       ? NO_DEBUG
			       : selected_debug_type);
	      use_gnu_debug_info_extensions = da->use_extensions_p;
	      debug_info_level = (enum debug_info_level) level;
	    }
	  
	  break;
	}
    }
4202
  
4203
  if (! da->arg)
Richard Kenner committed
4204
    warning ("`%s': unknown or unsupported -g option", arg - 2);
4205 4206 4207 4208 4209 4210 4211 4212 4213

  return 1;
}

/* Decode the first argument in the argv as a language-independent option.
   Return the number of strings consumed.  'strings_processed' is the
   number of strings that have already been decoded in a language
   specific fashion before this function was invoked.  */
   
4214
static unsigned int
4215 4216
independent_decode_option (argc, argv, strings_processed)
     int argc;
4217 4218
     char **argv;
     unsigned int strings_processed;
4219
{
4220
  char *arg = argv[0];
4221
  
4222
  if (arg[0] != '-' || arg[1] == 0)
Nick Clifton committed
4223
    {
4224 4225 4226 4227 4228 4229
      if (arg[0] == '+')
	return 0;
      
      filename = arg;

      return 1;
Nick Clifton committed
4230
    }
4231 4232

  arg ++;
4233
  
4234 4235 4236 4237 4238 4239 4240 4241
  if (!strcmp (arg, "-help"))
    {
      display_help ();
      exit (0);
    }

  if (* arg == 'Y')
    arg ++;
4242
  
4243
  switch (*arg)
Nick Clifton committed
4244
    {
4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259
    default:
      return 0;
      
    case 'O':
      /* Already been treated in main (). Do nothing.  */
      break;
	  
    case 'm':
      set_target_switch (arg + 1);
      break;

    case 'f':
      return decode_f_option (arg + 1);
	    
    case 'g':
4260 4261 4262 4263
      if (strings_processed == 0)
	return decode_g_option (arg + 1);
      else
	return strings_processed;
4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333

    case 'd':
      if (!strcmp (arg, "dumpbase"))
	{
	  if (argc == 1)
	    return 0;
	  
	  dump_base_name = argv[1];
	  return 2;
	}
      else
	decode_d_option (arg + 1);
      break;

    case 'p':
      if (!strcmp (arg, "pedantic"))
	pedantic = 1;
      else if (!strcmp (arg, "pedantic-errors"))
	flag_pedantic_errors = pedantic = 1;
      else if (arg[1] == 0)
	profile_flag = 1;
      else
	return 0;
      break;

    case 'q':
      if (!strcmp (arg, "quiet"))
	quiet_flag = 1;
      else
	return 0;
      break;

    case 'v':
      if (!strcmp (arg, "version"))
	version_flag = 1;
      else
	return 0;
      break;

    case 'w':
      if (arg[1] == 0)
	inhibit_warnings = 1;
      else
	return 0;
      break;

    case 'W':
      if (arg[1] == 0)
	{
	  extra_warnings = 1;
	  /* We save the value of warn_uninitialized, since if they put
	     -Wuninitialized on the command line, we need to generate a
	     warning about not using it without also specifying -O.  */
	  if (warn_uninitialized != 1)
	    warn_uninitialized = 2;
	}
      else
	return decode_W_option (arg + 1);
      break;
	  
    case 'a':
      if (arg[1] == 0)
	{
#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
	  warning ("`-a' option (basic block profile) not supported");
#else
	  profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
#endif
	}
      else if (!strcmp (arg, "ax"))
Nick Clifton committed
4334
	{
4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364
#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
	  warning ("`-ax' option (jump profiling) not supported");
#else
	  profile_block_flag = (!profile_block_flag 
				|| profile_block_flag == 2) ? 2 : 3;
#endif
	}
      else if (!strncmp (arg, "aux-info", 8))
	{
	  flag_gen_aux_info = 1;
	  if (arg[8] == '\0')
	    {
	      if (argc == 1)
		return 0;
	      
	      aux_info_file_name = argv[1];
	      return 2;
	    }
	  else
	    aux_info_file_name = arg + 8;
	}
      else
	return 0;
      break;

    case 'o':
      if (arg[1] == 0)
	{
	  if (argc == 1)
	    return 0;
4365
	  
4366 4367
	  asm_file_name = argv[1];
	  return 2;
Nick Clifton committed
4368
	}
4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399
      return 0;

    case 'G':
      {
	int g_switch_val;
	int return_val;
	    
	if (arg[1] == 0)
	  {
	    if (argc == 1)
	      return 0;
	    
	    g_switch_val = read_integral_parameter (argv[1], 0, -1);
	    return_val = 2;
	  }
	else
	  {
	    g_switch_val = read_integral_parameter (arg + 1, 0, -1);
	    return_val = 1;
	  }
	    
	if (g_switch_val == -1)
	  return_val = 0;
	else
	  {
	    g_switch_set = TRUE;
	    g_switch_value = g_switch_val;
	  }
	    
	return return_val;
      }
Nick Clifton committed
4400
    }
4401
  
Nick Clifton committed
4402 4403 4404
  return 1;
}

Richard Stallman committed
4405 4406 4407 4408
/* Entry point of cc1/c++.  Decode command args, then call compile_file.
   Exit code is 35 if can't open files, 34 if fatal error,
   33 if had nonfatal errors, else success.  */

4409
extern int main PARAMS ((int, char **));
4410

Richard Stallman committed
4411
int
4412
main (argc, argv)
Richard Stallman committed
4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423
     int argc;
     char **argv;
{
  register int i;
  char *p;

  /* save in case md file wants to emit args as a comment.  */
  save_argc = argc;
  save_argv = argv;

  p = argv[0] + strlen (argv[0]);
4424
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
4425
    --p;
Richard Stallman committed
4426 4427
  progname = p;

4428
#ifdef HAVE_LC_MESSAGES
4429
  setlocale (LC_MESSAGES, "");
4430
#endif
Kaveh R. Ghazi committed
4431 4432
  (void) bindtextdomain (PACKAGE, localedir);
  (void) textdomain (PACKAGE);
4433

Richard Stallman committed
4434 4435
  signal (SIGFPE, float_signal);

4436
#ifdef SIGPIPE
Richard Stallman committed
4437
  signal (SIGPIPE, pipe_closed);
4438
#endif
Richard Stallman committed
4439 4440

  decl_printable_name = decl_name;
4441
  lang_expand_expr = (lang_expand_expr_t) do_abort;
Richard Stallman committed
4442 4443 4444 4445 4446 4447 4448 4449

  /* Initialize whether `char' is signed.  */
  flag_signed_char = DEFAULT_SIGNED_CHAR;
#ifdef DEFAULT_SHORT_ENUMS
  /* Initialize how much space enums occupy, by default.  */
  flag_short_enums = DEFAULT_SHORT_ENUMS;
#endif

4450
  /* Initialize the garbage-collector.  */
4451
  init_ggc ();
4452
  ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
4453
		mark_file_stack);
4454
  ggc_add_rtx_root (&stack_limit_rtx, 1);
4455 4456
  ggc_add_tree_root (&current_function_decl, 1);
  ggc_add_tree_root (&current_function_func_begin_label, 1);
4457

4458 4459 4460
  /* Initialize the diagnostics reporting machinery.  */
  initialize_diagnostics();

4461 4462 4463
  /* Perform language-specific options intialization.  */
  lang_init_options ();

Richard Stallman committed
4464 4465 4466 4467 4468 4469 4470
  /* Scan to see what optimization level has been specified.  That will
     determine the default value of many flags.  */
  for (i = 1; i < argc; i++)
    {
      if (!strcmp (argv[i], "-O"))
	{
	  optimize = 1;
4471
	  optimize_size = 0;
Richard Stallman committed
4472 4473 4474
	}
      else if (argv[i][0] == '-' && argv[i][1] == 'O')
	{
4475
	  /* Handle -Os, -O2, -O3, -O69, ...  */
Richard Stallman committed
4476
	  char *p = &argv[i][2];
4477 4478
	  
	  if ((p[0] == 's') && (p[1] == 0))
4479 4480 4481 4482 4483 4484
	    {
	      optimize_size = 1;
	      
	      /* Optimizing for size forces optimize to be 2. */
	      optimize = 2;
	    }
4485 4486
	  else
	    {	    
4487 4488
	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
	      if (optimize_val != -1)
4489
		{
4490
		  optimize = optimize_val;
4491 4492
		  optimize_size = 0;
		}
4493
	    }
Richard Stallman committed
4494 4495 4496 4497 4498
	}
    }

  if (optimize >= 1)
    {
4499
      flag_defer_pop = 1;
Richard Stallman committed
4500 4501 4502 4503
      flag_thread_jumps = 1;
#ifdef DELAY_SLOTS
      flag_delayed_branch = 1;
#endif
4504 4505 4506
#ifdef CAN_DEBUG_WITHOUT_FP
      flag_omit_frame_pointer = 1;
#endif
Richard Stallman committed
4507 4508 4509 4510
    }

  if (optimize >= 2)
    {
4511
      flag_optimize_sibling_calls = 1;
Richard Stallman committed
4512
      flag_cse_follow_jumps = 1;
4513
      flag_cse_skip_blocks = 1;
4514
      flag_gcse = 1;
Richard Stallman committed
4515 4516 4517
      flag_expensive_optimizations = 1;
      flag_strength_reduce = 1;
      flag_rerun_cse_after_loop = 1;
4518
      flag_rerun_loop_opt = 1;
4519
      flag_caller_saves = 1;
4520
      flag_force_mem = 1;
4521
      flag_peephole2 = 1;
Richard Stallman committed
4522 4523 4524 4525
#ifdef INSN_SCHEDULING
      flag_schedule_insns = 1;
      flag_schedule_insns_after_reload = 1;
#endif
4526
      flag_regmove = 1;
4527
      flag_strict_aliasing = 1;
4528
      flag_delete_null_pointer_checks = 1;
Richard Stallman committed
4529 4530
    }

4531 4532 4533 4534 4535
  if (optimize >= 3)
    {
      flag_inline_functions = 1;
    }

4536 4537 4538 4539 4540 4541 4542 4543
  if (optimize < 2 || optimize_size)
    {
      align_loops = 1;
      align_jumps = 1;
      align_labels = 1;
      align_functions = 1;
    }

4544 4545 4546 4547 4548
  /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
     modify it.  */
  target_flags = 0;
  set_target_switch ("");

4549 4550 4551 4552 4553 4554
  /* Unwind tables are always present in an ABI-conformant IA-64
     object file, so the default should be ON. */
#ifdef IA64_UNWIND_INFO
  flag_unwind_tables = IA64_UNWIND_INFO;
#endif

Richard Stallman committed
4555 4556
#ifdef OPTIMIZATION_OPTIONS
  /* Allow default optimizations to be specified on a per-machine basis.  */
4557
  OPTIMIZATION_OPTIONS (optimize, optimize_size);
Richard Stallman committed
4558 4559 4560 4561 4562
#endif

  /* Initialize register usage now so switches may override.  */
  init_reg_sets ();

4563 4564
  /* Perform normal command line switch decoding.  */
  for (i = 1; i < argc;)
Richard Stallman committed
4565
    {
4566 4567
      unsigned int lang_processed;
      unsigned int indep_processed;
Jason Merrill committed
4568

4569 4570
      /* Give the language a chance to decode the option for itself.  */
      lang_processed = lang_decode_option (argc - i, argv + i);
4571

4572 4573 4574
      /* Now see if the option also has a language independent meaning.
	 Some options are both language specific and language independent,
	 eg --help.  It is possible that there might be options that should
4575
	 only be decoded in a language independent way if they were not
4576
	 decoded in a language specific way, which is why 'lang_processed'
4577
	 is passed in.  */
4578 4579
      indep_processed = independent_decode_option (argc - i, argv + i,
						   lang_processed);
4580 4581

      if (lang_processed || indep_processed)
4582 4583
	i += (lang_processed > indep_processed
	      ? lang_processed : indep_processed);
4584
      else
4585
	{
4586 4587 4588 4589 4590 4591 4592 4593
	  const char * option = NULL;
	  const char * lang = NULL;
	  unsigned int j;
	  
	  /* It is possible that the command line switch is not valid for the
	     current language, but it is valid for another language.  In order
	     to be compatible with previous versions of the compiler (which
	     did not issue an error message in this case) we check for this
4594
	     possibility here.  If we do find a match, then if extra_warnings
4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606
	     is set we generate a warning message, otherwise we will just
	     ignore the option.  */
	  for (j = 0; j < NUM_ELEM (documented_lang_options); j++)
	    {
	      option = documented_lang_options[j].option;
	      
	      if (option == NULL)
		lang = documented_lang_options[j].description;
	      else if (! strncmp (argv[i], option, strlen (option)))
		break;
	    }

4607
	  if (j != NUM_ELEM (documented_lang_options))
4608 4609 4610 4611 4612 4613
	    {
	      if (extra_warnings)
		{
		  warning ("Ignoring command line option '%s'", argv[i]);
		  if (lang)
		    warning ("\
4614
(It is valid for %s but not the selected language)", lang);
4615 4616 4617
		}
	    }
	  else
4618
	    error ("Unrecognized option `%s'", argv[i]);
4619
	  
4620 4621
	  i++;
	}
Richard Stallman committed
4622
    }
4623 4624 4625
  
  /* Reflect any language-specific diagnostic option setting.  */
  reshape_diagnostic_buffer ();
Richard Stallman committed
4626

4627 4628 4629 4630
  /* Checker uses the frame pointer.  */
  if (flag_check_memory_usage)
    flag_omit_frame_pointer = 0;

4631 4632
  if (optimize == 0)
    {
4633 4634
      /* Inlining does not work if not optimizing,
	 so force it not to be done.  */
4635 4636
      flag_no_inline = 1;
      warn_inline = 0;
4637 4638 4639 4640 4641 4642

      /* The c_decode_option and lang_decode_option functions set
	 this to `2' if -Wall is used, so we can avoid giving out
	 lots of errors for people who don't realize what -Wall does.  */
      if (warn_uninitialized == 1)
	warning ("-Wuninitialized is not supported without -O");
4643 4644
    }

Richard Stallman committed
4645 4646 4647 4648 4649
#ifdef OVERRIDE_OPTIONS
  /* Some machines may reject certain combinations of options.  */
  OVERRIDE_OPTIONS;
#endif

4650 4651 4652 4653 4654
  if (exceptions_via_longjmp == 2)
    {
#ifdef DWARF2_UNWIND_INFO
      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
#else
4655 4656 4657
#ifdef IA64_UNWIND_INFO
      exceptions_via_longjmp = ! IA64_UNWIND_INFO;
#else
4658 4659
      exceptions_via_longjmp = 1;
#endif
4660
#endif
4661 4662
    }

4663 4664 4665 4666 4667 4668 4669 4670
  /* Since each function gets its own handler data, we can't support the
     new model currently, since it depend on a specific rethrow label
     which is declared at the front of the table, and we can only
     have one such symbol in a file.  */
#ifdef IA64_UNWIND_INFO
  flag_new_exceptions = 0;
#endif

4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681
  /* Set up the align_*_log variables, defaulting them to 1 if they
     were still unset.  */
  if (align_loops <= 0) align_loops = 1;
  align_loops_log = floor_log2 (align_loops*2-1);
  if (align_jumps <= 0) align_jumps = 1;
  align_jumps_log = floor_log2 (align_jumps*2-1);
  if (align_labels <= 0) align_labels = 1;
  align_labels_log = floor_log2 (align_labels*2-1);
  if (align_functions <= 0) align_functions = 1;
  align_functions_log = floor_log2 (align_functions*2-1);
  
Richard Kenner committed
4682 4683 4684 4685 4686 4687
  if (profile_block_flag == 3)
    {
      warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
      profile_block_flag = 2;
    }

Richard Stallman committed
4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711
  /* Unrolling all loops implies that standard loop unrolling must also
     be done.  */
  if (flag_unroll_all_loops)
    flag_unroll_loops = 1;
  /* Loop unrolling requires that strength_reduction be on also.  Silently
     turn on strength reduction here if it isn't already on.  Also, the loop
     unrolling code assumes that cse will be run after loop, so that must
     be turned on also.  */
  if (flag_unroll_loops)
    {
      flag_strength_reduce = 1;
      flag_rerun_cse_after_loop = 1;
    }

  /* Warn about options that are not supported on this machine.  */
#ifndef INSN_SCHEDULING
  if (flag_schedule_insns || flag_schedule_insns_after_reload)
    warning ("instruction scheduling not supported on this target machine");
#endif
#ifndef DELAY_SLOTS
  if (flag_delayed_branch)
    warning ("this target machine does not have delayed branches");
#endif

4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726
  user_label_prefix = USER_LABEL_PREFIX;
  if (flag_leading_underscore != -1)
    {
      /* If the default prefix is more complicated than "" or "_", 
	 issue a warning and ignore this option.  */
      if (user_label_prefix[0] == 0 ||
	  (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
	{
	  user_label_prefix = flag_leading_underscore ? "_" : "";
	}
      else
	warning ("-f%sleading-underscore not supported on this target machine",
		 flag_leading_underscore ? "" : "no-");
    }

Richard Stallman committed
4727 4728 4729 4730
  /* If we are in verbose mode, write out the version and maybe all the
     option flags in use.  */
  if (version_flag)
    {
4731
      print_version (stderr, "");
Richard Stallman committed
4732
      if (! quiet_flag)
4733
	print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
Richard Stallman committed
4734 4735 4736 4737
    }

  compile_file (filename);

4738
#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
Richard Stallman committed
4739 4740 4741 4742
  if (flag_print_mem)
    {
      char *lim = (char *) sbrk (0);

4743
      fnotice (stderr, "Data size %ld.\n", (long) (lim - (char *) &environ));
Richard Stallman committed
4744 4745
      fflush (stderr);

4746
#ifndef __MSDOS__
Richard Stallman committed
4747 4748 4749 4750 4751
#ifdef USG
      system ("ps -l 1>&2");
#else /* not USG */
      system ("ps v");
#endif /* not USG */
4752
#endif
Richard Stallman committed
4753
    }
4754
#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
Richard Stallman committed
4755 4756

  if (errorcount)
4757
    return (FATAL_EXIT_CODE);
Richard Stallman committed
4758
  if (sorrycount)
4759 4760
    return (FATAL_EXIT_CODE);
  return (SUCCESS_EXIT_CODE);
4761
}
Richard Stallman committed
4762 4763 4764 4765

/* Decode -m switches.  */
/* Decode the switch -mNAME.  */

4766
static void
Richard Stallman committed
4767
set_target_switch (name)
4768
  const char *name;
Richard Stallman committed
4769
{
4770
  register size_t j;
4771
  int valid_target_option = 0;
Richard Stallman committed
4772 4773 4774 4775 4776 4777 4778 4779

  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
    if (!strcmp (target_switches[j].name, name))
      {
	if (target_switches[j].value < 0)
	  target_flags &= ~-target_switches[j].value;
	else
	  target_flags |= target_switches[j].value;
4780
	valid_target_option = 1;
Richard Stallman committed
4781 4782 4783
      }

#ifdef TARGET_OPTIONS
4784
  if (!valid_target_option)
Richard Stallman committed
4785 4786 4787 4788 4789 4790
    for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
      {
	int len = strlen (target_options[j].prefix);
	if (!strncmp (target_options[j].prefix, name, len))
	  {
	    *target_options[j].variable = name + len;
4791
	    valid_target_option = 1;
Richard Stallman committed
4792 4793 4794 4795
	  }
      }
#endif

4796
  if (!valid_target_option)
Richard Stallman committed
4797 4798 4799
    error ("Invalid option `%s'", name);
}

4800 4801 4802
/* Print version information to FILE.
   Each line begins with INDENT (for the case where FILE is the
   assembler output file).  */
Richard Stallman committed
4803

4804
static void
4805 4806
print_version (file, indent)
     FILE *file;
4807
     const char *indent;
Richard Stallman committed
4808
{
4809
#ifndef __VERSION__
4810
#define __VERSION__ "[?]"
4811
#endif
4812 4813 4814
  fnotice (file,
#ifdef __GNUC__
	   "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
4815
#else
4816
	   "%s%s%s version %s (%s) compiled by CC.\n"
4817
#endif
4818 4819
	   , indent, *indent != 0 ? " " : "",
	   language_string, version_string, TARGET_NAME, __VERSION__);
4820
}
Richard Stallman committed
4821

4822
/* Print an option value and return the adjusted position in the line.
4823 4824
   ??? We don't handle error returns from fprintf (disk full); presumably
   other code will catch a disk full though.  */
Richard Stallman committed
4825

4826
static int
4827 4828 4829
print_single_switch (file, pos, max, indent, sep, term, type, name)
     FILE *file;
     int pos, max;
4830
     const char *indent, *sep, *term, *type, *name;
4831
{
4832 4833 4834 4835
  /* The ultrix fprintf returns 0 on success, so compute the result we want
     here since we need it for the following test.  */
  int len = strlen (sep) + strlen (type) + strlen (name);

4836
  if (pos != 0
4837
      && pos + len > max)
Richard Stallman committed
4838
    {
4839 4840
      fprintf (file, "%s", term);
      pos = 0;
Richard Stallman committed
4841
    }
4842 4843
  if (pos == 0)
    {
4844 4845
      fprintf (file, "%s", indent);
      pos = strlen (indent);
4846
    }
4847 4848
  fprintf (file, "%s%s%s", sep, type, name);
  pos += len;
4849
  return pos;
Richard Stallman committed
4850 4851
}
     
4852 4853 4854 4855
/* Print active target switches to FILE.
   POS is the current cursor position and MAX is the size of a "line".
   Each line begins with INDENT and ends with TERM.
   Each switch is separated from the next by SEP.  */
Richard Stallman committed
4856

4857
static void
4858 4859 4860
print_switch_values (file, pos, max, indent, sep, term)
     FILE *file;
     int pos, max;
4861
     const char *indent, *sep, *term;
Richard Stallman committed
4862
{
4863
  size_t j;
4864 4865 4866
  char **p;

  /* Print the options as passed.  */
Richard Stallman committed
4867

4868
  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
4869
			     _("options passed: "), "");
4870

4871
  for (p = &save_argv[1]; *p != NULL; p++)
4872 4873 4874
    if (**p == '-')
      {
	/* Ignore these.  */
4875 4876 4877 4878 4879 4880
	if (strcmp (*p, "-o") == 0)
	  {
	    if (p[1] != NULL)
	      p++;
	    continue;
	  }
4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897
	if (strcmp (*p, "-quiet") == 0)
	  continue;
	if (strcmp (*p, "-version") == 0)
	  continue;
	if ((*p)[1] == 'd')
	  continue;

	pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
      }
  if (pos > 0)
    fprintf (file, "%s", term);

  /* Print the -f and -m options that have been enabled.
     We don't handle language specific options but printing argv
     should suffice.  */

  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
4898
			     _("options enabled: "), "");
Richard Stallman committed
4899 4900 4901

  for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
    if (*f_options[j].variable == f_options[j].on_value)
4902 4903
      pos = print_single_switch (file, pos, max, indent, sep, term,
				 "-f", f_options[j].string);
Richard Stallman committed
4904

4905
  /* Print target specific options.  */
Richard Stallman committed
4906 4907 4908 4909 4910 4911

  for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
    if (target_switches[j].name[0] != '\0'
	&& target_switches[j].value > 0
	&& ((target_switches[j].value & target_flags)
	    == target_switches[j].value))
4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926
      {
	pos = print_single_switch (file, pos, max, indent, sep, term,
				   "-m", target_switches[j].name);
      }

#ifdef TARGET_OPTIONS
  for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
    if (*target_options[j].variable != NULL)
      {
	char prefix[256];
	sprintf (prefix, "-m%s", target_options[j].prefix);
	pos = print_single_switch (file, pos, max, indent, sep, term,
				   prefix, *target_options[j].variable);
      }
#endif
Richard Stallman committed
4927

4928
  fprintf (file, "%s", term);
Richard Stallman committed
4929
}
x  
Jason Merrill committed
4930 4931 4932 4933 4934

/* Record the beginning of a new source file, named FILENAME.  */

void
debug_start_source_file (filename)
Zack Weinberg committed
4935
     register const char *filename ATTRIBUTE_UNUSED;
x  
Jason Merrill committed
4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950
{
#ifdef DBX_DEBUGGING_INFO
  if (write_symbols == DBX_DEBUG)
    dbxout_start_new_source_file (filename);
#endif
#ifdef DWARF_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF_DEBUG)
    dwarfout_start_new_source_file (filename);
#endif /* DWARF_DEBUGGING_INFO */
#ifdef DWARF2_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF2_DEBUG)
    dwarf2out_start_source_file (filename);
#endif /* DWARF2_DEBUGGING_INFO */  
4951 4952 4953 4954
#ifdef SDB_DEBUGGING_INFO
  if (write_symbols == SDB_DEBUG)
    sdbout_start_new_source_file (filename);
#endif
x  
Jason Merrill committed
4955 4956 4957 4958 4959 4960 4961
}

/* Record the resumption of a source file.  LINENO is the line number in
   the source file we are returning to.  */

void
debug_end_source_file (lineno)
Kaveh R. Ghazi committed
4962
     register unsigned lineno ATTRIBUTE_UNUSED;
x  
Jason Merrill committed
4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977
{
#ifdef DBX_DEBUGGING_INFO
  if (write_symbols == DBX_DEBUG)
    dbxout_resume_previous_source_file ();
#endif
#ifdef DWARF_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF_DEBUG)
    dwarfout_resume_previous_source_file (lineno);
#endif /* DWARF_DEBUGGING_INFO */
#ifdef DWARF2_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF2_DEBUG)
    dwarf2out_end_source_file ();
#endif /* DWARF2_DEBUGGING_INFO */
4978 4979 4980 4981
#ifdef SDB_DEBUGGING_INFO
  if (write_symbols == SDB_DEBUG)
    sdbout_resume_previous_source_file ();
#endif
x  
Jason Merrill committed
4982 4983 4984 4985 4986 4987 4988 4989
}

/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
   the tail part of the directive line, i.e. the part which is past the
   initial whitespace, #, whitespace, directive-name, whitespace part.  */

void
debug_define (lineno, buffer)
Kaveh R. Ghazi committed
4990 4991
     register unsigned lineno ATTRIBUTE_UNUSED;
     register char *buffer ATTRIBUTE_UNUSED;
x  
Jason Merrill committed
4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010
{
#ifdef DWARF_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF_DEBUG)
    dwarfout_define (lineno, buffer);
#endif /* DWARF_DEBUGGING_INFO */
#ifdef DWARF2_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF2_DEBUG)
    dwarf2out_define (lineno, buffer);
#endif /* DWARF2_DEBUGGING_INFO */
}

/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
   the tail part of the directive line, i.e. the part which is past the
   initial whitespace, #, whitespace, directive-name, whitespace part.  */

void
debug_undef (lineno, buffer)
Kaveh R. Ghazi committed
5011 5012
     register unsigned lineno ATTRIBUTE_UNUSED;
     register char *buffer ATTRIBUTE_UNUSED;
x  
Jason Merrill committed
5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024
{
#ifdef DWARF_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF_DEBUG)
    dwarfout_undef (lineno, buffer);
#endif /* DWARF_DEBUGGING_INFO */
#ifdef DWARF2_DEBUGGING_INFO
  if (debug_info_level == DINFO_LEVEL_VERBOSE
      && write_symbols == DWARF2_DEBUG)
    dwarf2out_undef (lineno, buffer);
#endif /* DWARF2_DEBUGGING_INFO */
}
5025

5026 5027 5028 5029 5030
/* Returns nonzero if it is appropriate not to emit any debugging
   information for BLOCK, because it doesn't contain any instructions.
   This may not be the case for blocks containing nested functions, since
   we may actually call such a function even though the BLOCK information
   is messed up.  */
5031

5032
int
5033
debug_ignore_block (block)
5034
     tree block ATTRIBUTE_UNUSED;
5035
{
5036 5037 5038 5039 5040 5041
  /* Never delete the BLOCK for the outermost scope
     of the function; we can refer to names from
     that scope even if the block notes are messed up.  */
  if (is_body_block (block))
    return 0;

5042 5043
#ifdef DWARF2_DEBUGGING_INFO
  if (write_symbols == DWARF2_DEBUG)
5044
    return dwarf2out_ignore_block (block);
5045
#endif
5046 5047

  return 1;
5048
}