OSDN Git Service

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