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