OSDN Git Service

* toplev.c (lang_options): Add -frtti flag for rtti support in C++.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
1 /* Top level of GNU C compiler
2    Copyright (C) 1987, 88, 89, 92, 93, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 /* This is the top level of cc1/c++.
22    It parses command args, opens files, invokes the various passes
23    in the proper order, and counts the time used by each.
24    Error messages and low-level interface to malloc also handled here.  */
25
26 #include "config.h"
27 #ifdef __STDC__
28 #include <stdarg.h>
29 #else
30 #include <varargs.h>
31 #endif
32 #include <stdio.h>
33 #include <signal.h>
34 #include <setjmp.h>
35 #include <sys/types.h>
36 #include <ctype.h>
37 #include <sys/stat.h>
38
39 #ifndef WINNT
40 #ifdef USG
41 #undef FLOAT
42 #include <sys/param.h>
43 /* This is for hpux.  It is a real screw.  They should change hpux.  */
44 #undef FLOAT
45 #include <sys/times.h>
46 #include <time.h>   /* Correct for hpux at least.  Is it good on other USG?  */
47 #undef FFS  /* Some systems define this in param.h.  */
48 #else
49 #ifndef VMS
50 #include <sys/time.h>
51 #include <sys/resource.h>
52 #endif
53 #endif
54 #endif
55
56 #include "input.h"
57 #include "tree.h"
58 /* #include "c-tree.h" */
59 #include "rtl.h"
60 #include "flags.h"
61 #include "insn-attr.h"
62 #include "defaults.h"
63
64 #ifdef XCOFF_DEBUGGING_INFO
65 #include "xcoffout.h"
66 #endif
67
68 #include "bytecode.h"
69 #include "bc-emit.h"
70 \f
71 #ifdef VMS
72 /* The extra parameters substantially improve the I/O performance.  */
73 static FILE *
74 vms_fopen (fname, type)
75      char * fname;
76      char * type;
77 {
78   /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
79      fixed arguments, which matches ANSI's specification but not VAXCRTL's
80      pre-ANSI implementation.  This hack circumvents the mismatch problem.  */
81   FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
82
83   if (*type == 'w')
84     return (*vmslib_fopen) (fname, type, "mbc=32",
85                             "deq=64", "fop=tef", "shr=nil");
86   else
87     return (*vmslib_fopen) (fname, type, "mbc=32");
88 }
89 #define fopen vms_fopen
90 #endif  /* VMS */
91
92 #ifndef DEFAULT_GDB_EXTENSIONS
93 #define DEFAULT_GDB_EXTENSIONS 1
94 #endif
95
96 extern int rtx_equal_function_value_matters;
97
98 #if ! (defined (VMS) || defined (OS2))
99 extern char **environ;
100 #endif
101 extern char *version_string, *language_string;
102
103 /* Carry information from ASM_DECLARE_OBJECT_NAME
104    to ASM_FINISH_DECLARE_OBJECT.  */
105
106 extern int size_directive_output;
107 extern tree last_assemble_variable_decl;
108
109 extern void init_lex ();
110 extern void init_decl_processing ();
111 extern void init_obstacks ();
112 extern void init_tree_codes ();
113 extern void init_rtl ();
114 extern void init_regs ();
115 extern void init_optabs ();
116 extern void init_stmt ();
117 extern void init_reg_sets ();
118 extern void dump_flow_info ();
119 extern void dump_sched_info ();
120 extern void dump_local_alloc ();
121
122 void rest_of_decl_compilation ();
123 void error_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
124 void error_with_decl PVPROTO((tree decl, char *s, ...));
125 void error_for_asm PVPROTO((rtx insn, char *s, ...));
126 void error PVPROTO((char *s, ...));
127 void fatal PVPROTO((char *s, ...));
128 void warning_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
129 void warning_with_decl PVPROTO((tree decl, char *s, ...));
130 void warning_for_asm PVPROTO((rtx insn, char *s, ...));
131 void warning PVPROTO((char *s, ...));
132 void pedwarn PVPROTO((char *s, ...));
133 void pedwarn_with_decl PVPROTO((tree decl, char *s, ...));
134 void pedwarn_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
135 void sorry PVPROTO((char *s, ...));
136 void really_sorry PVPROTO((char *s, ...));
137 void fancy_abort ();
138 #ifndef abort
139 void abort ();
140 #endif
141 void set_target_switch ();
142 static void print_switch_values ();
143 static char *decl_name ();
144
145 /* Name of program invoked, sans directories.  */
146
147 char *progname;
148
149 /* Copy of arguments to main.  */
150 int save_argc;
151 char **save_argv;
152 \f
153 /* Name of current original source file (what was input to cpp).
154    This comes from each #-command in the actual input.  */
155
156 char *input_filename;
157
158 /* Name of top-level original source file (what was input to cpp).
159    This comes from the #-command at the beginning of the actual input.
160    If there isn't any there, then this is the cc1 input file name.  */
161
162 char *main_input_filename;
163
164 /* Stream for reading from the input file.  */
165
166 FILE *finput;
167
168 /* Current line number in real source file.  */
169
170 int lineno;
171
172 /* Stack of currently pending input files.  */
173
174 struct file_stack *input_file_stack;
175
176 /* Incremented on each change to input_file_stack.  */
177 int input_file_stack_tick;
178
179 /* FUNCTION_DECL for function now being parsed or compiled.  */
180
181 extern tree current_function_decl;
182
183 /* Name to use as base of names for dump output files.  */
184
185 char *dump_base_name;
186
187 /* Bit flags that specify the machine subtype we are compiling for.
188    Bits are tested using macros TARGET_... defined in the tm.h file
189    and set by `-m...' switches.  Must be defined in rtlanal.c.  */
190
191 extern int target_flags;
192
193 /* Flags saying which kinds of debugging dump have been requested.  */
194
195 int rtl_dump = 0;
196 int rtl_dump_and_exit = 0;
197 int jump_opt_dump = 0;
198 int cse_dump = 0;
199 int loop_dump = 0;
200 int cse2_dump = 0;
201 int flow_dump = 0;
202 int combine_dump = 0;
203 int sched_dump = 0;
204 int local_reg_dump = 0;
205 int global_reg_dump = 0;
206 int sched2_dump = 0;
207 int jump2_opt_dump = 0;
208 int dbr_sched_dump = 0;
209 int flag_print_asm_name = 0;
210 int stack_reg_dump = 0;
211
212 /* Name for output file of assembly code, specified with -o.  */
213
214 char *asm_file_name;
215
216 /* Value of the -G xx switch, and whether it was passed or not.  */
217 int g_switch_value;
218 int g_switch_set;
219
220 /* Type(s) of debugging information we are producing (if any).
221    See flags.h for the definitions of the different possible
222    types of debugging information.  */
223 enum debug_info_type write_symbols = NO_DEBUG;
224
225 /* Level of debugging information we are producing.  See flags.h
226    for the definitions of the different possible levels.  */
227 enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
228
229 /* Nonzero means use GNU-only extensions in the generated symbolic
230    debugging information.  */
231 /* Currently, this only has an effect when write_symbols is set to
232    DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
233 int use_gnu_debug_info_extensions = 0;
234
235 /* Nonzero means do optimizations.  -O.
236    Particular numeric values stand for particular amounts of optimization;
237    thus, -O2 stores 2 here.  However, the optimizations beyond the basic
238    ones are not controlled directly by this variable.  Instead, they are
239    controlled by individual `flag_...' variables that are defaulted
240    based on this variable.  */
241
242 int optimize = 0;
243
244 /* Number of error messages and warning messages so far.  */
245
246 int errorcount = 0;
247 int warningcount = 0;
248 int sorrycount = 0;
249
250 /* Flag to output bytecode instead of native assembler */
251 int output_bytecode = 0;
252
253 /* Pointer to function to compute the name to use to print a declaration.  */
254
255 char *(*decl_printable_name) ();
256
257 /* Pointer to function to compute rtl for a language-specific tree code.  */
258
259 struct rtx_def *(*lang_expand_expr) ();
260
261 /* Pointer to function to finish handling an incomplete decl at the
262    end of compilation.  */
263
264 void (*incomplete_decl_finalize_hook) () = 0;
265
266 /* Pointer to function for interim exception handling implementation.
267    This interface will change, and it is only here until a better interface
268    replaces it.  */
269
270 void (*interim_eh_hook) PROTO((tree));
271
272 /* Nonzero if generating code to do profiling.  */
273
274 int profile_flag = 0;
275
276 /* Nonzero if generating code to do profiling on a line-by-line basis.  */
277
278 int profile_block_flag;
279
280 /* Nonzero for -pedantic switch: warn about anything
281    that standard spec forbids.  */
282
283 int pedantic = 0;
284
285 /* Temporarily suppress certain warnings.
286    This is set while reading code from a system header file.  */
287
288 int in_system_header = 0;
289
290 /* Nonzero means do stupid register allocation.
291    Currently, this is 1 if `optimize' is 0.  */
292
293 int obey_regdecls = 0;
294
295 /* Don't print functions as they are compiled and don't print
296    times taken by the various passes.  -quiet.  */
297
298 int quiet_flag = 0;
299 \f
300 /* -f flags.  */
301
302 /* Nonzero means `char' should be signed.  */
303
304 int flag_signed_char;
305
306 /* Nonzero means give an enum type only as many bytes as it needs.  */
307
308 int flag_short_enums;
309
310 /* Nonzero for -fcaller-saves: allocate values in regs that need to
311    be saved across function calls, if that produces overall better code.
312    Optional now, so people can test it.  */
313
314 #ifdef DEFAULT_CALLER_SAVES
315 int flag_caller_saves = 1;
316 #else
317 int flag_caller_saves = 0;
318 #endif
319
320 /* Nonzero if structures and unions should be returned in memory.
321
322    This should only be defined if compatibility with another compiler or
323    with an ABI is needed, because it results in slower code.  */
324
325 #ifndef DEFAULT_PCC_STRUCT_RETURN
326 #define DEFAULT_PCC_STRUCT_RETURN 1
327 #endif
328
329 /* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */
330
331 int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
332
333 /* Nonzero for -fforce-mem: load memory value into a register
334    before arithmetic on it.  This makes better cse but slower compilation.  */
335
336 int flag_force_mem = 0;
337
338 /* Nonzero for -fforce-addr: load memory address into a register before
339    reference to memory.  This makes better cse but slower compilation.  */
340
341 int flag_force_addr = 0;
342
343 /* Nonzero for -fdefer-pop: don't pop args after each function call;
344    instead save them up to pop many calls' args with one insns.  */
345
346 int flag_defer_pop = 0;
347
348 /* Nonzero for -ffloat-store: don't allocate floats and doubles
349    in extended-precision registers.  */
350
351 int flag_float_store = 0;
352
353 /* Nonzero for -fcse-follow-jumps:
354    have cse follow jumps to do a more extensive job.  */
355
356 int flag_cse_follow_jumps;
357
358 /* Nonzero for -fcse-skip-blocks:
359    have cse follow a branch around a block.  */
360 int flag_cse_skip_blocks;
361
362 /* Nonzero for -fexpensive-optimizations:
363    perform miscellaneous relatively-expensive optimizations.  */
364 int flag_expensive_optimizations;
365
366 /* Nonzero for -fthread-jumps:
367    have jump optimize output of loop.  */
368
369 int flag_thread_jumps;
370
371 /* Nonzero enables strength-reduction in loop.c.  */
372
373 int flag_strength_reduce = 0;
374
375 /* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
376    number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
377    UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
378    unrolled.  */
379
380 int flag_unroll_loops;
381
382 /* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
383    This is generally not a win.  */
384
385 int flag_unroll_all_loops;
386
387 /* Nonzero for -fwritable-strings:
388    store string constants in data segment and don't uniquize them.  */
389
390 int flag_writable_strings = 0;
391
392 /* Nonzero means don't put addresses of constant functions in registers.
393    Used for compiling the Unix kernel, where strange substitutions are
394    done on the assembly output.  */
395
396 int flag_no_function_cse = 0;
397
398 /* Nonzero for -fomit-frame-pointer:
399    don't make a frame pointer in simple functions that don't require one.  */
400
401 int flag_omit_frame_pointer = 0;
402
403 /* Nonzero to inhibit use of define_optimization peephole opts.  */
404
405 int flag_no_peephole = 0;
406
407 /* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
408    operations in the interest of optimization.  For example it allows
409    GCC to assume arguments to sqrt are nonnegative numbers, allowing
410    faster code for sqrt to be generated. */
411
412 int flag_fast_math = 0;
413
414 /* Nonzero means all references through pointers are volatile.  */
415
416 int flag_volatile;
417
418 /* Nonzero means treat all global and extern variables as global.  */
419
420 int flag_volatile_global;
421
422 /* Nonzero means just do syntax checking; don't output anything.  */
423
424 int flag_syntax_only = 0;
425
426 /* Nonzero means to rerun cse after loop optimization.  This increases
427    compilation time about 20% and picks up a few more common expressions.  */
428
429 static int flag_rerun_cse_after_loop;
430
431 /* Nonzero for -finline-functions: ok to inline functions that look like
432    good inline candidates.  */
433
434 int flag_inline_functions;
435
436 /* Nonzero for -fkeep-inline-functions: even if we make a function
437    go inline everywhere, keep its definition around for debugging
438    purposes.  */
439
440 int flag_keep_inline_functions;
441
442 /* Nonzero means that functions will not be inlined.  */
443
444 int flag_no_inline;
445
446 /* Nonzero means we should be saving declaration info into a .X file.  */
447
448 int flag_gen_aux_info = 0;
449
450 /* Specified name of aux-info file.  */
451
452 static char *aux_info_file_name;
453
454 /* Nonzero means make the text shared if supported.  */
455
456 int flag_shared_data;
457
458 /* Nonzero means schedule into delayed branch slots if supported.  */
459
460 int flag_delayed_branch;
461
462 /* Nonzero means to run cleanups after CALL_EXPRs.  */
463
464 int flag_short_temps;
465
466 /* Nonzero if we are compiling pure (sharable) code.
467    Value is 1 if we are doing reasonable (i.e. simple
468    offset into offset table) pic.  Value is 2 if we can
469    only perform register offsets.  */
470
471 int flag_pic;
472
473 /* Nonzero means place uninitialized global data in the bss section. */
474
475 int flag_no_common;
476
477 /* Nonzero means pretend it is OK to examine bits of target floats,
478    even if that isn't true.  The resulting code will have incorrect constants,
479    but the same series of instructions that the native compiler would make.  */
480
481 int flag_pretend_float;
482
483 /* Nonzero means change certain warnings into errors.
484    Usually these are warnings about failure to conform to some standard.  */
485
486 int flag_pedantic_errors = 0;
487
488 /* flag_schedule_insns means schedule insns within basic blocks (before
489    local_alloc).
490    flag_schedule_insns_after_reload means schedule insns after
491    global_alloc.  */
492
493 int flag_schedule_insns = 0;
494 int flag_schedule_insns_after_reload = 0;
495
496 /* -finhibit-size-directive inhibits output of .size for ELF.
497    This is used only for compiling crtstuff.c, 
498    and it may be extended to other effects
499    needed for crtstuff.c on other systems.  */
500 int flag_inhibit_size_directive = 0;
501
502 /* -fverbose-asm causes extra commentary information to be produced in
503    the generated assembly code (to make it more readable).  This option
504    is generally only of use to those who actually need to read the
505    generated assembly code (perhaps while debugging the compiler itself).  */
506
507 int flag_verbose_asm = 0;
508
509 /* -fgnu-linker specifies use of the GNU linker for initializations.
510    (Or, more generally, a linker that handles initializations.)
511    -fno-gnu-linker says that collect2 will be used.  */
512 #ifdef USE_COLLECT2
513 int flag_gnu_linker = 0;
514 #else
515 int flag_gnu_linker = 1;
516 #endif
517
518 /* Table of language-independent -f options.
519    STRING is the option name.  VARIABLE is the address of the variable.
520    ON_VALUE is the value to store in VARIABLE
521     if `-fSTRING' is seen as an option.
522    (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
523
524 struct { char *string; int *variable; int on_value;} f_options[] =
525 {
526   {"float-store", &flag_float_store, 1},
527   {"volatile", &flag_volatile, 1},
528   {"volatile-global", &flag_volatile_global, 1},
529   {"defer-pop", &flag_defer_pop, 1},
530   {"omit-frame-pointer", &flag_omit_frame_pointer, 1},
531   {"cse-follow-jumps", &flag_cse_follow_jumps, 1},
532   {"cse-skip-blocks", &flag_cse_skip_blocks, 1},
533   {"expensive-optimizations", &flag_expensive_optimizations, 1},
534   {"thread-jumps", &flag_thread_jumps, 1},
535   {"strength-reduce", &flag_strength_reduce, 1},
536   {"unroll-loops", &flag_unroll_loops, 1},
537   {"unroll-all-loops", &flag_unroll_all_loops, 1},
538   {"writable-strings", &flag_writable_strings, 1},
539   {"peephole", &flag_no_peephole, 0},
540   {"force-mem", &flag_force_mem, 1},
541   {"force-addr", &flag_force_addr, 1},
542   {"function-cse", &flag_no_function_cse, 0},
543   {"inline-functions", &flag_inline_functions, 1},
544   {"keep-inline-functions", &flag_keep_inline_functions, 1},
545   {"inline", &flag_no_inline, 0},
546   {"syntax-only", &flag_syntax_only, 1},
547   {"shared-data", &flag_shared_data, 1},
548   {"caller-saves", &flag_caller_saves, 1},
549   {"pcc-struct-return", &flag_pcc_struct_return, 1},
550   {"reg-struct-return", &flag_pcc_struct_return, 0},
551   {"delayed-branch", &flag_delayed_branch, 1},
552   {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
553   {"pretend-float", &flag_pretend_float, 1},
554   {"schedule-insns", &flag_schedule_insns, 1},
555   {"schedule-insns2", &flag_schedule_insns_after_reload, 1},
556   {"pic", &flag_pic, 1},
557   {"PIC", &flag_pic, 2},
558   {"fast-math", &flag_fast_math, 1},
559   {"common", &flag_no_common, 0},
560   {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
561   {"verbose-asm", &flag_verbose_asm, 1},
562   {"gnu-linker", &flag_gnu_linker, 1},
563   {"bytecode", &output_bytecode, 1}
564 };
565
566 /* Table of language-specific options.  */
567
568 char *lang_options[] =
569 {
570   "-ansi",
571   "-fallow-single-precision",
572
573   "-fsigned-bitfields",
574   "-funsigned-bitfields",
575   "-fno-signed-bitfields",
576   "-fno-unsigned-bitfields",
577   "-fsigned-char",
578   "-funsigned-char",
579   "-fno-signed-char",
580   "-fno-unsigned-char",
581
582   "-ftraditional",
583   "-traditional",
584   "-fnotraditional",
585   "-fno-traditional",
586
587   "-fasm",
588   "-fno-asm",
589   "-fbuiltin",
590   "-fno-builtin",
591   "-fcond-mismatch",
592   "-fno-cond-mismatch",
593   "-fdollars-in-identifiers",
594   "-fno-dollars-in-identifiers",
595   "-fident",
596   "-fno-ident",
597   "-fshort-double",
598   "-fno-short-double",
599   "-fshort-enums",
600   "-fno-short-enums",
601
602   "-Wall",
603   "-Wbad-function-cast",
604   "-Wno-bad-function-cast",
605   "-Wcast-qual",
606   "-Wno-cast-qual",
607   "-Wchar-subscripts",
608   "-Wno-char-subscripts",
609   "-Wcomment",
610   "-Wno-comment",
611   "-Wcomments",
612   "-Wno-comments",
613   "-Wconversion",
614   "-Wno-conversion",
615   "-Wformat",
616   "-Wno-format",
617   "-Wimport",
618   "-Wno-import",
619   "-Wimplicit",
620   "-Wno-implicit",
621   "-Wmissing-braces",
622   "-Wno-missing-braces",
623   "-Wmissing-declarations",
624   "-Wno-missing-declarations",
625   "-Wmissing-prototypes",
626   "-Wno-missing-prototypes",
627   "-Wnested-externs",
628   "-Wno-nested-externs",
629   "-Wparentheses",
630   "-Wno-parentheses",
631   "-Wpointer-arith",
632   "-Wno-pointer-arith",
633   "-Wredundant-decls",
634   "-Wno-redundant-decls",
635   "-Wstrict-prototypes",
636   "-Wno-strict-prototypes",
637   "-Wtraditional",
638   "-Wno-traditional",
639   "-Wtrigraphs",
640   "-Wno-trigraphs",
641   "-Wwrite-strings",
642   "-Wno-write-strings",
643
644   /* These are for C++.  */
645   "-+e0",                       /* gcc.c tacks the `-' on the front.  */
646   "-+e1",
647   "-+e2",
648   "-faccess-control",
649   "-fno-access-control",
650   "-fall-virtual",
651   "-fno-all-virtual",
652   "-falt-external-templates",
653   "-fno-alt-external-templates",
654   "-fansi-overloading",
655   "-fno-ansi-overloading",
656   "-fcadillac",
657   "-fno-cadillac",
658   "-fconserve-space",
659   "-fno-conserve-space",
660   "-fdefault-inline",
661   "-fno-default-inline",
662   "-frtti",
663   "-fno-rtti",
664   "-felide-constructors",
665   "-fno-elide-constructors",
666   "-fenum-int-equiv",
667   "-fno-enum-int-equiv",
668   "-fexternal-templates",
669   "-fno-external-templates",
670   "-fgc",
671   "-fno-gc",
672   "-fhandle-exceptions",
673   "-fno-handle-exceptions",
674   "-fhandle-signatures",
675   "-fno-handle-signatures",
676   "-fhuge-objects",
677   "-fno-huge-objects",
678   "-fimplement-inlines",
679   "-fno-implement-inlines",
680   "-fimplicit-templates",
681   "-fno-implicit-templates",
682   "-flabels-ok",
683   "-fno-labels-ok",
684   "-fmemoize-lookups",
685   "-fno-memoize-lookups",
686   "-fnonnull-objects",
687   "-fno-nonnull-objects",
688   "-fsave-memoized",
689   "-fno-save-memoized",
690   "-fshort-temps",
691   "-fno-short-temps",
692   "-fstats",
693   "-fno-stats",
694   "-fstrict-prototype",
695   "-fno-strict-prototype",
696   "-fthis-is-variable",
697   "-fno-this-is-variable",
698   "-fvtable-thunks",
699   "-fno-vtable-thunks",
700   "-fxref",
701   "-fno-xref",
702
703   "-Wreturn-type",
704   "-Wno-return-type",
705   "-Woverloaded-virtual",
706   "-Wno-overloaded-virtual",
707   "-Wenum-clash",
708   "-Wno-enum-clash",
709   "-Wtemplate-debugging",
710   "-Wno-template-debugging",
711   "-Wctor-dtor-privacy",
712   "-Wno-ctor-dtor-privacy",
713   "-Wnon-virtual-dtor",
714   "-Wno-non-virtual-dtor",
715   "-Wextern-inline",
716   "-Wno-extern-inline",
717   "-Wreorder",
718   "-Wno-reorder",
719   "-Wsynth",
720   "-Wno-synth",
721
722   /* these are for obj c */
723   "-lang-objc",
724   "-gen-decls",
725   "-fgnu-runtime",
726   "-fno-gnu-runtime",
727   "-fnext-runtime",
728   "-fno-next-runtime",
729   "-Wselector",
730   "-Wno-selector",
731   "-Wprotocol",
732   "-Wno-protocol",
733
734   /* This is for GNAT and is temporary.  */
735   "-gnat",
736   0
737 };
738 \f
739 /* Options controlling warnings */
740
741 /* Don't print warning messages.  -w.  */
742
743 int inhibit_warnings = 0;
744
745 /* Print various extra warnings.  -W.  */
746
747 int extra_warnings = 0;
748
749 /* Treat warnings as errors.  -Werror.  */
750
751 int warnings_are_errors = 0;
752
753 /* Nonzero to warn about unused local variables.  */
754
755 int warn_unused;
756
757 /* Nonzero to warn about variables used before they are initialized.  */
758
759 int warn_uninitialized;
760
761 /* Nonzero means warn about all declarations which shadow others.   */
762
763 int warn_shadow;
764
765 /* Warn if a switch on an enum fails to have a case for every enum value.  */
766
767 int warn_switch;
768
769 /* Nonzero means warn about function definitions that default the return type
770    or that use a null return and have a return-type other than void.  */
771
772 int warn_return_type;
773
774 /* Nonzero means warn about pointer casts that increase the required
775    alignment of the target type (and might therefore lead to a crash
776    due to a misaligned access).  */
777
778 int warn_cast_align;
779
780 /* Nonzero means warn about any identifiers that match in the first N
781    characters.  The value N is in `id_clash_len'.  */
782
783 int warn_id_clash;
784 unsigned id_clash_len;
785
786 /* Nonzero means warn about any objects definitions whose size is larger
787    than N bytes.  Also want about function definitions whose returned
788    values are larger than N bytes. The value N is in `larger_than_size'.  */
789  
790 int warn_larger_than;
791 unsigned larger_than_size;
792
793 /* Nonzero means warn if inline function is too large.  */
794
795 int warn_inline;
796
797 /* Warn if a function returns an aggregate,
798    since there are often incompatible calling conventions for doing this.  */
799
800 int warn_aggregate_return;
801
802 /* Likewise for -W.  */
803
804 struct { char *string; int *variable; int on_value;} W_options[] =
805 {
806   {"unused", &warn_unused, 1},
807   {"error", &warnings_are_errors, 1},
808   {"shadow", &warn_shadow, 1},
809   {"switch", &warn_switch, 1},
810   {"aggregate-return", &warn_aggregate_return, 1},
811   {"cast-align", &warn_cast_align, 1},
812   {"uninitialized", &warn_uninitialized, 1},
813   {"inline", &warn_inline, 1}
814 };
815 \f
816 /* Output files for assembler code (real compiler output)
817    and debugging dumps.  */
818
819 FILE *asm_out_file;
820 FILE *aux_info_file;
821 FILE *rtl_dump_file;
822 FILE *jump_opt_dump_file;
823 FILE *cse_dump_file;
824 FILE *loop_dump_file;
825 FILE *cse2_dump_file;
826 FILE *flow_dump_file;
827 FILE *combine_dump_file;
828 FILE *sched_dump_file;
829 FILE *local_reg_dump_file;
830 FILE *global_reg_dump_file;
831 FILE *sched2_dump_file;
832 FILE *jump2_opt_dump_file;
833 FILE *dbr_sched_dump_file;
834 FILE *stack_reg_dump_file;
835
836 /* Time accumulators, to count the total time spent in various passes.  */
837
838 int parse_time;
839 int varconst_time;
840 int integration_time;
841 int jump_time;
842 int cse_time;
843 int loop_time;
844 int cse2_time;
845 int flow_time;
846 int combine_time;
847 int sched_time;
848 int local_alloc_time;
849 int global_alloc_time;
850 int sched2_time;
851 int dbr_sched_time;
852 int shorten_branch_time;
853 int stack_reg_time;
854 int final_time;
855 int symout_time;
856 int dump_time;
857 \f
858 /* Return time used so far, in microseconds.  */
859
860 int
861 get_run_time ()
862 {
863 #ifdef WINNT
864   return 0;
865 #else
866 #ifdef USG
867   struct tms tms;
868 #else
869 #ifndef VMS
870   struct rusage rusage;
871 #else /* VMS */
872   struct
873     {
874       int proc_user_time;
875       int proc_system_time;
876       int child_user_time;
877       int child_system_time;
878     } vms_times;
879 #endif
880 #endif
881
882   if (quiet_flag)
883     return 0;
884
885 #ifdef USG
886   times (&tms);
887   return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
888 #else
889 #ifndef VMS
890   getrusage (0, &rusage);
891   return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
892           + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
893 #else /* VMS */
894   times (&vms_times);
895   return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
896 #endif
897 #endif
898 #endif
899 }
900
901 #define TIMEVAR(VAR, BODY)    \
902 do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
903
904 void
905 print_time (str, total)
906      char *str;
907      int total;
908 {
909   fprintf (stderr,
910            "time in %s: %d.%06d\n",
911            str, total / 1000000, total % 1000000);
912 }
913
914 /* Count an error or warning.  Return 1 if the message should be printed.  */
915
916 int
917 count_error (warningp)
918      int warningp;
919 {
920   if (warningp && inhibit_warnings)
921     return 0;
922
923   if (warningp && !warnings_are_errors)
924     warningcount++;
925   else
926     {
927       static int warning_message = 0;
928
929       if (warningp && !warning_message)
930         {
931           fprintf (stderr, "%s: warnings being treated as errors\n", progname);
932           warning_message = 1;
933         }
934       errorcount++;
935     }
936
937   return 1;
938 }
939
940 /* Print a fatal error message.  NAME is the text.
941    Also include a system error message based on `errno'.  */
942
943 void
944 pfatal_with_name (name)
945      char *name;
946 {
947   fprintf (stderr, "%s: ", progname);
948   perror (name);
949   exit (35);
950 }
951
952 void
953 fatal_io_error (name)
954      char *name;
955 {
956   fprintf (stderr, "%s: %s: I/O error\n", progname, name);
957   exit (35);
958 }
959
960 /* Called to give a better error message for a bad insn rather than
961    just calling abort().  */
962
963 void
964 fatal_insn (message, insn)
965      char *message;
966      rtx insn;
967 {
968   if (!output_bytecode)
969     {
970       error (message);
971       debug_rtx (insn);
972     }
973   if (asm_out_file)
974     fflush (asm_out_file);
975   if (aux_info_file)
976     fflush (aux_info_file);
977   if (rtl_dump_file)
978     fflush (rtl_dump_file);
979   if (jump_opt_dump_file)
980     fflush (jump_opt_dump_file);
981   if (cse_dump_file)
982     fflush (cse_dump_file);
983   if (loop_dump_file)
984     fflush (loop_dump_file);
985   if (cse2_dump_file)
986     fflush (cse2_dump_file);
987   if (flow_dump_file)
988     fflush (flow_dump_file);
989   if (combine_dump_file)
990     fflush (combine_dump_file);
991   if (sched_dump_file)
992     fflush (sched_dump_file);
993   if (local_reg_dump_file)
994     fflush (local_reg_dump_file);
995   if (global_reg_dump_file)
996     fflush (global_reg_dump_file);
997   if (sched2_dump_file)
998     fflush (sched2_dump_file);
999   if (jump2_opt_dump_file)
1000     fflush (jump2_opt_dump_file);
1001   if (dbr_sched_dump_file)
1002     fflush (dbr_sched_dump_file);
1003   if (stack_reg_dump_file)
1004     fflush (stack_reg_dump_file);
1005   abort ();
1006 }
1007
1008 /* Called to give a better error message when we don't have an insn to match
1009    what we are looking for or if the insn's constraints aren't satisfied,
1010    rather than just calling abort().  */
1011
1012 void
1013 fatal_insn_not_found (insn)
1014      rtx insn;
1015 {
1016   if (INSN_CODE (insn) < 0)
1017     fatal_insn ("internal error--unrecognizable insn:", insn);
1018   else
1019     fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
1020 }
1021
1022 /* This is the default decl_printable_name function.  */
1023
1024 static char *
1025 decl_name (decl, kind)
1026      tree decl;
1027      char **kind;
1028 {
1029   return IDENTIFIER_POINTER (DECL_NAME (decl));
1030 }
1031
1032 /* This is the default interim_eh_hook function.  */
1033
1034 void
1035 interim_eh (finalization)
1036      tree finalization;
1037 {
1038   /* Don't do anything by default.  */
1039 }
1040 \f
1041 static int need_error_newline;
1042
1043 /* Function of last error message;
1044    more generally, function such that if next error message is in it
1045    then we don't have to mention the function name.  */
1046 static tree last_error_function = NULL;
1047
1048 /* Used to detect when input_file_stack has changed since last described.  */
1049 static int last_error_tick;
1050
1051 /* Called when the start of a function definition is parsed,
1052    this function prints on stderr the name of the function.  */
1053
1054 void
1055 announce_function (decl)
1056      tree decl;
1057 {
1058   if (! quiet_flag)
1059     {
1060       char *junk;
1061       if (rtl_dump_and_exit)
1062         fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
1063       else
1064         fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk));
1065       fflush (stderr);
1066       need_error_newline = 1;
1067       last_error_function = current_function_decl;
1068     }
1069 }
1070
1071 /* Prints out, if necessary, the name of the current function
1072    which caused an error.  Called from all error and warning functions.  */
1073
1074 void
1075 report_error_function (file)
1076      char *file;
1077 {
1078   struct file_stack *p;
1079
1080   if (need_error_newline)
1081     {
1082       fprintf (stderr, "\n");
1083       need_error_newline = 0;
1084     }
1085
1086   if (last_error_function != current_function_decl)
1087     {
1088       char *kind = "function";
1089       if (current_function_decl != 0
1090           && TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
1091         kind = "method";
1092
1093       if (file)
1094         fprintf (stderr, "%s: ", file);
1095
1096       if (current_function_decl == NULL)
1097         fprintf (stderr, "At top level:\n");
1098       else
1099         {
1100           char *name = (*decl_printable_name) (current_function_decl, &kind);
1101           fprintf (stderr, "In %s `%s':\n", kind, name);
1102         }
1103
1104       last_error_function = current_function_decl;
1105     }
1106   if (input_file_stack && input_file_stack->next != 0
1107       && input_file_stack_tick != last_error_tick)
1108     {
1109       fprintf (stderr, "In file included");
1110       for (p = input_file_stack->next; p; p = p->next)
1111         {
1112           fprintf (stderr, " from %s:%d", p->name, p->line);
1113           if (p->next)
1114             fprintf (stderr, ",\n                ");
1115         }
1116       fprintf (stderr, ":\n");
1117       last_error_tick = input_file_stack_tick;
1118     }
1119 }
1120 \f
1121 /* Print a message.  */
1122
1123 static void
1124 vmessage (prefix, s, ap)
1125      char *prefix;
1126      char *s;
1127      va_list ap;
1128 {
1129   if (prefix)
1130     fprintf (stderr, "%s: ", prefix);
1131
1132 #ifdef HAVE_VPRINTF
1133   vfprintf (stderr, s, ap);
1134 #else
1135   {
1136     HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
1137     HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
1138     HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
1139     fprintf (stderr, s, v1, v2, v3);
1140   }
1141 #endif
1142 }
1143
1144 /* Print a message relevant to line LINE of file FILE.  */
1145
1146 static void
1147 v_message_with_file_and_line (file, line, prefix, s, ap)
1148      char *file;
1149      int line;
1150      char *prefix;
1151      char *s;
1152      va_list ap;
1153 {
1154   if (file)
1155     fprintf (stderr, "%s:%d: ", file, line);
1156   else
1157     fprintf (stderr, "%s: ", progname);
1158
1159   vmessage (prefix, s, ap);
1160   fputc ('\n', stderr);
1161 }
1162
1163 /* Print a message relevant to the given DECL.  */
1164
1165 static void
1166 v_message_with_decl (decl, prefix, s, ap)
1167      tree decl;
1168      char *prefix;
1169      char *s;
1170      va_list ap;
1171 {
1172   char *n, *p, *junk;
1173
1174   fprintf (stderr, "%s:%d: ",
1175            DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1176
1177   if (prefix)
1178     fprintf (stderr, "%s: ", prefix);
1179
1180   /* Do magic to get around lack of varargs support for insertion
1181      of arguments into existing list.  We know that the decl is first;
1182      we ass_u_me that it will be printed with "%s".  */
1183
1184   for (p = s; *p; ++p)
1185     {
1186       if (*p == '%')
1187         {
1188           if (*(p + 1) == '%')
1189             ++p;
1190           else
1191             break;
1192         }
1193     }
1194
1195   if (p > s)                    /* Print the left-hand substring.  */
1196     {
1197       char fmt[sizeof "%.255s"];
1198       long width = p - s;
1199              
1200       if (width > 255L) width = 255L;   /* arbitrary */
1201       sprintf (fmt, "%%.%lds", width);
1202       fprintf (stderr, fmt, s);
1203     }
1204
1205   if (*p == '%')                /* Print the name.  */
1206     {
1207       char *n = (DECL_NAME (decl)
1208                  ? (*decl_printable_name) (decl, &junk)
1209                  : "((anonymous))");
1210       fputs (n, stderr);
1211       while (*p)
1212         {
1213           ++p;
1214           if (isalpha (*(p - 1) & 0xFF))
1215             break;
1216         }
1217     }
1218
1219   if (*p)                       /* Print the rest of the message.  */
1220     vmessage ((char *)NULL, p, ap);
1221
1222   fputc ('\n', stderr);
1223 }
1224
1225 /* Figure file and line of the given INSN.  */
1226
1227 static void
1228 file_and_line_for_asm (insn, pfile, pline)
1229      rtx insn;
1230      char **pfile;
1231      int *pline;
1232 {
1233   rtx body = PATTERN (insn);
1234   rtx asmop;
1235
1236   /* Find the (or one of the) ASM_OPERANDS in the insn.  */
1237   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
1238     asmop = SET_SRC (body);
1239   else if (GET_CODE (body) == ASM_OPERANDS)
1240     asmop = body;
1241   else if (GET_CODE (body) == PARALLEL
1242            && GET_CODE (XVECEXP (body, 0, 0)) == SET)
1243     asmop = SET_SRC (XVECEXP (body, 0, 0));
1244   else if (GET_CODE (body) == PARALLEL
1245            && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
1246     asmop = XVECEXP (body, 0, 0);
1247   else
1248     asmop = NULL;
1249
1250   if (asmop)
1251     {
1252       *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
1253       *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
1254     }
1255   else
1256     {
1257       *pfile = input_filename;
1258       *pline = lineno;
1259     }
1260 }
1261
1262 /* Report an error at line LINE of file FILE.  */
1263
1264 static void
1265 v_error_with_file_and_line (file, line, s, ap)
1266      char *file;
1267      int line;
1268      char *s;
1269      va_list ap;
1270 {
1271   count_error (0);
1272   report_error_function (file);
1273   v_message_with_file_and_line (file, line, (char *)NULL, s, ap);
1274 }
1275
1276 void
1277 error_with_file_and_line VPROTO((char *file, int line, char *s, ...))
1278 {
1279 #ifndef __STDC__
1280   char *file;
1281   int line;
1282   char *s;
1283 #endif
1284   va_list ap;
1285
1286   VA_START (ap, s);
1287
1288 #ifndef __STDC__
1289   file = va_arg (ap, char *);
1290   line = va_arg (ap, int);
1291   s = va_arg (ap, char *);
1292 #endif
1293
1294   v_error_with_file_and_line (file, line, s, ap);
1295   va_end (ap);
1296 }
1297
1298 /* Report an error at the declaration DECL.
1299    S is a format string which uses %s to substitute the declaration
1300    name; subsequent substitutions are a la printf.  */
1301
1302 static void
1303 v_error_with_decl (decl, s, ap)
1304      tree decl;
1305      char *s;
1306      va_list ap;
1307 {
1308   count_error (0);
1309   report_error_function (DECL_SOURCE_FILE (decl));
1310   v_message_with_decl (decl, (char *)NULL, s, ap);
1311 }
1312
1313 void
1314 error_with_decl VPROTO((tree decl, char *s, ...))
1315 {
1316 #ifndef __STDC__
1317   tree decl;
1318   char *s;
1319 #endif
1320   va_list ap;
1321
1322   VA_START (ap, s);
1323
1324 #ifndef __STDC__
1325   decl = va_arg (ap, tree);
1326   s = va_arg (ap, char *);
1327 #endif
1328
1329   v_error_with_decl (decl, s, ap);
1330   va_end (ap);
1331 }
1332
1333 /* Report an error at the line number of the insn INSN.
1334    This is used only when INSN is an `asm' with operands,
1335    and each ASM_OPERANDS records its own source file and line.  */
1336
1337 static void
1338 v_error_for_asm (insn, s, ap)
1339      rtx insn;
1340      char *s;
1341      va_list ap;
1342 {
1343   char *file;
1344   int line;
1345
1346   count_error (0);
1347   file_and_line_for_asm (insn, &file, &line);
1348   report_error_function (file);
1349   v_message_with_file_and_line (file, line, (char *)NULL, s, ap);
1350 }
1351
1352 void
1353 error_for_asm VPROTO((rtx insn, char *s, ...))
1354 {
1355 #ifndef __STDC__
1356   rtx insn;
1357   char *s;
1358 #endif
1359   va_list ap;
1360
1361   VA_START (ap, s);
1362
1363 #ifndef __STDC__
1364   insn = va_arg (ap, rtx);
1365   s = va_arg (ap, char *);
1366 #endif
1367
1368   v_error_for_asm (insn, s, ap);
1369   va_end (ap);
1370 }
1371
1372 /* Report an error at the current line number.  */
1373
1374 static void
1375 verror (s, ap)
1376      char *s;
1377      va_list ap;
1378 {
1379   v_error_with_file_and_line (input_filename, lineno, s, ap);
1380 }
1381
1382 void
1383 error VPROTO((char *s, ...))
1384 {
1385 #ifndef __STDC__
1386   char *s;
1387 #endif
1388   va_list ap;
1389
1390   VA_START (ap, s);
1391
1392 #ifndef __STDC__
1393   s = va_arg (ap, char *);
1394 #endif
1395
1396   verror (s, ap);
1397   va_end (ap);
1398 }
1399
1400 /* Report a fatal error at the current line number.  */
1401
1402 static void
1403 vfatal (s, ap)
1404      char *s;
1405      va_list ap;
1406 {
1407   verror (s, ap);
1408   exit (34);
1409 }
1410
1411 void
1412 fatal VPROTO((char *s, ...))
1413 {
1414 #ifndef __STDC__
1415   char *s;
1416 #endif
1417   va_list ap;
1418
1419   VA_START (ap, s);
1420
1421 #ifndef __STDC__
1422   s = va_arg (ap, char *);
1423 #endif
1424
1425   vfatal (s, ap);
1426   va_end (ap);
1427 }
1428
1429 /* Report a warning at line LINE of file FILE.  */
1430
1431 static void
1432 v_warning_with_file_and_line (file, line, s, ap)
1433      char *file;
1434      int line;
1435      char *s;
1436      va_list ap;
1437 {
1438   if (count_error (1))
1439     {
1440       report_error_function (file);
1441       v_message_with_file_and_line (file, line, "warning", s, ap);
1442     }
1443 }
1444
1445 void
1446 warning_with_file_and_line VPROTO((char *file, int line, char *s, ...))
1447 {
1448 #ifndef __STDC__
1449   char *file;
1450   int line;
1451   char *s;
1452 #endif
1453   va_list ap;
1454
1455   VA_START (ap, s);
1456
1457 #ifndef __STDC__
1458   file = va_arg (ap, char *);
1459   line = va_arg (ap, int);
1460   s = va_arg (ap, char *);
1461 #endif
1462
1463   v_warning_with_file_and_line (file, line, s, ap);
1464   va_end (ap);
1465 }
1466
1467 /* Report a warning at the declaration DECL.
1468    S is a format string which uses %s to substitute the declaration
1469    name; subsequent substitutions are a la printf.  */
1470
1471 static void
1472 v_warning_with_decl (decl, s, ap)
1473      tree decl;
1474      char *s;
1475      va_list ap;
1476 {
1477   if (count_error (1))
1478     {
1479       report_error_function (DECL_SOURCE_FILE (decl));
1480       v_message_with_decl (decl, "warning", s, ap);
1481     }
1482 }
1483
1484 void
1485 warning_with_decl VPROTO((tree decl, char *s, ...))
1486 {
1487 #ifndef __STDC__
1488   tree decl;
1489   char *s;
1490 #endif
1491   va_list ap;
1492
1493   VA_START (ap, s);
1494
1495 #ifndef __STDC__
1496   decl = va_arg (ap, tree);
1497   s = va_arg (ap, char *);
1498 #endif
1499
1500   v_warning_with_decl (decl, s, ap);
1501   va_end (ap);
1502 }
1503
1504 /* Report a warning at the line number of the insn INSN.
1505    This is used only when INSN is an `asm' with operands,
1506    and each ASM_OPERANDS records its own source file and line.  */
1507
1508 static void
1509 v_warning_for_asm (insn, s, ap)
1510      rtx insn;
1511      char *s;
1512      va_list ap;
1513 {
1514   if (count_error (1))
1515     {
1516       char *file;
1517       int line;
1518
1519       file_and_line_for_asm (insn, &file, &line);
1520       report_error_function (file);
1521       v_message_with_file_and_line (file, line, "warning", s, ap);
1522     }
1523 }
1524
1525 void
1526 warning_for_asm VPROTO((rtx insn, char *s, ...))
1527 {
1528 #ifndef __STDC__
1529   rtx insn;
1530   char *s;
1531 #endif
1532   va_list ap;
1533
1534   VA_START (ap, s);
1535
1536 #ifndef __STDC__
1537   insn = va_arg (ap, rtx);
1538   s = va_arg (ap, char *);
1539 #endif
1540
1541   v_warning_for_asm (insn, s, ap);
1542   va_end (ap);
1543 }
1544
1545 /* Report a warning at the current line number.  */
1546
1547 static void
1548 vwarning (s, ap)
1549      char *s;
1550      va_list ap;
1551 {
1552   v_warning_with_file_and_line (input_filename, lineno, s, ap);
1553 }
1554
1555 void
1556 warning VPROTO((char *s, ...))
1557 {
1558 #ifndef __STDC__
1559   char *s;
1560 #endif
1561   va_list ap;
1562
1563   VA_START (ap, s);
1564
1565 #ifndef __STDC__
1566   s = va_arg (ap, char *);
1567 #endif
1568
1569   vwarning (s, ap);
1570   va_end (ap);
1571 }
1572
1573 /* These functions issue either warnings or errors depending on
1574    -pedantic-errors.  */
1575
1576 static void
1577 vpedwarn (s, ap)
1578      char *s;
1579      va_list ap;
1580 {
1581   if (flag_pedantic_errors)
1582     verror (s, ap);
1583   else
1584     vwarning (s, ap);
1585 }
1586
1587 void
1588 pedwarn VPROTO((char *s, ...))
1589 {
1590 #ifndef __STDC__
1591   char *s;
1592 #endif
1593   va_list ap;
1594
1595   VA_START (ap, s);
1596
1597 #ifndef __STDC__
1598   s = va_arg (ap, char *);
1599 #endif
1600
1601   vpedwarn (s, ap);
1602   va_end (ap);
1603 }
1604
1605 static void
1606 v_pedwarn_with_decl (decl, s, ap)
1607      tree decl;
1608      char *s;
1609      va_list ap;
1610 {
1611   /* We don't want -pedantic-errors to cause the compilation to fail from
1612      "errors" in system header files.  Sometimes fixincludes can't fix what's
1613      broken (eg: unsigned char bitfields - fixing it may change the alignment
1614      which will cause programs to mysteriously fail because the C library
1615      or kernel uses the original layout).  There's no point in issuing a
1616      warning either, it's just unnecessary noise.  */
1617
1618   if (! DECL_IN_SYSTEM_HEADER (decl))
1619     {
1620       if (flag_pedantic_errors)
1621         v_error_with_decl (decl, s, ap);
1622       else
1623         v_warning_with_decl (decl, s, ap);
1624     }
1625 }
1626
1627 void
1628 pedwarn_with_decl VPROTO((tree decl, char *s, ...))
1629 {
1630 #ifndef __STDC__
1631   tree decl;
1632   char *s;
1633 #endif
1634   va_list ap;
1635
1636   VA_START (ap, s);
1637
1638 #ifndef __STDC__
1639   decl = va_arg (ap, tree);
1640   s = va_arg (ap, char *);
1641 #endif
1642
1643   v_pedwarn_with_decl (decl, s, ap);
1644   va_end (ap);
1645 }
1646
1647 static void
1648 v_pedwarn_with_file_and_line (file, line, s, ap)
1649      char *file;
1650      int line;
1651      char *s;
1652      va_list ap;
1653 {
1654   if (flag_pedantic_errors)
1655     v_error_with_file_and_line (file, line, s, ap);
1656   else
1657     v_warning_with_file_and_line (file, line, s, ap);
1658 }
1659
1660 void
1661 pedwarn_with_file_and_line VPROTO((char *file, int line, char *s, ...))
1662 {
1663 #ifndef __STDC__
1664   char *file;
1665   int line;
1666   char *s;
1667 #endif
1668   va_list ap;
1669
1670   VA_START (ap, s);
1671
1672 #ifndef __STDC__
1673   file = va_arg (ap, char *);
1674   line = va_arg (ap, int);
1675   s = va_arg (ap, char *);
1676 #endif
1677
1678   v_pedwarn_with_file_and_line (file, line, s, ap);
1679   va_end (ap);
1680 }
1681
1682 /* Apologize for not implementing some feature.  */
1683
1684 static void
1685 vsorry (s, ap)
1686      char *s;
1687      va_list ap;
1688 {
1689   sorrycount++;
1690   if (input_filename)
1691     fprintf (stderr, "%s:%d: ", input_filename, lineno);
1692   else
1693     fprintf (stderr, "%s: ", progname);
1694   vmessage ("sorry, not implemented", s, ap);
1695   fputc ('\n', stderr);
1696 }
1697
1698 void
1699 sorry VPROTO((char *s, ...))
1700 {
1701 #ifndef __STDC__
1702   char *s;
1703 #endif
1704   va_list ap;
1705
1706   VA_START (ap, s);
1707
1708 #ifndef __STDC__
1709   s = va_arg (ap, char *);
1710 #endif
1711
1712   vsorry (s, ap);
1713   va_end (ap);
1714 }
1715
1716 /* Apologize for not implementing some feature, then quit.  */
1717
1718 static void
1719 v_really_sorry (s, ap)
1720      char *s;
1721      va_list ap;
1722 {
1723   sorrycount++;
1724   if (input_filename)
1725     fprintf (stderr, "%s:%d: ", input_filename, lineno);
1726   else
1727     fprintf (stderr, "%s: ", progname);
1728   vmessage ("sorry, not implemented", s, ap);
1729   fatal (" (fatal)\n");
1730 }
1731
1732 void
1733 really_sorry VPROTO((char *s, ...))
1734 {
1735 #ifndef __STDC__
1736   char *s;
1737 #endif
1738   va_list ap;
1739
1740   VA_START (ap, s);
1741
1742 #ifndef __STDC__
1743   s = va_arg (ap, char *);
1744 #endif
1745
1746   v_really_sorry (s, ap);
1747   va_end (ap);
1748 }
1749 \f
1750 /* More 'friendly' abort that prints the line and file.
1751    config.h can #define abort fancy_abort if you like that sort of thing.
1752
1753    I don't think this is actually a good idea.
1754    Other sorts of crashes will look a certain way.
1755    It is a good thing if crashes from calling abort look the same way.
1756      -- RMS  */
1757
1758 void
1759 fancy_abort ()
1760 {
1761   fatal ("internal gcc abort");
1762 }
1763
1764 /* This calls abort and is used to avoid problems when abort if a macro.
1765    It is used when we need to pass the address of abort.  */
1766
1767 void
1768 do_abort ()
1769 {
1770   abort ();
1771 }
1772
1773 /* When `malloc.c' is compiled with `rcheck' defined,
1774    it calls this function to report clobberage.  */
1775
1776 void
1777 botch (s)
1778 {
1779   abort ();
1780 }
1781
1782 /* Same as `malloc' but report error if no memory available.  */
1783
1784 char *
1785 xmalloc (size)
1786      unsigned size;
1787 {
1788   register char *value = (char *) malloc (size);
1789   if (value == 0)
1790     fatal ("virtual memory exhausted");
1791   return value;
1792 }
1793
1794 /* Same as `realloc' but report error if no memory available.  */
1795
1796 char *
1797 xrealloc (ptr, size)
1798      char *ptr;
1799      int size;
1800 {
1801   char *result = (char *) realloc (ptr, size);
1802   if (!result)
1803     fatal ("virtual memory exhausted");
1804   return result;
1805 }
1806 \f
1807 /* Return the logarithm of X, base 2, considering X unsigned,
1808    if X is a power of 2.  Otherwise, returns -1.
1809
1810    This should be used via the `exact_log2' macro.  */
1811
1812 int
1813 exact_log2_wide (x)
1814      register unsigned HOST_WIDE_INT x;
1815 {
1816   register int log = 0;
1817   /* Test for 0 or a power of 2.  */
1818   if (x == 0 || x != (x & -x))
1819     return -1;
1820   while ((x >>= 1) != 0)
1821     log++;
1822   return log;
1823 }
1824
1825 /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
1826    If X is 0, return -1.
1827
1828    This should be used via the floor_log2 macro.  */
1829
1830 int
1831 floor_log2_wide (x)
1832      register unsigned HOST_WIDE_INT x;
1833 {
1834   register int log = -1;
1835   while (x != 0)
1836     log++,
1837     x >>= 1;
1838   return log;
1839 }
1840
1841 int float_handled;
1842 jmp_buf float_handler;
1843
1844 /* Specify where to longjmp to when a floating arithmetic error happens.
1845    If HANDLER is 0, it means don't handle the errors any more.  */
1846
1847 void
1848 set_float_handler (handler)
1849      jmp_buf handler;
1850 {
1851   float_handled = (handler != 0);
1852   if (handler)
1853     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
1854 }
1855
1856 /* Specify, in HANDLER, where to longjmp to when a floating arithmetic
1857    error happens, pushing the previous specification into OLD_HANDLER.
1858    Return an indication of whether there was a previous handler in effect.  */
1859
1860 int
1861 push_float_handler (handler, old_handler)
1862      jmp_buf handler, old_handler;
1863 {
1864   int was_handled = float_handled;
1865
1866   float_handled = 1;
1867   if (was_handled)
1868     bcopy ((char *) float_handler, (char *) old_handler,
1869            sizeof (float_handler));
1870
1871   bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
1872   return was_handled;
1873 }
1874
1875 /* Restore the previous specification of whether and where to longjmp to
1876    when a floating arithmetic error happens.  */
1877
1878 void
1879 pop_float_handler (handled, handler)
1880      int handled;
1881      jmp_buf handler;
1882 {
1883   float_handled = handled;
1884   if (handled)
1885     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
1886 }
1887
1888 /* Signals actually come here.  */
1889
1890 static void
1891 float_signal (signo)
1892      /* If this is missing, some compilers complain.  */
1893      int signo;
1894 {
1895   if (float_handled == 0)
1896     abort ();
1897 #if defined (USG) || defined (hpux)
1898   signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
1899 #endif
1900   float_handled = 0;
1901   signal (SIGFPE, float_signal);
1902   longjmp (float_handler, 1);
1903 }
1904
1905 /* Handler for SIGPIPE.  */
1906
1907 static void
1908 pipe_closed (signo)
1909      /* If this is missing, some compilers complain.  */
1910      int signo;
1911 {
1912   fatal ("output pipe has been closed");
1913 }
1914
1915 /* Strip off a legitimate source ending from the input string NAME of
1916    length LEN. */
1917
1918 void
1919 strip_off_ending (name, len)
1920      char *name;
1921      int len;
1922 {
1923   if (len > 2 && ! strcmp (".c", name + len - 2))
1924     name[len - 2] = 0;
1925   else if (len > 2 && ! strcmp (".m", name + len - 2))
1926     name[len - 2] = 0;
1927   else if (len > 2 && ! strcmp (".i", name + len - 2))
1928     name[len - 2] = 0;
1929   else if (len > 3 && ! strcmp (".ii", name + len - 3))
1930     name[len - 3] = 0;
1931   else if (len > 3 && ! strcmp (".co", name + len - 3))
1932     name[len - 3] = 0;
1933   else if (len > 3 && ! strcmp (".cc", name + len - 3))
1934     name[len - 3] = 0;
1935   else if (len > 2 && ! strcmp (".C", name + len - 2))
1936     name[len - 2] = 0;
1937   else if (len > 4 && ! strcmp (".cxx", name + len - 4))
1938     name[len - 4] = 0;
1939   else if (len > 4 && ! strcmp (".cpp", name + len - 4))
1940     name[len - 4] = 0;
1941   else if (len > 2 && ! strcmp (".f", name + len - 2))
1942     name[len - 2] = 0;
1943   /* Ada will use extensions like .ada, .adb, and .ads, so just test
1944      for "ad".  */
1945   else if (len > 4 && ! strncmp (".ad", name + len - 4, 3))
1946     name[len - 4] = 0;
1947   else if (len > 4 && ! strcmp (".atr", name + len - 4))
1948     name[len - 4] = 0;
1949 }
1950
1951 /* Output a quoted string.  */
1952 void
1953 output_quoted_string (asm_file, string)
1954      FILE *asm_file;
1955      char *string;
1956 {
1957   char c;
1958
1959   putc ('\"', asm_file);
1960   while ((c = *string++) != 0)
1961     {
1962       if (c == '\"' || c == '\\')
1963         putc ('\\', asm_file);
1964       putc (c, asm_file);
1965     }
1966   putc ('\"', asm_file);
1967 }
1968
1969 /* Output a file name in the form wanted by System V.  */
1970
1971 void
1972 output_file_directive (asm_file, input_name)
1973      FILE *asm_file;
1974      char *input_name;
1975 {
1976   int len = strlen (input_name);
1977   char *na = input_name + len;
1978
1979   /* NA gets INPUT_NAME sans directory names.  */
1980   while (na > input_name)
1981     {
1982       if (na[-1] == '/')
1983         break;
1984       na--;
1985     }
1986
1987 #ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
1988   ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
1989 #else
1990 #ifdef ASM_OUTPUT_SOURCE_FILENAME
1991   ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
1992 #else
1993   fprintf (asm_file, "\t.file\t");
1994   output_quoted_string (asm_file, na);
1995   fputc ('\n', asm_file);
1996 #endif
1997 #endif
1998 }
1999 \f
2000 /* Routine to build language identifier for object file. */
2001 static void
2002 output_lang_identify (asm_out_file)
2003      FILE *asm_out_file;
2004 {
2005   int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
2006   char *s = (char *) alloca (len);
2007   sprintf (s, "__gnu_compiled_%s", lang_identify ());
2008   ASM_OUTPUT_LABEL (asm_out_file, s);
2009 }
2010
2011 /* Routine to open a dump file.  */
2012 static FILE *
2013 open_dump_file (base_name, suffix)
2014      char *base_name;
2015      char *suffix;
2016 {
2017   FILE *f;
2018   char *dumpname = (char *) alloca (strlen (base_name) + strlen (suffix) + 1);
2019
2020   strcpy (dumpname, base_name);
2021   strcat (dumpname, suffix);
2022   f = fopen (dumpname, "w");
2023   if (f == 0)
2024     pfatal_with_name (dumpname);
2025   return f;
2026 }
2027
2028 /* Compile an entire file of output from cpp, named NAME.
2029    Write a file of assembly output and various debugging dumps.  */
2030
2031 static void
2032 compile_file (name)
2033      char *name;
2034 {
2035   tree globals;
2036   int start_time;
2037
2038   int name_specified = name != 0;
2039
2040   if (dump_base_name == 0)
2041     dump_base_name = name ? name : "gccdump";
2042
2043   parse_time = 0;
2044   varconst_time = 0;
2045   integration_time = 0;
2046   jump_time = 0;
2047   cse_time = 0;
2048   loop_time = 0;
2049   cse2_time = 0;
2050   flow_time = 0;
2051   combine_time = 0;
2052   sched_time = 0;
2053   local_alloc_time = 0;
2054   global_alloc_time = 0;
2055   sched2_time = 0;
2056   dbr_sched_time = 0;
2057   shorten_branch_time = 0;
2058   stack_reg_time = 0;
2059   final_time = 0;
2060   symout_time = 0;
2061   dump_time = 0;
2062
2063   /* Open input file.  */
2064
2065   if (name == 0 || !strcmp (name, "-"))
2066     {
2067       finput = stdin;
2068       name = "stdin";
2069     }
2070   else
2071     finput = fopen (name, "r");
2072   if (finput == 0)
2073     pfatal_with_name (name);
2074
2075 #ifdef IO_BUFFER_SIZE
2076   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
2077 #endif
2078
2079   /* Initialize data in various passes.  */
2080
2081   init_obstacks ();
2082   init_tree_codes ();
2083   init_lex ();
2084   /* Some of these really don't need to be called when generating bytecode,
2085      but the options would have to be parsed first to know that. -bson */
2086   init_rtl ();
2087   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
2088                   || debug_info_level == DINFO_LEVEL_VERBOSE);
2089   init_regs ();
2090   init_decl_processing ();
2091   init_optabs ();
2092   init_stmt ();
2093   init_expmed ();
2094   init_expr_once ();
2095   init_loop ();
2096   init_reload ();
2097
2098   if (flag_caller_saves)
2099     init_caller_save ();
2100
2101   /* If auxiliary info generation is desired, open the output file.
2102      This goes in the same directory as the source file--unlike
2103      all the other output files.  */
2104   if (flag_gen_aux_info)
2105     {
2106       aux_info_file = fopen (aux_info_file_name, "w");
2107       if (aux_info_file == 0)
2108         pfatal_with_name (aux_info_file_name);
2109     }
2110
2111   /* If rtl dump desired, open the output file.  */
2112   if (rtl_dump)
2113     rtl_dump_file = open_dump_file (dump_base_name, ".rtl");
2114
2115   /* If jump_opt dump desired, open the output file.  */
2116   if (jump_opt_dump)
2117     jump_opt_dump_file = open_dump_file (dump_base_name, ".jump");
2118
2119   /* If cse dump desired, open the output file.  */
2120   if (cse_dump)
2121     cse_dump_file = open_dump_file (dump_base_name, ".cse");
2122
2123   /* If loop dump desired, open the output file.  */
2124   if (loop_dump)
2125     loop_dump_file = open_dump_file (dump_base_name, ".loop");
2126
2127   /* If cse2 dump desired, open the output file.  */
2128   if (cse2_dump)
2129     cse2_dump_file = open_dump_file (dump_base_name, ".cse2");
2130
2131   /* If flow dump desired, open the output file.  */
2132   if (flow_dump)
2133     flow_dump_file = open_dump_file (dump_base_name, ".flow");
2134
2135   /* If combine dump desired, open the output file.  */
2136   if (combine_dump)
2137     combine_dump_file = open_dump_file (dump_base_name, ".combine");
2138
2139   /* If scheduling dump desired, open the output file.  */
2140   if (sched_dump)
2141     sched_dump_file = open_dump_file (dump_base_name, ".sched");
2142
2143   /* If local_reg dump desired, open the output file.  */
2144   if (local_reg_dump)
2145     local_reg_dump_file = open_dump_file (dump_base_name, ".lreg");
2146
2147   /* If global_reg dump desired, open the output file.  */
2148   if (global_reg_dump)
2149     global_reg_dump_file = open_dump_file (dump_base_name, ".greg");
2150
2151   /* If 2nd scheduling dump desired, open the output file.  */
2152   if (sched2_dump)
2153     sched2_dump_file = open_dump_file (dump_base_name, ".sched2");
2154
2155   /* If jump2_opt dump desired, open the output file.  */
2156   if (jump2_opt_dump)
2157     jump2_opt_dump_file = open_dump_file (dump_base_name, ".jump2");
2158
2159   /* If dbr_sched dump desired, open the output file.  */
2160   if (dbr_sched_dump)
2161     dbr_sched_dump_file = open_dump_file (dump_base_name, ".dbr");
2162
2163 #ifdef STACK_REGS
2164
2165   /* If stack_reg dump desired, open the output file.  */
2166   if (stack_reg_dump)
2167     stack_reg_dump_file = open_dump_file (dump_base_name, ".stack");
2168
2169 #endif
2170
2171   /* Open assembler code output file.  */
2172
2173   if (! name_specified && asm_file_name == 0)
2174     asm_out_file = stdout;
2175   else
2176     {
2177       int len = strlen (dump_base_name);
2178       register char *dumpname = (char *) xmalloc (len + 6);
2179       strcpy (dumpname, dump_base_name);
2180       strip_off_ending (dumpname, len);
2181       strcat (dumpname, ".s");
2182       if (asm_file_name == 0)
2183         {
2184           asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
2185           strcpy (asm_file_name, dumpname);
2186         }
2187       if (!strcmp (asm_file_name, "-"))
2188         asm_out_file = stdout;
2189       else
2190         asm_out_file = fopen (asm_file_name, "w");
2191       if (asm_out_file == 0)
2192         pfatal_with_name (asm_file_name);
2193     }
2194
2195 #ifdef IO_BUFFER_SIZE
2196   setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
2197            _IOFBF, IO_BUFFER_SIZE);
2198 #endif
2199
2200   input_filename = name;
2201
2202   /* Perform language-specific initialization.
2203      This may set main_input_filename.  */
2204   lang_init ();
2205
2206   /* If the input doesn't start with a #line, use the input name
2207      as the official input file name.  */
2208   if (main_input_filename == 0)
2209     main_input_filename = name;
2210
2211   /* Put an entry on the input file stack for the main input file.  */
2212   input_file_stack
2213     = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2214   input_file_stack->next = 0;
2215   input_file_stack->name = input_filename;
2216
2217   if (!output_bytecode)
2218     {
2219       ASM_FILE_START (asm_out_file);
2220     }
2221
2222   /* Output something to inform GDB that this compilation was by GCC.  Also
2223      serves to tell GDB file consists of bytecodes. */
2224   if (output_bytecode)
2225     fprintf (asm_out_file, "bc_gcc2_compiled.:\n");
2226   else
2227     {
2228 #ifndef ASM_IDENTIFY_GCC
2229       fprintf (asm_out_file, "gcc2_compiled.:\n");
2230 #else
2231       ASM_IDENTIFY_GCC (asm_out_file);
2232 #endif
2233     }
2234
2235   /* Output something to identify which front-end produced this file. */
2236 #ifdef ASM_IDENTIFY_LANGUAGE
2237   ASM_IDENTIFY_LANGUAGE (asm_out_file);
2238 #endif
2239
2240   if (output_bytecode)
2241     {
2242       if (profile_flag || profile_block_flag)
2243         error ("profiling not supported in bytecode compilation");
2244     }
2245   else
2246     {
2247       /* ??? Note: There used to be a conditional here
2248          to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
2249          This was to guarantee separation between gcc_compiled. and
2250          the first function, for the sake of dbx on Suns.
2251          However, having the extra zero here confused the Emacs
2252          code for unexec, and might confuse other programs too.
2253          Therefore, I took out that change.
2254          In future versions we should find another way to solve
2255          that dbx problem.  -- rms, 23 May 93.  */
2256       
2257       /* Don't let the first function fall at the same address
2258          as gcc_compiled., if profiling.  */
2259       if (profile_flag || profile_block_flag)
2260         assemble_zeros (UNITS_PER_WORD);
2261     }
2262
2263   /* If dbx symbol table desired, initialize writing it
2264      and output the predefined types.  */
2265 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
2266   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2267     TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
2268                                        getdecls ()));
2269 #endif
2270 #ifdef SDB_DEBUGGING_INFO
2271   if (write_symbols == SDB_DEBUG)
2272     TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
2273                                        getdecls ()));
2274 #endif
2275 #ifdef DWARF_DEBUGGING_INFO
2276   if (write_symbols == DWARF_DEBUG)
2277     TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
2278 #endif
2279
2280   /* Initialize yet another pass.  */
2281
2282   if (!output_bytecode)
2283     init_final (main_input_filename);
2284
2285   start_time = get_run_time ();
2286
2287   /* Call the parser, which parses the entire file
2288      (calling rest_of_compilation for each function).  */
2289
2290   if (yyparse () != 0)
2291     {
2292       if (errorcount == 0)
2293         fprintf (stderr, "Errors detected in input file (your bison.simple is out of date)");
2294
2295       /* In case there were missing closebraces,
2296          get us back to the global binding level.  */
2297       while (! global_bindings_p ())
2298         poplevel (0, 0, 0);
2299     }
2300
2301   /* Compilation is now finished except for writing
2302      what's left of the symbol table output.  */
2303
2304   parse_time += get_run_time () - start_time;
2305
2306   parse_time -= integration_time;
2307   parse_time -= varconst_time;
2308
2309   globals = getdecls ();
2310
2311   /* Really define vars that have had only a tentative definition.
2312      Really output inline functions that must actually be callable
2313      and have not been output so far.  */
2314
2315   {
2316     int len = list_length (globals);
2317     tree *vec = (tree *) alloca (sizeof (tree) * len);
2318     int i;
2319     tree decl;
2320     int reconsider = 1;
2321
2322     /* Process the decls in reverse order--earliest first.
2323        Put them into VEC from back to front, then take out from front.  */
2324
2325     for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
2326       vec[len - i - 1] = decl;
2327
2328     for (i = 0; i < len; i++)
2329       {
2330         decl = vec[i];
2331
2332         /* We're not deferring this any longer.  */
2333         DECL_DEFER_OUTPUT (decl) = 0;
2334
2335         if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
2336             && incomplete_decl_finalize_hook != 0)
2337           (*incomplete_decl_finalize_hook) (decl);
2338       }
2339
2340     /* Now emit any global variables or functions that we have been putting
2341        off.  We need to loop in case one of the things emitted here
2342        references another one which comes earlier in the list.  */
2343     while (reconsider)
2344       {
2345         reconsider = 0;
2346         for (i = 0; i < len; i++)
2347           {
2348             decl = vec[i];
2349
2350             if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
2351               continue;
2352
2353             /* Don't write out static consts, unless we still need them.
2354
2355                We also keep static consts if not optimizing (for debugging).
2356                ??? They might be better written into the debug information.
2357                This is possible when using DWARF.
2358
2359                A language processor that wants static constants to be always
2360                written out (even if it is not used) is responsible for
2361                calling rest_of_decl_compilation itself.  E.g. the C front-end
2362                calls rest_of_decl_compilation from finish_decl.
2363                One motivation for this is that is conventional in some
2364                environments to write things like:
2365                    static const char rcsid[] = "... version string ...";
2366                intending to force the string to be in the executable.
2367
2368                A language processor that would prefer to have unneeded
2369                static constants "optimized away" would just defer writing
2370                them out until here.  E.g. C++ does this, because static
2371                constants are often defined in header files.
2372
2373                ??? A tempting alternative (for both C and C++) would be
2374                to force a constant to be written if and only if it is
2375                defined in a main file, as opposed to an include file. */
2376
2377             if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
2378                 && (! TREE_READONLY (decl)
2379                     || TREE_PUBLIC (decl)
2380                     || !optimize
2381                     || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
2382               {
2383                 reconsider = 1;
2384                 rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
2385               }
2386
2387             if (TREE_CODE (decl) == FUNCTION_DECL
2388                 && DECL_INITIAL (decl) != 0
2389                 && DECL_SAVED_INSNS (decl) != 0
2390                 && (flag_keep_inline_functions
2391                     || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
2392               {
2393                 reconsider = 1;
2394                 temporary_allocation ();
2395                 output_inline_function (decl);
2396                 permanent_allocation (1);
2397               }
2398           }
2399       }
2400
2401     for (i = 0; i < len; i++)
2402       {
2403         decl = vec[i];
2404
2405         if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
2406             && ! TREE_ASM_WRITTEN (decl))
2407           /* Cancel the RTL for this decl so that, if debugging info
2408              output for global variables is still to come,
2409              this one will be omitted.  */
2410           DECL_RTL (decl) = NULL;
2411
2412         /* Warn about any function
2413            declared static but not defined.
2414            We don't warn about variables,
2415            because many programs have static variables
2416            that exist only to get some text into the object file.  */
2417         if (TREE_CODE (decl) == FUNCTION_DECL
2418             && (warn_unused
2419                 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
2420             && DECL_INITIAL (decl) == 0
2421             && DECL_EXTERNAL (decl)
2422             && ! TREE_PUBLIC (decl))
2423           {
2424             pedwarn_with_decl (decl, 
2425                                "`%s' declared `static' but never defined");
2426             /* This symbol is effectively an "extern" declaration now.  */
2427             TREE_PUBLIC (decl) = 1;
2428             assemble_external (decl);
2429           }
2430
2431         /* Warn about static fns or vars defined but not used,
2432            but not about inline functions or static consts
2433            since defining those in header files is normal practice.  */
2434         if (warn_unused
2435             && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
2436                 || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
2437             && ! DECL_IN_SYSTEM_HEADER (decl)
2438             && ! DECL_EXTERNAL (decl)
2439             && ! TREE_PUBLIC (decl)
2440             && ! TREE_USED (decl)
2441             && ! DECL_REGISTER (decl)
2442             /* The TREE_USED bit for file-scope decls
2443                is kept in the identifier, to handle multiple
2444                external decls in different scopes.  */
2445             && ! TREE_USED (DECL_NAME (decl)))
2446           warning_with_decl (decl, "`%s' defined but not used");
2447
2448 #ifdef SDB_DEBUGGING_INFO
2449         /* The COFF linker can move initialized global vars to the end.
2450            And that can screw up the symbol ordering.
2451            By putting the symbols in that order to begin with,
2452            we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
2453         if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
2454             && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
2455             && ! DECL_EXTERNAL (decl)
2456             && DECL_RTL (decl) != 0)
2457           TIMEVAR (symout_time, sdbout_symbol (decl, 0));
2458
2459         /* Output COFF information for non-global
2460            file-scope initialized variables. */
2461         if (write_symbols == SDB_DEBUG
2462             && TREE_CODE (decl) == VAR_DECL
2463             && DECL_INITIAL (decl)
2464             && ! DECL_EXTERNAL (decl)
2465             && DECL_RTL (decl) != 0
2466             && GET_CODE (DECL_RTL (decl)) == MEM)
2467           TIMEVAR (symout_time, sdbout_toplevel_data (decl));
2468 #endif /* SDB_DEBUGGING_INFO */
2469 #ifdef DWARF_DEBUGGING_INFO
2470         /* Output DWARF information for file-scope tentative data object
2471            declarations, file-scope (extern) function declarations (which
2472            had no corresponding body) and file-scope tagged type declarations
2473            and definitions which have not yet been forced out.  */
2474
2475         if (write_symbols == DWARF_DEBUG
2476             && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
2477           TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
2478 #endif
2479       }
2480   }
2481
2482   /* Do dbx symbols */
2483 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
2484   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2485     TIMEVAR (symout_time,
2486              {
2487                dbxout_finish (asm_out_file, main_input_filename);
2488              });
2489 #endif
2490
2491 #ifdef DWARF_DEBUGGING_INFO
2492   if (write_symbols == DWARF_DEBUG)
2493     TIMEVAR (symout_time,
2494              {
2495                dwarfout_finish ();
2496              });
2497 #endif
2498
2499   /* Output some stuff at end of file if nec.  */
2500
2501   if (!output_bytecode)
2502     {
2503       end_final (main_input_filename);
2504
2505 #ifdef ASM_FILE_END
2506       ASM_FILE_END (asm_out_file);
2507 #endif
2508     }
2509
2510   /* Language-specific end of compilation actions.  */
2511
2512   lang_finish ();
2513
2514   if (output_bytecode)
2515     bc_write_file (asm_out_file);
2516
2517   /* Close the dump files.  */
2518
2519   if (flag_gen_aux_info)
2520     {
2521       fclose (aux_info_file);
2522       if (errorcount)
2523         unlink (aux_info_file_name);
2524     }
2525
2526   if (rtl_dump)
2527     fclose (rtl_dump_file);
2528
2529   if (jump_opt_dump)
2530     fclose (jump_opt_dump_file);
2531
2532   if (cse_dump)
2533     fclose (cse_dump_file);
2534
2535   if (loop_dump)
2536     fclose (loop_dump_file);
2537
2538   if (cse2_dump)
2539     fclose (cse2_dump_file);
2540
2541   if (flow_dump)
2542     fclose (flow_dump_file);
2543
2544   if (combine_dump)
2545     {
2546       dump_combine_total_stats (combine_dump_file);
2547       fclose (combine_dump_file);
2548     }
2549
2550   if (sched_dump)
2551     fclose (sched_dump_file);
2552
2553   if (local_reg_dump)
2554     fclose (local_reg_dump_file);
2555
2556   if (global_reg_dump)
2557     fclose (global_reg_dump_file);
2558
2559   if (sched2_dump)
2560     fclose (sched2_dump_file);
2561
2562   if (jump2_opt_dump)
2563     fclose (jump2_opt_dump_file);
2564
2565   if (dbr_sched_dump)
2566     fclose (dbr_sched_dump_file);
2567
2568 #ifdef STACK_REGS
2569   if (stack_reg_dump)
2570     fclose (stack_reg_dump_file);
2571 #endif
2572
2573   /* Close non-debugging input and output files.  Take special care to note
2574      whether fclose returns an error, since the pages might still be on the
2575      buffer chain while the file is open.  */
2576
2577   fclose (finput);
2578   if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
2579     fatal_io_error (asm_file_name);
2580
2581   /* Print the times.  */
2582
2583   if (! quiet_flag)
2584     {
2585       fprintf (stderr,"\n");
2586       print_time ("parse", parse_time);
2587
2588       if (!output_bytecode)
2589         {
2590           print_time ("integration", integration_time);
2591           print_time ("jump", jump_time);
2592           print_time ("cse", cse_time);
2593           print_time ("loop", loop_time);
2594           print_time ("cse2", cse2_time);
2595           print_time ("flow", flow_time);
2596           print_time ("combine", combine_time);
2597           print_time ("sched", sched_time);
2598           print_time ("local-alloc", local_alloc_time);
2599           print_time ("global-alloc", global_alloc_time);
2600           print_time ("sched2", sched2_time);
2601           print_time ("dbranch", dbr_sched_time);
2602           print_time ("shorten-branch", shorten_branch_time);
2603           print_time ("stack-reg", stack_reg_time);
2604           print_time ("final", final_time);
2605           print_time ("varconst", varconst_time);
2606           print_time ("symout", symout_time);
2607           print_time ("dump", dump_time);
2608         }
2609     }
2610 }
2611 \f
2612 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
2613    and TYPE_DECL nodes.
2614
2615    This does nothing for local (non-static) variables.
2616    Otherwise, it sets up the RTL and outputs any assembler code
2617    (label definition, storage allocation and initialization).
2618
2619    DECL is the declaration.  If ASMSPEC is nonzero, it specifies
2620    the assembler symbol name to be used.  TOP_LEVEL is nonzero
2621    if this declaration is not within a function.  */
2622
2623 void
2624 rest_of_decl_compilation (decl, asmspec, top_level, at_end)
2625      tree decl;
2626      char *asmspec;
2627      int top_level;
2628      int at_end;
2629 {
2630   /* Declarations of variables, and of functions defined elsewhere.  */
2631
2632 /* The most obvious approach, to put an #ifndef around where
2633    this macro is used, doesn't work since it's inside a macro call.  */
2634 #ifndef ASM_FINISH_DECLARE_OBJECT
2635 #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
2636 #endif
2637
2638   /* Forward declarations for nested functions are not "external",
2639      but we need to treat them as if they were.  */
2640   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
2641       || TREE_CODE (decl) == FUNCTION_DECL)
2642     TIMEVAR (varconst_time,
2643              {
2644                make_decl_rtl (decl, asmspec, top_level);
2645                /* Initialized extern variable exists to be replaced
2646                   with its value, or represents something that will be
2647                   output in another file.  */
2648                if (! (TREE_CODE (decl) == VAR_DECL
2649                       && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
2650                       && DECL_INITIAL (decl) != 0
2651                       && DECL_INITIAL (decl) != error_mark_node))
2652                  /* Don't output anything
2653                     when a tentative file-scope definition is seen.
2654                     But at end of compilation, do output code for them.  */
2655                  if (! (! at_end && top_level
2656                         && (DECL_INITIAL (decl) == 0
2657                             || DECL_INITIAL (decl) == error_mark_node)))
2658                    assemble_variable (decl, top_level, at_end, 0);
2659                if (decl == last_assemble_variable_decl)
2660                  {
2661                    ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
2662                                               top_level, at_end);
2663                  }
2664              });
2665   else if (DECL_REGISTER (decl) && asmspec != 0)
2666     {
2667       if (decode_reg_name (asmspec) >= 0)
2668         {
2669           DECL_RTL (decl) = 0;
2670           make_decl_rtl (decl, asmspec, top_level);
2671         }
2672       else
2673         error ("invalid register name `%s' for register variable", asmspec);
2674     }
2675 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
2676   else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2677            && TREE_CODE (decl) == TYPE_DECL)
2678     TIMEVAR (symout_time, dbxout_symbol (decl, 0));
2679 #endif
2680 #ifdef SDB_DEBUGGING_INFO
2681   else if (write_symbols == SDB_DEBUG && top_level
2682            && TREE_CODE (decl) == TYPE_DECL)
2683     TIMEVAR (symout_time, sdbout_symbol (decl, 0));
2684 #endif
2685 }
2686
2687 /* Called after finishing a record, union or enumeral type.  */
2688
2689 void
2690 rest_of_type_compilation (type, toplev)
2691      tree type;
2692      int toplev;
2693 {
2694 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
2695   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
2696     TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
2697 #endif
2698 #ifdef SDB_DEBUGGING_INFO
2699   if (write_symbols == SDB_DEBUG)
2700     TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
2701 #endif
2702 }
2703
2704 /* This is called from finish_function (within yyparse)
2705    after each top-level definition is parsed.
2706    It is supposed to compile that function or variable
2707    and output the assembler code for it.
2708    After we return, the tree storage is freed.  */
2709
2710 void
2711 rest_of_compilation (decl)
2712      tree decl;
2713 {
2714   register rtx insns;
2715   int start_time = get_run_time ();
2716   int tem;
2717   /* Nonzero if we have saved the original DECL_INITIAL of the function,
2718      to be restored after we finish compiling the function
2719      (for use when compiling inline calls to this function).  */
2720   tree saved_block_tree = 0;
2721   /* Likewise, for DECL_ARGUMENTS.  */
2722   tree saved_arguments = 0;
2723   int failure = 0;
2724
2725   if (output_bytecode)
2726     return;
2727
2728   /* If we are reconsidering an inline function
2729      at the end of compilation, skip the stuff for making it inline.  */
2730
2731   if (DECL_SAVED_INSNS (decl) == 0)
2732     {
2733       int specd = DECL_INLINE (decl);
2734       char *lose;
2735
2736       /* If requested, consider whether to make this function inline.  */
2737       if (specd || flag_inline_functions)
2738         TIMEVAR (integration_time,
2739                  {
2740                    lose = function_cannot_inline_p (decl);
2741                    /* If not optimzing, then make sure the DECL_INLINE
2742                       bit is off.  */
2743                    if (lose || ! optimize)
2744                      {
2745                        if (warn_inline && specd)
2746                          warning_with_decl (decl, lose);
2747                        DECL_INLINE (decl) = 0;
2748                        DECL_ABSTRACT_ORIGIN (decl) = 0;
2749                        /* Don't really compile an extern inline function.
2750                           If we can't make it inline, pretend
2751                           it was only declared.  */
2752                        if (DECL_EXTERNAL (decl))
2753                          {
2754                            DECL_INITIAL (decl) = 0;
2755                            goto exit_rest_of_compilation;
2756                          }
2757                      }
2758                    else
2759                      DECL_INLINE (decl) = 1;
2760                  });
2761
2762       insns = get_insns ();
2763
2764       /* Dump the rtl code if we are dumping rtl.  */
2765
2766       if (rtl_dump)
2767         TIMEVAR (dump_time,
2768                  {
2769                    fprintf (rtl_dump_file, "\n;; Function %s\n\n",
2770                             IDENTIFIER_POINTER (DECL_NAME (decl)));
2771                    if (DECL_SAVED_INSNS (decl))
2772                      fprintf (rtl_dump_file, ";; (integrable)\n\n");
2773                    print_rtl (rtl_dump_file, insns);
2774                    fflush (rtl_dump_file);
2775                  });
2776
2777       /* If function is inline, and we don't yet know whether to
2778          compile it by itself, defer decision till end of compilation.
2779          finish_compilation will call rest_of_compilation again
2780          for those functions that need to be output.  Also defer those
2781          functions that we are supposed to defer.  */
2782
2783       if (DECL_DEFER_OUTPUT (decl)
2784           || (DECL_INLINE (decl)
2785               && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
2786                    && ! flag_keep_inline_functions)
2787                   || DECL_EXTERNAL (decl))))
2788         {
2789 #ifdef DWARF_DEBUGGING_INFO
2790           /* Generate the DWARF info for the "abstract" instance
2791              of a function which we may later generate inlined and/or
2792              out-of-line instances of.  */
2793           if (write_symbols == DWARF_DEBUG)
2794             {
2795               set_decl_abstract_flags (decl, 1);
2796               TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
2797               set_decl_abstract_flags (decl, 0);
2798             }
2799 #endif
2800           TIMEVAR (integration_time, save_for_inline_nocopy (decl));
2801           goto exit_rest_of_compilation;
2802         }
2803
2804       /* If we have to compile the function now, save its rtl and subdecls
2805          so that its compilation will not affect what others get.  */
2806       if (DECL_INLINE (decl))
2807         {
2808 #ifdef DWARF_DEBUGGING_INFO
2809           /* Generate the DWARF info for the "abstract" instance of
2810              a function which we will generate an out-of-line instance
2811              of almost immediately (and which we may also later generate
2812              various inlined instances of).  */
2813           if (write_symbols == DWARF_DEBUG)
2814             {
2815               set_decl_abstract_flags (decl, 1);
2816               TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
2817               set_decl_abstract_flags (decl, 0);
2818             }
2819 #endif
2820           saved_block_tree = DECL_INITIAL (decl);
2821           saved_arguments = DECL_ARGUMENTS (decl);
2822           TIMEVAR (integration_time, save_for_inline_copying (decl));
2823         }
2824
2825       /* If specified extern inline but we aren't inlining it, we are
2826          done.  */
2827       if (specd && DECL_EXTERNAL (decl))
2828         goto exit_rest_of_compilation;
2829     }
2830
2831   TREE_ASM_WRITTEN (decl) = 1;
2832
2833   /* Now that integrate will no longer see our rtl, we need not distinguish
2834      between the return value of this function and the return value of called
2835      functions.  */
2836   rtx_equal_function_value_matters = 0;
2837
2838   /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
2839   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
2840     {
2841       goto exit_rest_of_compilation;
2842     }
2843
2844   /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
2845      Note that that may have been done above, in save_for_inline_copying.
2846      The call to resume_temporary_allocation near the end of this function
2847      goes back to the usual state of affairs.  */
2848
2849   rtl_in_current_obstack ();
2850
2851 #ifdef FINALIZE_PIC
2852   /* If we are doing position-independent code generation, now
2853      is the time to output special prologues and epilogues.
2854      We do not want to do this earlier, because it just clutters
2855      up inline functions with meaningless insns.  */
2856   if (flag_pic)
2857     FINALIZE_PIC;
2858 #endif
2859
2860   insns = get_insns ();
2861
2862   /* Copy any shared structure that should not be shared.  */
2863
2864   unshare_all_rtl (insns);
2865
2866   /* Instantiate all virtual registers.  */
2867
2868   instantiate_virtual_regs (current_function_decl, get_insns ());
2869
2870   /* See if we have allocated stack slots that are not directly addressable.
2871      If so, scan all the insns and create explicit address computation
2872      for all references to such slots.  */
2873 /*   fixup_stack_slots (); */
2874
2875   /* Do jump optimization the first time, if -opt.
2876      Also do it if -W, but in that case it doesn't change the rtl code,
2877      it only computes whether control can drop off the end of the function.  */
2878
2879   if (optimize > 0 || extra_warnings || warn_return_type
2880       /* If function is `noreturn', we should warn if it tries to return.  */
2881       || TREE_THIS_VOLATILE (decl))
2882     {
2883       TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
2884       TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
2885     }
2886
2887   /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
2888   if (rtl_dump_and_exit || flag_syntax_only)
2889     goto exit_rest_of_compilation;
2890
2891   /* Dump rtl code after jump, if we are doing that.  */
2892
2893   if (jump_opt_dump)
2894     TIMEVAR (dump_time,
2895              {
2896                fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
2897                         IDENTIFIER_POINTER (DECL_NAME (decl)));
2898                print_rtl (jump_opt_dump_file, insns);
2899                fflush (jump_opt_dump_file);
2900              });
2901
2902   /* Perform common subexpression elimination.
2903      Nonzero value from `cse_main' means that jumps were simplified
2904      and some code may now be unreachable, so do
2905      jump optimization again.  */
2906
2907   if (cse_dump)
2908     TIMEVAR (dump_time,
2909              {
2910                fprintf (cse_dump_file, "\n;; Function %s\n\n",
2911                         IDENTIFIER_POINTER (DECL_NAME (decl)));
2912              });
2913
2914   if (optimize > 0)
2915     {
2916       TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
2917
2918       if (flag_thread_jumps)
2919         /* Hacks by tiemann & kenner.  */
2920         TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
2921
2922       TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
2923                                          0, cse_dump_file));
2924       TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ()));
2925
2926       if (tem || optimize > 1)
2927         TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
2928     }
2929
2930   /* Dump rtl code after cse, if we are doing that.  */
2931
2932   if (cse_dump)
2933     TIMEVAR (dump_time,
2934              {
2935                print_rtl (cse_dump_file, insns);
2936                fflush (cse_dump_file);
2937              });
2938
2939   if (loop_dump)
2940     TIMEVAR (dump_time,
2941              {
2942                fprintf (loop_dump_file, "\n;; Function %s\n\n",
2943                         IDENTIFIER_POINTER (DECL_NAME (decl)));
2944              });
2945
2946   /* Move constant computations out of loops.  */
2947
2948   if (optimize > 0)
2949     {
2950       TIMEVAR (loop_time,
2951                {
2952                  loop_optimize (insns, loop_dump_file);
2953                });
2954     }
2955
2956   /* Dump rtl code after loop opt, if we are doing that.  */
2957
2958   if (loop_dump)
2959     TIMEVAR (dump_time,
2960              {
2961                print_rtl (loop_dump_file, insns);
2962                fflush (loop_dump_file);
2963              });
2964
2965   if (cse2_dump)
2966     TIMEVAR (dump_time,
2967              {
2968                fprintf (cse2_dump_file, "\n;; Function %s\n\n",
2969                         IDENTIFIER_POINTER (DECL_NAME (decl)));
2970              });
2971
2972   if (optimize > 0 && flag_rerun_cse_after_loop)
2973     {
2974       /* Running another jump optimization pass before the second
2975          cse pass sometimes simplifies the RTL enough to allow
2976          the second CSE pass to do a better job.  Jump_optimize can change
2977          max_reg_num so we must rerun reg_scan afterwards.
2978          ??? Rework to not call reg_scan so often.  */
2979       TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
2980       TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
2981
2982       TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
2983       TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
2984                                           1, cse2_dump_file));
2985       if (tem)
2986         TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
2987     }
2988
2989   if (optimize > 0 && flag_thread_jumps)
2990     /* This pass of jump threading straightens out code
2991        that was kinked by loop optimization.  */
2992     TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
2993
2994   /* Dump rtl code after cse, if we are doing that.  */
2995
2996   if (cse2_dump)
2997     TIMEVAR (dump_time,
2998              {
2999                print_rtl (cse2_dump_file, insns);
3000                fflush (cse2_dump_file);
3001              });
3002
3003   /* We are no longer anticipating cse in this function, at least.  */
3004
3005   cse_not_expected = 1;
3006
3007   /* Now we choose between stupid (pcc-like) register allocation
3008      (if we got the -noreg switch and not -opt)
3009      and smart register allocation.  */
3010
3011   if (optimize > 0)                     /* Stupid allocation probably won't work */
3012     obey_regdecls = 0;          /* if optimizations being done.  */
3013
3014   regclass_init ();
3015
3016   /* Print function header into flow dump now
3017      because doing the flow analysis makes some of the dump.  */
3018
3019   if (flow_dump)
3020     TIMEVAR (dump_time,
3021              {
3022                fprintf (flow_dump_file, "\n;; Function %s\n\n",
3023                         IDENTIFIER_POINTER (DECL_NAME (decl)));
3024              });
3025
3026   if (obey_regdecls)
3027     {
3028       TIMEVAR (flow_time,
3029                {
3030                  regclass (insns, max_reg_num ());
3031                  stupid_life_analysis (insns, max_reg_num (),
3032                                        flow_dump_file);
3033                });
3034     }
3035   else
3036     {
3037       /* Do control and data flow analysis,
3038          and write some of the results to dump file.  */
3039
3040       TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
3041                                          flow_dump_file));
3042       if (warn_uninitialized)
3043         {
3044           uninitialized_vars_warning (DECL_INITIAL (decl));
3045           setjmp_args_warning ();
3046         }
3047     }
3048
3049   /* Dump rtl after flow analysis.  */
3050
3051   if (flow_dump)
3052     TIMEVAR (dump_time,
3053              {
3054                print_rtl (flow_dump_file, insns);
3055                fflush (flow_dump_file);
3056              });
3057
3058   /* If -opt, try combining insns through substitution.  */
3059
3060   if (optimize > 0)
3061     TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
3062
3063   /* Dump rtl code after insn combination.  */
3064
3065   if (combine_dump)
3066     TIMEVAR (dump_time,
3067              {
3068                fprintf (combine_dump_file, "\n;; Function %s\n\n",
3069                         IDENTIFIER_POINTER (DECL_NAME (decl)));
3070                dump_combine_stats (combine_dump_file);
3071                print_rtl (combine_dump_file, insns);
3072                fflush (combine_dump_file);
3073              });
3074
3075   /* Print function header into sched dump now
3076      because doing the sched analysis makes some of the dump.  */
3077
3078   if (sched_dump)
3079     TIMEVAR (dump_time,
3080              {
3081                fprintf (sched_dump_file, "\n;; Function %s\n\n",
3082                         IDENTIFIER_POINTER (DECL_NAME (decl)));
3083              });
3084
3085   if (optimize > 0 && flag_schedule_insns)
3086     {
3087       /* Do control and data sched analysis,
3088          and write some of the results to dump file.  */
3089
3090       TIMEVAR (sched_time, schedule_insns (sched_dump_file));
3091     }
3092
3093   /* Dump rtl after instruction scheduling.  */
3094
3095   if (sched_dump)
3096     TIMEVAR (dump_time,
3097              {
3098                print_rtl (sched_dump_file, insns);
3099                fflush (sched_dump_file);
3100              });
3101
3102   /* Unless we did stupid register allocation,
3103      allocate pseudo-regs that are used only within 1 basic block.  */
3104
3105   if (!obey_regdecls)
3106     TIMEVAR (local_alloc_time,
3107              {
3108                regclass (insns, max_reg_num ());
3109                local_alloc ();
3110              });
3111
3112   /* Dump rtl code after allocating regs within basic blocks.  */
3113
3114   if (local_reg_dump)
3115     TIMEVAR (dump_time,
3116              {
3117                fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
3118                         IDENTIFIER_POINTER (DECL_NAME (decl)));
3119                dump_flow_info (local_reg_dump_file);
3120                dump_local_alloc (local_reg_dump_file);
3121                print_rtl (local_reg_dump_file, insns);
3122                fflush (local_reg_dump_file);
3123              });
3124
3125   if (global_reg_dump)
3126     TIMEVAR (dump_time,
3127              fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
3128                       IDENTIFIER_POINTER (DECL_NAME (decl))));
3129
3130   /* Unless we did stupid register allocation,
3131      allocate remaining pseudo-regs, then do the reload pass
3132      fixing up any insns that are invalid.  */
3133
3134   TIMEVAR (global_alloc_time,
3135            {
3136              if (!obey_regdecls)
3137                failure = global_alloc (global_reg_dump_file);
3138              else
3139                failure = reload (insns, 0, global_reg_dump_file);
3140            });
3141
3142   if (global_reg_dump)
3143     TIMEVAR (dump_time,
3144              {
3145                dump_global_regs (global_reg_dump_file);
3146                print_rtl (global_reg_dump_file, insns);
3147                fflush (global_reg_dump_file);
3148              });
3149
3150   if (failure)
3151     goto exit_rest_of_compilation;
3152
3153   reload_completed = 1;
3154
3155   /* On some machines, the prologue and epilogue code, or parts thereof,
3156      can be represented as RTL.  Doing so lets us schedule insns between
3157      it and the rest of the code and also allows delayed branch
3158      scheduling to operate in the epilogue.  */
3159
3160   thread_prologue_and_epilogue_insns (insns);
3161
3162   if (optimize > 0 && flag_schedule_insns_after_reload)
3163     {
3164       if (sched2_dump)
3165         TIMEVAR (dump_time,
3166                  {
3167                    fprintf (sched2_dump_file, "\n;; Function %s\n\n",
3168                             IDENTIFIER_POINTER (DECL_NAME (decl)));
3169                  });
3170
3171       /* Do control and data sched analysis again,
3172          and write some more of the results to dump file.  */
3173
3174       TIMEVAR (sched2_time, schedule_insns (sched2_dump_file));
3175
3176       /* Dump rtl after post-reorder instruction scheduling.  */
3177
3178       if (sched2_dump)
3179         TIMEVAR (dump_time,
3180                  {
3181                    print_rtl (sched2_dump_file, insns);
3182                    fflush (sched2_dump_file);
3183                  });
3184     }
3185
3186 #ifdef LEAF_REGISTERS
3187   leaf_function = 0;
3188   if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
3189     leaf_function = 1;
3190 #endif
3191
3192   /* One more attempt to remove jumps to .+1
3193      left by dead-store-elimination.
3194      Also do cross-jumping this time
3195      and delete no-op move insns.  */
3196
3197   if (optimize > 0)
3198     {
3199       TIMEVAR (jump_time, jump_optimize (insns, 1, 1, 0));
3200     }
3201
3202   /* Dump rtl code after jump, if we are doing that.  */
3203
3204   if (jump2_opt_dump)
3205     TIMEVAR (dump_time,
3206              {
3207                fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
3208                         IDENTIFIER_POINTER (DECL_NAME (decl)));
3209                print_rtl (jump2_opt_dump_file, insns);
3210                fflush (jump2_opt_dump_file);
3211              });
3212
3213   /* If a machine dependent reorganization is needed, call it.  */
3214 #ifdef MACHINE_DEPENDENT_REORG
3215    MACHINE_DEPENDENT_REORG (insns);
3216 #endif
3217
3218   /* If a scheduling pass for delayed branches is to be done,
3219      call the scheduling code. */
3220
3221 #ifdef DELAY_SLOTS
3222   if (optimize > 0 && flag_delayed_branch)
3223     {
3224       TIMEVAR (dbr_sched_time, dbr_schedule (insns, dbr_sched_dump_file));
3225       if (dbr_sched_dump)
3226         {
3227           TIMEVAR (dump_time,
3228                  {
3229                    fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n",
3230                             IDENTIFIER_POINTER (DECL_NAME (decl)));
3231                    print_rtl (dbr_sched_dump_file, insns);
3232                    fflush (dbr_sched_dump_file);
3233                  });
3234         }
3235     }
3236 #endif
3237
3238   if (optimize > 0)
3239     /* Shorten branches.  */
3240     TIMEVAR (shorten_branch_time,
3241              {
3242                shorten_branches (get_insns ());
3243              });
3244
3245 #ifdef STACK_REGS
3246   TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file));
3247   if (stack_reg_dump)
3248     {
3249       TIMEVAR (dump_time,
3250                {
3251                  fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
3252                           IDENTIFIER_POINTER (DECL_NAME (decl)));
3253                  print_rtl (stack_reg_dump_file, insns);
3254                  fflush (stack_reg_dump_file);
3255                });
3256     }
3257 #endif
3258
3259   /* Now turn the rtl into assembler code.  */
3260
3261   TIMEVAR (final_time,
3262            {
3263              rtx x;
3264              char *fnname;
3265
3266              /* Get the function's name, as described by its RTL.
3267                 This may be different from the DECL_NAME name used
3268                 in the source file.  */
3269
3270              x = DECL_RTL (decl);
3271              if (GET_CODE (x) != MEM)
3272                abort ();
3273              x = XEXP (x, 0);
3274              if (GET_CODE (x) != SYMBOL_REF)
3275                abort ();
3276              fnname = XSTR (x, 0);
3277
3278              assemble_start_function (decl, fnname);
3279              final_start_function (insns, asm_out_file, optimize);
3280              final (insns, asm_out_file, optimize, 0);
3281              final_end_function (insns, asm_out_file, optimize);
3282              assemble_end_function (decl, fnname);
3283              fflush (asm_out_file);
3284            });
3285
3286   /* Write DBX symbols if requested */
3287
3288   /* Note that for those inline functions where we don't initially
3289      know for certain that we will be generating an out-of-line copy,
3290      the first invocation of this routine (rest_of_compilation) will
3291      skip over this code by doing a `goto exit_rest_of_compilation;'.
3292      Later on, finish_compilation will call rest_of_compilation again
3293      for those inline functions that need to have out-of-line copies
3294      generated.  During that call, we *will* be routed past here.  */
3295
3296 #ifdef DBX_DEBUGGING_INFO
3297   if (write_symbols == DBX_DEBUG)
3298     TIMEVAR (symout_time, dbxout_function (decl));
3299 #endif
3300
3301 #ifdef DWARF_DEBUGGING_INFO
3302   if (write_symbols == DWARF_DEBUG)
3303     TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
3304 #endif
3305
3306  exit_rest_of_compilation:
3307
3308   /* In case the function was not output,
3309      don't leave any temporary anonymous types
3310      queued up for sdb output.  */
3311 #ifdef SDB_DEBUGGING_INFO
3312   if (write_symbols == SDB_DEBUG)
3313     sdbout_types (NULL_TREE);
3314 #endif
3315
3316   /* Put back the tree of subblocks and list of arguments
3317      from before we copied them.
3318      Code generation and the output of debugging info may have modified
3319      the copy, but the original is unchanged.  */
3320
3321   if (saved_block_tree != 0)
3322     DECL_INITIAL (decl) = saved_block_tree;
3323   if (saved_arguments != 0)
3324     DECL_ARGUMENTS (decl) = saved_arguments;
3325
3326   reload_completed = 0;
3327
3328   /* Clear out the real_constant_chain before some of the rtx's
3329      it runs through become garbage.  */
3330
3331   clear_const_double_mem ();
3332
3333   /* Cancel the effect of rtl_in_current_obstack.  */
3334
3335   resume_temporary_allocation ();
3336
3337   /* The parsing time is all the time spent in yyparse
3338      *except* what is spent in this function.  */
3339
3340   parse_time -= get_run_time () - start_time;
3341 }
3342 \f
3343 /* Entry point of cc1/c++.  Decode command args, then call compile_file.
3344    Exit code is 35 if can't open files, 34 if fatal error,
3345    33 if had nonfatal errors, else success.  */
3346
3347 int
3348 main (argc, argv, envp)
3349      int argc;
3350      char **argv;
3351      char **envp;
3352 {
3353   register int i;
3354   char *filename = 0;
3355   int flag_print_mem = 0;
3356   int version_flag = 0;
3357   char *p;
3358
3359   /* save in case md file wants to emit args as a comment.  */
3360   save_argc = argc;
3361   save_argv = argv;
3362
3363   p = argv[0] + strlen (argv[0]);
3364   while (p != argv[0] && p[-1] != '/') --p;
3365   progname = p;
3366
3367 #ifdef RLIMIT_STACK
3368   /* Get rid of any avoidable limit on stack size.  */
3369   {
3370     struct rlimit rlim;
3371
3372     /* Set the stack limit huge so that alloca does not fail. */
3373     getrlimit (RLIMIT_STACK, &rlim);
3374     rlim.rlim_cur = rlim.rlim_max;
3375     setrlimit (RLIMIT_STACK, &rlim);
3376   }
3377 #endif /* RLIMIT_STACK */
3378
3379   signal (SIGFPE, float_signal);
3380
3381 #ifdef SIGPIPE
3382   signal (SIGPIPE, pipe_closed);
3383 #endif
3384
3385   decl_printable_name = decl_name;
3386   lang_expand_expr = (struct rtx_def *(*)()) do_abort;
3387   interim_eh_hook = interim_eh;
3388
3389   /* Initialize whether `char' is signed.  */
3390   flag_signed_char = DEFAULT_SIGNED_CHAR;
3391 #ifdef DEFAULT_SHORT_ENUMS
3392   /* Initialize how much space enums occupy, by default.  */
3393   flag_short_enums = DEFAULT_SHORT_ENUMS;
3394 #endif
3395
3396   /* Scan to see what optimization level has been specified.  That will
3397      determine the default value of many flags.  */
3398   for (i = 1; i < argc; i++)
3399     {
3400       if (!strcmp (argv[i], "-O"))
3401         {
3402           optimize = 1;
3403         }
3404       else if (argv[i][0] == '-' && argv[i][1] == 'O')
3405         {
3406           /* Handle -O2, -O3, -O69, ...  */
3407           char *p = &argv[i][2];
3408           int c;
3409
3410           while (c = *p++)
3411             if (! (c >= '0' && c <= '9'))
3412               break;
3413           if (c == 0)
3414             optimize = atoi (&argv[i][2]);
3415         }
3416     }
3417
3418   obey_regdecls = (optimize == 0);
3419   if (optimize == 0)
3420     {
3421       flag_no_inline = 1;
3422       warn_inline = 0;
3423     }
3424
3425   if (optimize >= 1)
3426     {
3427       flag_defer_pop = 1;
3428       flag_thread_jumps = 1;
3429 #ifdef DELAY_SLOTS
3430       flag_delayed_branch = 1;
3431 #endif
3432 #ifdef CAN_DEBUG_WITHOUT_FP
3433       flag_omit_frame_pointer = 1;
3434 #endif
3435     }
3436
3437   if (optimize >= 2)
3438     {
3439       flag_cse_follow_jumps = 1;
3440       flag_cse_skip_blocks = 1;
3441       flag_expensive_optimizations = 1;
3442       flag_strength_reduce = 1;
3443       flag_rerun_cse_after_loop = 1;
3444       flag_caller_saves = 1;
3445 #ifdef INSN_SCHEDULING
3446       flag_schedule_insns = 1;
3447       flag_schedule_insns_after_reload = 1;
3448 #endif
3449     }
3450
3451   if (optimize >= 3)
3452     {
3453       flag_inline_functions = 1;
3454     }
3455
3456 #ifdef OPTIMIZATION_OPTIONS
3457   /* Allow default optimizations to be specified on a per-machine basis.  */
3458   OPTIMIZATION_OPTIONS (optimize);
3459 #endif
3460
3461   /* Initialize register usage now so switches may override.  */
3462   init_reg_sets ();
3463
3464   target_flags = 0;
3465   set_target_switch ("");
3466
3467   for (i = 1; i < argc; i++)
3468     {
3469       int j;
3470       /* If this is a language-specific option,
3471          decode it in a language-specific way.  */
3472       for (j = 0; lang_options[j] != 0; j++)
3473         if (!strncmp (argv[i], lang_options[j],
3474                       strlen (lang_options[j])))
3475           break;
3476       if (lang_options[j] != 0)
3477         /* If the option is valid for *some* language,
3478            treat it as valid even if this language doesn't understand it.  */
3479         lang_decode_option (argv[i]);
3480       else if (argv[i][0] == '-' && argv[i][1] != 0)
3481         {
3482           register char *str = argv[i] + 1;
3483           if (str[0] == 'Y')
3484             str++;
3485
3486           if (str[0] == 'm')
3487             set_target_switch (&str[1]);
3488           else if (!strcmp (str, "dumpbase"))
3489             {
3490               dump_base_name = argv[++i];
3491             }
3492           else if (str[0] == 'd')
3493             {
3494               register char *p = &str[1];
3495               while (*p)
3496                 switch (*p++)
3497                   {
3498                   case 'a':
3499                     combine_dump = 1;
3500                     dbr_sched_dump = 1;
3501                     flow_dump = 1;
3502                     global_reg_dump = 1;
3503                     jump_opt_dump = 1;
3504                     jump2_opt_dump = 1;
3505                     local_reg_dump = 1;
3506                     loop_dump = 1;
3507                     rtl_dump = 1;
3508                     cse_dump = 1, cse2_dump = 1;
3509                     sched_dump = 1;
3510                     sched2_dump = 1;
3511                     stack_reg_dump = 1;
3512                     break;
3513                   case 'k':
3514                     stack_reg_dump = 1;
3515                     break;
3516                   case 'c':
3517                     combine_dump = 1;
3518                     break;
3519                   case 'd':
3520                     dbr_sched_dump = 1;
3521                     break;
3522                   case 'f':
3523                     flow_dump = 1;
3524                     break;
3525                   case 'g':
3526                     global_reg_dump = 1;
3527                     break;
3528                   case 'j':
3529                     jump_opt_dump = 1;
3530                     break;
3531                   case 'J':
3532                     jump2_opt_dump = 1;
3533                     break;
3534                   case 'l':
3535                     local_reg_dump = 1;
3536                     break;
3537                   case 'L':
3538                     loop_dump = 1;
3539                     break;
3540                   case 'm':
3541                     flag_print_mem = 1;
3542                     break;
3543                   case 'p':
3544                     flag_print_asm_name = 1;
3545                     break;
3546                   case 'r':
3547                     rtl_dump = 1;
3548                     break;
3549                   case 's':
3550                     cse_dump = 1;
3551                     break;
3552                   case 't':
3553                     cse2_dump = 1;
3554                     break;
3555                   case 'S':
3556                     sched_dump = 1;
3557                     break;
3558                   case 'R':
3559                     sched2_dump = 1;
3560                     break;
3561                   case 'y':
3562                     set_yydebug (1);
3563                     break;
3564
3565                   case 'x':
3566                     rtl_dump_and_exit = 1;
3567                     break;
3568                   }
3569             }
3570           else if (str[0] == 'f')
3571             {
3572               register char *p = &str[1];
3573               int found = 0;
3574
3575               /* Some kind of -f option.
3576                  P's value is the option sans `-f'.
3577                  Search for it in the table of options.  */
3578
3579               for (j = 0;
3580                    !found && j < sizeof (f_options) / sizeof (f_options[0]);
3581                    j++)
3582                 {
3583                   if (!strcmp (p, f_options[j].string))
3584                     {
3585                       *f_options[j].variable = f_options[j].on_value;
3586                       /* A goto here would be cleaner,
3587                          but breaks the vax pcc.  */
3588                       found = 1;
3589                     }
3590                   if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
3591                       && ! strcmp (p+3, f_options[j].string))
3592                     {
3593                       *f_options[j].variable = ! f_options[j].on_value;
3594                       found = 1;
3595                     }
3596                 }
3597
3598               if (found)
3599                 ;
3600               else if (!strncmp (p, "fixed-", 6))
3601                 fix_register (&p[6], 1, 1);
3602               else if (!strncmp (p, "call-used-", 10))
3603                 fix_register (&p[10], 0, 1);
3604               else if (!strncmp (p, "call-saved-", 11))
3605                 fix_register (&p[11], 0, 0);
3606               else
3607                 error ("Invalid option `%s'", argv[i]);
3608             }
3609           else if (str[0] == 'O')
3610             {
3611               register char *p = str+1;
3612               while (*p && *p >= '0' && *p <= '9')
3613                 p++;
3614               if (*p == '\0')
3615                 ;
3616               else
3617                 error ("Invalid option `%s'", argv[i]);
3618             }
3619           else if (!strcmp (str, "pedantic"))
3620             pedantic = 1;
3621           else if (!strcmp (str, "pedantic-errors"))
3622             flag_pedantic_errors = pedantic = 1;
3623           else if (!strcmp (str, "quiet"))
3624             quiet_flag = 1;
3625           else if (!strcmp (str, "version"))
3626             version_flag = 1;
3627           else if (!strcmp (str, "w"))
3628             inhibit_warnings = 1;
3629           else if (!strcmp (str, "W"))
3630             {
3631               extra_warnings = 1;
3632               /* We save the value of warn_uninitialized, since if they put
3633                  -Wuninitialized on the command line, we need to generate a
3634                  warning about not using it without also specifying -O.  */
3635               if (warn_uninitialized != 1)
3636                 warn_uninitialized = 2;
3637             }
3638           else if (str[0] == 'W')
3639             {
3640               register char *p = &str[1];
3641               int found = 0;
3642
3643               /* Some kind of -W option.
3644                  P's value is the option sans `-W'.
3645                  Search for it in the table of options.  */
3646
3647               for (j = 0;
3648                    !found && j < sizeof (W_options) / sizeof (W_options[0]);
3649                    j++)
3650                 {
3651                   if (!strcmp (p, W_options[j].string))
3652                     {
3653                       *W_options[j].variable = W_options[j].on_value;
3654                       /* A goto here would be cleaner,
3655                          but breaks the vax pcc.  */
3656                       found = 1;
3657                     }
3658                   if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
3659                       && ! strcmp (p+3, W_options[j].string))
3660                     {
3661                       *W_options[j].variable = ! W_options[j].on_value;
3662                       found = 1;
3663                     }
3664                 }
3665
3666               if (found)
3667                 ;
3668               else if (!strncmp (p, "id-clash-", 9))
3669                 {
3670                   char *endp = p + 9;
3671
3672                   while (*endp)
3673                     {
3674                       if (*endp >= '0' && *endp <= '9')
3675                         endp++;
3676                       else
3677                         {
3678                           error ("Invalid option `%s'", argv[i]);
3679                           goto id_clash_lose;
3680                         }
3681                     }
3682                   warn_id_clash = 1;
3683                   id_clash_len = atoi (str + 10);
3684                 id_clash_lose: ;
3685                 }
3686               else if (!strncmp (p, "larger-than-", 12))
3687                 {
3688                   char *endp = p + 12;
3689
3690                   while (*endp)
3691                     {
3692                       if (*endp >= '0' && *endp <= '9')
3693                         endp++;
3694                       else
3695                         {
3696                           error ("Invalid option `%s'", argv[i]);
3697                           goto larger_than_lose;
3698                         }
3699                     }
3700                   warn_larger_than = 1;
3701                   larger_than_size = atoi (str + 13);
3702                 larger_than_lose: ;
3703                 }
3704               else
3705                 error ("Invalid option `%s'", argv[i]);
3706             }
3707           else if (!strcmp (str, "p"))
3708             {
3709               if (!output_bytecode)
3710                 profile_flag = 1;
3711               else
3712                 error ("profiling not supported in bytecode compilation");
3713             }
3714           else if (!strcmp (str, "a"))
3715             {
3716 #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
3717               warning ("`-a' option (basic block profile) not supported");
3718 #else
3719               profile_block_flag = 1;
3720 #endif
3721             }
3722           else if (str[0] == 'g')
3723             {
3724               char *p = str + 1;
3725               char *q;
3726               unsigned len;
3727               unsigned level;
3728
3729               while (*p && (*p < '0' || *p > '9'))
3730                 p++;
3731               len = p - str;
3732               q = p;
3733               while (*q && (*q >= '0' && *q <= '9'))
3734                 q++;
3735               if (*p)
3736                 level = atoi (p);
3737               else
3738                 level = 2;      /* default debugging info level */
3739               if (*q || level > 3)
3740                 {
3741                   warning ("invalid debug level specification in option: `-%s'",
3742                            str);
3743                   warning ("no debugging information will be generated");
3744                   level = 0;
3745                 }
3746
3747               /* If more than one debugging type is supported,
3748                  you must define PREFERRED_DEBUGGING_TYPE
3749                  to choose a format in a system-dependent way.  */
3750               /* This is one long line cause VAXC can't handle a \-newline.  */
3751 #if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
3752 #ifdef PREFERRED_DEBUGGING_TYPE
3753               if (!strncmp (str, "ggdb", len))
3754                 write_symbols = PREFERRED_DEBUGGING_TYPE;
3755 #else /* no PREFERRED_DEBUGGING_TYPE */
3756 You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
3757 #endif /* no PREFERRED_DEBUGGING_TYPE */
3758 #endif /* More than one debugger format enabled.  */
3759 #ifdef DBX_DEBUGGING_INFO
3760               if (write_symbols != NO_DEBUG)
3761                 ;
3762               else if (!strncmp (str, "ggdb", len))
3763                 write_symbols = DBX_DEBUG;
3764               else if (!strncmp (str, "gstabs", len))
3765                 write_symbols = DBX_DEBUG;
3766               else if (!strncmp (str, "gstabs+", len))
3767                 write_symbols = DBX_DEBUG;
3768
3769               /* Always enable extensions for -ggdb or -gstabs+, 
3770                  always disable for -gstabs.
3771                  For plain -g, use system-specific default.  */
3772               if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len)
3773                   && len >= 2)
3774                 use_gnu_debug_info_extensions = 1;
3775               else if (write_symbols == DBX_DEBUG && !strncmp (str, "gstabs+", len)
3776                        && len >= 7)
3777                 use_gnu_debug_info_extensions = 1;
3778               else if (write_symbols == DBX_DEBUG
3779                        && !strncmp (str, "gstabs", len) && len >= 2)
3780                 use_gnu_debug_info_extensions = 0;
3781               else
3782                 use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
3783 #endif /* DBX_DEBUGGING_INFO */
3784 #ifdef DWARF_DEBUGGING_INFO
3785               if (write_symbols != NO_DEBUG)
3786                 ;
3787               else if (!strncmp (str, "g", len))
3788                 write_symbols = DWARF_DEBUG;
3789               else if (!strncmp (str, "ggdb", len))
3790                 write_symbols = DWARF_DEBUG;
3791               else if (!strncmp (str, "gdwarf", len))
3792                 write_symbols = DWARF_DEBUG;
3793
3794               /* Always enable extensions for -ggdb or -gdwarf+, 
3795                  always disable for -gdwarf.
3796                  For plain -g, use system-specific default.  */
3797               if (write_symbols == DWARF_DEBUG && !strncmp (str, "ggdb", len)
3798                   && len >= 2)
3799                 use_gnu_debug_info_extensions = 1;
3800               else if (write_symbols == DWARF_DEBUG && !strcmp (str, "gdwarf+"))
3801                 use_gnu_debug_info_extensions = 1;
3802               else if (write_symbols == DWARF_DEBUG
3803                        && !strncmp (str, "gdwarf", len) && len >= 2)
3804                 use_gnu_debug_info_extensions = 0;
3805               else
3806                 use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
3807 #endif
3808 #ifdef SDB_DEBUGGING_INFO
3809               if (write_symbols != NO_DEBUG)
3810                 ;
3811               else if (!strncmp (str, "g", len))
3812                 write_symbols = SDB_DEBUG;
3813               else if (!strncmp (str, "gdb", len))
3814                 write_symbols = SDB_DEBUG;
3815               else if (!strncmp (str, "gcoff", len))
3816                 write_symbols = SDB_DEBUG;
3817 #endif /* SDB_DEBUGGING_INFO */
3818 #ifdef XCOFF_DEBUGGING_INFO
3819               if (write_symbols != NO_DEBUG)
3820                 ;
3821               else if (!strncmp (str, "g", len))
3822                 write_symbols = XCOFF_DEBUG;
3823               else if (!strncmp (str, "ggdb", len))
3824                 write_symbols = XCOFF_DEBUG;
3825               else if (!strncmp (str, "gxcoff", len))
3826                 write_symbols = XCOFF_DEBUG;
3827
3828               /* Always enable extensions for -ggdb or -gxcoff+,
3829                  always disable for -gxcoff.
3830                  For plain -g, use system-specific default.  */
3831               if (write_symbols == XCOFF_DEBUG && !strncmp (str, "ggdb", len)
3832                   && len >= 2)
3833                 use_gnu_debug_info_extensions = 1;
3834               else if (write_symbols == XCOFF_DEBUG && !strcmp (str, "gxcoff+"))
3835                 use_gnu_debug_info_extensions = 1;
3836               else if (write_symbols == XCOFF_DEBUG
3837                        && !strncmp (str, "gxcoff", len) && len >= 2)
3838                 use_gnu_debug_info_extensions = 0;
3839               else
3840                 use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
3841 #endif        
3842               if (write_symbols == NO_DEBUG)
3843                 warning ("`-%s' option not supported on this version of GCC", str);
3844               else if (level == 0)
3845                 write_symbols = NO_DEBUG;
3846               else
3847                 debug_info_level = (enum debug_info_level) level;
3848             }
3849           else if (!strcmp (str, "o"))
3850             {
3851               asm_file_name = argv[++i];
3852             }
3853           else if (str[0] == 'G')
3854             {
3855               g_switch_set = TRUE;
3856               g_switch_value = atoi ((str[1] != '\0') ? str+1 : argv[++i]);
3857             }
3858           else if (!strncmp (str, "aux-info", 8))
3859             {
3860               flag_gen_aux_info = 1;
3861               aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
3862             }
3863           else
3864             error ("Invalid option `%s'", argv[i]);
3865         }
3866       else if (argv[i][0] == '+')
3867         error ("Invalid option `%s'", argv[i]);
3868       else
3869         filename = argv[i];
3870     }
3871
3872   /* Initialize for bytecode output.  A good idea to do this as soon as
3873      possible after the "-f" options have been parsed. */
3874   if (output_bytecode)
3875     {
3876 #ifndef TARGET_SUPPORTS_BYTECODE
3877       /* Just die with a fatal error if not supported */
3878       fatal ("-fbytecode not supporter for this target");
3879 #else
3880       bc_initialize ();
3881 #endif
3882     }
3883
3884   if (optimize == 0)
3885     {
3886       /* Inlining does not work if not optimizing,
3887          so force it not to be done.  */
3888       flag_no_inline = 1;
3889       warn_inline = 0;
3890
3891       /* The c_decode_option and lang_decode_option functions set
3892          this to `2' if -Wall is used, so we can avoid giving out
3893          lots of errors for people who don't realize what -Wall does.  */
3894       if (warn_uninitialized == 1)
3895         warning ("-Wuninitialized is not supported without -O");
3896     }
3897
3898 #if defined(DWARF_DEBUGGING_INFO)
3899   if (write_symbols == DWARF_DEBUG
3900       && strcmp (language_string, "GNU C++") == 0)
3901     {
3902       warning ("-g option not supported for C++ on SVR4 systems");
3903       write_symbols = NO_DEBUG;
3904     }
3905 #endif /* defined(DWARF_DEBUGGING_INFO) */
3906
3907 #ifdef OVERRIDE_OPTIONS
3908   /* Some machines may reject certain combinations of options.  */
3909   OVERRIDE_OPTIONS;
3910 #endif
3911
3912   /* Unrolling all loops implies that standard loop unrolling must also
3913      be done.  */
3914   if (flag_unroll_all_loops)
3915     flag_unroll_loops = 1;
3916   /* Loop unrolling requires that strength_reduction be on also.  Silently
3917      turn on strength reduction here if it isn't already on.  Also, the loop
3918      unrolling code assumes that cse will be run after loop, so that must
3919      be turned on also.  */
3920   if (flag_unroll_loops)
3921     {
3922       flag_strength_reduce = 1;
3923       flag_rerun_cse_after_loop = 1;
3924     }
3925
3926   /* Warn about options that are not supported on this machine.  */
3927 #ifndef INSN_SCHEDULING
3928   if (flag_schedule_insns || flag_schedule_insns_after_reload)
3929     warning ("instruction scheduling not supported on this target machine");
3930 #endif
3931 #ifndef DELAY_SLOTS
3932   if (flag_delayed_branch)
3933     warning ("this target machine does not have delayed branches");
3934 #endif
3935
3936   /* If we are in verbose mode, write out the version and maybe all the
3937      option flags in use.  */
3938   if (version_flag)
3939     {
3940       fprintf (stderr, "%s version %s", language_string, version_string);
3941 #ifdef TARGET_VERSION
3942       TARGET_VERSION;
3943 #endif
3944 #ifdef __GNUC__
3945 #ifndef __VERSION__
3946 #define __VERSION__ "[unknown]"
3947 #endif
3948       fprintf (stderr, " compiled by GNU C version %s.\n", __VERSION__);
3949 #else
3950       fprintf (stderr, " compiled by CC.\n");
3951 #endif
3952       if (! quiet_flag)
3953         print_switch_values ();
3954     }
3955
3956   compile_file (filename);
3957
3958 #if !defined(OS2) && !defined(VMS) && !defined(WINNT)
3959   if (flag_print_mem)
3960     {
3961 #ifdef __alpha
3962       char *sbrk ();
3963 #endif
3964       char *lim = (char *) sbrk (0);
3965
3966       fprintf (stderr, "Data size %d.\n",
3967                lim - (char *) &environ);
3968       fflush (stderr);
3969
3970 #ifdef USG
3971       system ("ps -l 1>&2");
3972 #else /* not USG */
3973       system ("ps v");
3974 #endif /* not USG */
3975     }
3976 #endif /* not OS2 and not VMS and not WINNT */
3977
3978   if (errorcount)
3979     exit (FATAL_EXIT_CODE);
3980   if (sorrycount)
3981     exit (FATAL_EXIT_CODE);
3982   exit (SUCCESS_EXIT_CODE);
3983   return 34;
3984 }
3985 \f
3986 /* Decode -m switches.  */
3987
3988 /* Here is a table, controlled by the tm.h file, listing each -m switch
3989    and which bits in `target_switches' it should set or clear.
3990    If VALUE is positive, it is bits to set.
3991    If VALUE is negative, -VALUE is bits to clear.
3992    (The sign bit is not used so there is no confusion.)  */
3993
3994 struct {char *name; int value;} target_switches []
3995   = TARGET_SWITCHES;
3996
3997 /* This table is similar, but allows the switch to have a value.  */
3998
3999 #ifdef TARGET_OPTIONS
4000 struct {char *prefix; char ** variable;} target_options []
4001   = TARGET_OPTIONS;
4002 #endif
4003
4004 /* Decode the switch -mNAME.  */
4005
4006 void
4007 set_target_switch (name)
4008      char *name;
4009 {
4010   register int j;
4011   int valid = 0;
4012
4013   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
4014     if (!strcmp (target_switches[j].name, name))
4015       {
4016         if (target_switches[j].value < 0)
4017           target_flags &= ~-target_switches[j].value;
4018         else
4019           target_flags |= target_switches[j].value;
4020         valid = 1;
4021       }
4022
4023 #ifdef TARGET_OPTIONS
4024   if (!valid)
4025     for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
4026       {
4027         int len = strlen (target_options[j].prefix);
4028         if (!strncmp (target_options[j].prefix, name, len))
4029           {
4030             *target_options[j].variable = name + len;
4031             valid = 1;
4032           }
4033       }
4034 #endif
4035
4036   if (!valid)
4037     error ("Invalid option `%s'", name);
4038 }
4039 \f
4040 /* Variable used for communication between the following two routines.  */
4041
4042 static int line_position;
4043
4044 /* Print an option value and adjust the position in the line.  */
4045
4046 static void
4047 print_single_switch (type, name)
4048      char *type, *name;
4049 {
4050   fprintf (stderr, " %s%s", type, name);
4051
4052   line_position += strlen (type) + strlen (name) + 1;
4053
4054   if (line_position > 65)
4055     {
4056       fprintf (stderr, "\n\t");
4057       line_position = 8;
4058     }
4059 }
4060      
4061 /* Print default target switches for -version.  */
4062
4063 static void
4064 print_switch_values ()
4065 {
4066   register int j;
4067
4068   fprintf (stderr, "enabled:");
4069   line_position = 8;
4070
4071   for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
4072     if (*f_options[j].variable == f_options[j].on_value)
4073       print_single_switch ("-f", f_options[j].string);
4074
4075   for (j = 0; j < sizeof W_options / sizeof W_options[0]; j++)
4076     if (*W_options[j].variable == W_options[j].on_value)
4077       print_single_switch ("-W", W_options[j].string);
4078
4079   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
4080     if (target_switches[j].name[0] != '\0'
4081         && target_switches[j].value > 0
4082         && ((target_switches[j].value & target_flags)
4083             == target_switches[j].value))
4084       print_single_switch ("-m", target_switches[j].name);
4085
4086   fprintf (stderr, "\n");
4087 }