|
|
1.1 root 1: /* Top level of GNU C compiler
1.1.1.2 root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* This is the top level of cc1.
23: It parses command args, opens files, invokes the various passes
24: in the proper order, and counts the time used by each.
25: Error messages and low-level interface to malloc also handled here. */
26:
27: #include "config.h"
28: #include <stdio.h>
29: #include <signal.h>
1.1.1.2 root 30:
31: #ifdef USG
32: #include <sys/param.h>
33: #include <sys/times.h>
34: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */
35: #else
36: #ifndef VMS
1.1 root 37: #include <sys/time.h>
38: #include <sys/resource.h>
1.1.1.2 root 39: #endif
40: #endif
41:
1.1 root 42: #ifndef _TYPES_
43: #include <sys/types.h>
44: #endif
45: #include <sys/stat.h>
1.1.1.2 root 46:
1.1 root 47: #include "tree.h"
48: #include "c-tree.h"
49: #include "rtl.h"
1.1.1.2 root 50: #include "flags.h"
1.1 root 51:
52: extern int yydebug;
53:
54: extern FILE *finput;
55:
56: extern void init_lex ();
57: extern void init_decl_processing ();
58: extern void init_tree ();
59: extern void init_rtl ();
60: extern void init_optabs ();
1.1.1.2 root 61: extern void init_reg_sets ();
1.1 root 62: extern void dump_flow_info ();
63: extern void dump_local_alloc ();
64:
1.1.1.2 root 65: void rest_of_decl_compilation ();
66: void error ();
67: void error_with_file_and_line ();
68: void set_target_switch ();
69:
1.1 root 70: /* Bit flags that specify the machine subtype we are compiling for.
71: Bits are tested using macros TARGET_... defined in the tm-...h file
72: and set by `-m...' switches. */
73:
74: int target_flags;
75:
1.1.1.2 root 76: /* Name of current original source file (what was input to cpp).
77: This comes from each #-command in the actual input. */
1.1 root 78:
1.1.1.2 root 79: char *input_filename;
80:
81: /* Name of top-level original source file (what was input to cpp).
82: This comes from the first #-command in the actual input. */
83:
84: char *main_input_filename;
1.1 root 85:
86: /* Current line number in real source file. */
87:
88: extern int lineno;
89:
90: /* FUNCTION_DECL for function now being parsed or compiled. */
91:
92: extern tree current_function_decl;
93:
94: /* Name to use as base of names for dump output files. */
95:
96: char *dump_base_name;
97:
98: /* Flags saying which kinds of debugging dump have been requested. */
99:
100: int rtl_dump = 0;
101: int rtl_dump_and_exit = 0;
102: int jump_opt_dump = 0;
103: int cse_dump = 0;
104: int loop_dump = 0;
105: int flow_dump = 0;
106: int combine_dump = 0;
107: int local_reg_dump = 0;
108: int global_reg_dump = 0;
1.1.1.2 root 109: int jump2_opt_dump = 0;
1.1 root 110:
111: /* 1 => write gdb debugging output (using symout.c). -g
112: 2 => write dbx debugging output (using dbxout.c). -G */
113:
114: int write_symbols = 0;
115:
116: /* Nonzero means do optimizations. -opt. */
117:
118: int optimize = 0;
119:
1.1.1.2 root 120: /* Nonzero for -fforce-mem: load memory value into a register
1.1 root 121: before arithmetic on it. This makes better cse but slower compilation. */
122:
1.1.1.2 root 123: int flag_force_mem = 0;
1.1 root 124:
1.1.1.2 root 125: /* Nonzero for -fforce-addr: load memory address into a register before
1.1 root 126: reference to memory. This makes better cse but slower compilation. */
127:
1.1.1.2 root 128: int flag_force_addr = 0;
129:
130: /* Nonzero for -fdefer-pop: don't pop args after each function call;
131: instead save them up to pop many calls' args with one insns. */
132:
133: int flag_defer_pop = 1;
134:
135: /* Nonzero for -ffloat-store: don't allocate floats and doubles
136: in extended-precision registers. */
137:
138: int flag_float_store = 0;
139:
140: /* Nonzero for -fcombine-regs:
141: allow instruction combiner to combine an insn
142: that just copies one reg to another. */
143:
144: int flag_combine_regs = 0;
145:
146: /* Nonzero for -fwritable-strings:
147: store string constants in data segment and don't uniquize them. */
148:
149: int flag_writable_strings = 0;
150:
151: /* Nonzero means don't put addresses of constant functions in registers.
152: Used for compiling the Unix kernel, where strange substitutions are
153: done on the assembly output. */
154:
155: int flag_no_function_cse = 0;
156:
157: /* Nonzero for -fomit-frame-pointer:
158: don't make a frame pointer in simple functions that don't require one. */
159:
160: int flag_omit_frame_pointer = 0;
161:
162: /* Nonzero to inhibit use of define_optimization peephole opts. */
163:
164: int flag_no_peephole = 0;
165:
166: /* Nonzero means `char' should be signed. */
167:
168: int flag_signed_char;
169:
170: /* Nonzero means allow type mismatches in conditional expressions;
171: just make their values `void'. */
172:
173: int flag_cond_mismatch;
174:
175: /* Nonzero means don't recognize the keyword `asm'. */
176:
177: int flag_no_asm;
178:
179: /* Nonzero means warn about implicit declarations. */
180:
181: int warn_implicit;
182:
183: /* Nonzero means warn about function definitions that default the return type
184: or that use a null return and have a return-type other than void. */
185:
186: int warn_return_type;
187:
188: /* Nonzero means do some things the same way PCC does. */
189:
190: int flag_traditional;
191:
192: /* Nonzero means all references through pointers are volatile. */
193:
194: int flag_volatile;
1.1 root 195:
196: /* Nonzero means do stupid register allocation. -noreg.
1.1.1.2 root 197: This and `optimize' are controlled by different switches in cc1,
1.1 root 198: but normally cc controls them both with the -O switch. */
199:
200: int obey_regdecls = 0;
201:
202: /* Don't print functions as they are compiled and don't print
203: times taken by the various passes. -quiet. */
204:
205: int quiet_flag = 0;
206:
207: /* Don't print warning messages. -w. */
208:
209: int inhibit_warnings = 0;
210:
1.1.1.2 root 211: /* Do print extra warnings (such as for uninitialized variables). -W. */
212:
213: int extra_warnings = 0;
214:
1.1 root 215: /* Number of error messages and warning messages so far. */
216:
217: int errorcount = 0;
218: int warningcount = 0;
219:
1.1.1.2 root 220: /* Nonzero if generating code to do profiling. */
221:
222: int profile_flag = 0;
223:
1.1 root 224: /* Nonzero for -pedantic switch: warn about anything
225: that standard C forbids. */
226:
227: int pedantic = 0;
228:
1.1.1.2 root 229: /* Nonzero for -finline-functions: ok to inline functions that look like
230: good inline candidates. */
231:
232: int flag_inline_functions;
233:
234: /* Nonzero for -fkeep-inline-functions: even if we make a function
235: go inline everywhere, keep its defintion around for debugging
236: purposes. */
237:
238: int flag_keep_inline_functions;
239:
1.1 root 240: /* Name for output file of assembly code, specified with -o. */
241:
242: char *asm_file_name;
243:
244: /* Name for output file of GDB symbol segment, specified with -symout. */
245:
246: char *sym_file_name;
247:
248: /* Output files for assembler code (real compiler output)
249: and debugging dumps. */
250:
251: FILE *asm_out_file;
252: FILE *rtl_dump_file;
253: FILE *jump_opt_dump_file;
254: FILE *cse_dump_file;
255: FILE *loop_dump_file;
256: FILE *flow_dump_file;
257: FILE *combine_dump_file;
258: FILE *local_reg_dump_file;
259: FILE *global_reg_dump_file;
1.1.1.2 root 260: FILE *jump2_opt_dump_file;
1.1 root 261:
262: /* Time accumulators, to count the total time spent in various passes. */
263:
264: int parse_time;
265: int varconst_time;
1.1.1.2 root 266: int integration_time;
1.1 root 267: int jump_time;
268: int cse_time;
269: int loop_time;
270: int flow_time;
271: int combine_time;
272: int local_alloc_time;
273: int global_alloc_time;
274: int final_time;
275: int symout_time;
276: int dump_time;
277:
278: /* Return time used so far, in microseconds. */
279:
1.1.1.2 root 280: int
1.1 root 281: gettime ()
282: {
1.1.1.2 root 283: #ifdef USG
284: struct tms tms;
285: #else
286: #ifndef VMS
1.1 root 287: struct rusage rusage;
1.1.1.2 root 288: #else /* VMS */
289: struct
290: {
291: int proc_user_time;
292: int proc_system_time;
293: int child_user_time;
294: int child_system_time;
295: } vms_times;
296: #endif
297: #endif
298:
1.1 root 299: if (quiet_flag)
300: return 0;
1.1.1.2 root 301:
302: #ifdef USG
303: times (&tms);
304: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
305: #else
306: #ifndef VMS
1.1 root 307: getrusage (0, &rusage);
308: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
309: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
1.1.1.2 root 310: #else /* VMS */
311: times (&vms_times);
312: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
313: #endif
314: #endif
1.1 root 315: }
316:
317: #define TIMEVAR(VAR, BODY) \
1.1.1.3 ! root 318: do { int otime = gettime (); BODY; VAR += gettime () - otime; } while (0)
1.1 root 319:
1.1.1.2 root 320: void
1.1 root 321: print_time (str, total)
322: char *str;
323: int total;
324: {
1.1.1.2 root 325: fprintf (stderr,
326: "time in %s: %d.%06d\n",
327: str, total / 1000000, total % 1000000);
1.1 root 328: }
329:
330: /* Count an error or warning. Return 1 if the message should be printed. */
331:
332: int
333: count_error (warningp)
334: int warningp;
335: {
336: if (warningp && inhibit_warnings)
337: return 0;
338:
339: if (warningp)
340: warningcount++;
341: else
342: errorcount++;
343:
344: return 1;
345: }
346:
347: /* Print a fatal error message. NAME is the text.
348: Also include a system error message based on `errno'. */
349:
1.1.1.2 root 350: void
1.1 root 351: pfatal_with_name (name)
1.1.1.2 root 352: char *name;
1.1 root 353: {
354: fprintf (stderr, "cc1: ");
355: perror (name);
356: exit (35);
357: }
358:
359: void
1.1.1.2 root 360: fatal_io_error (name)
361: char *name;
362: {
363: fprintf (stderr, "cc1:%s: I/O error\n", name);
364: exit (35);
365: }
366:
367: void
1.1 root 368: fatal (s)
369: char *s;
370: {
1.1.1.2 root 371: error (s, 0);
1.1 root 372: exit (34);
373: }
374:
375: /* Called when the start of a function definition is parsed,
376: this function prints on stderr the name of the function. */
377:
378: void
379: announce_function (decl)
380: tree decl;
381: {
382: if (! quiet_flag)
383: {
384: fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl)));
385: fflush (stderr);
386: }
387: }
388:
1.1.1.2 root 389: /* Prints out, if necessary, the name of the current function
390: which caused an error. Called from all error and warning functions. */
391:
392: void
393: report_error_function()
394: {
395: static tree last_error_function = NULL;
396:
397: if (last_error_function != current_function_decl)
398: {
399: if (current_function_decl == NULL)
400: {
401: if (!quiet_flag)
402: fprintf (stderr, "\n");
403: fprintf (stderr, "At top level:\n");
404: }
405: else
406: {
407: if (!quiet_flag)
408: /* We already know this info. Don't print it twice.
409: But make sure we are at the beginning of a line. */
410: fprintf (stderr, "\n");
411: else
412: fprintf (stderr, "In function %s:\n",
413: IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
414: }
415: last_error_function = current_function_decl;
416: }
417: }
1.1 root 418:
419: /* Report an error at the current line number.
420: S and V are a string and an arg for `printf'. */
421:
422: void
1.1.1.2 root 423: error (s, v)
1.1 root 424: char *s;
425: int v; /* @@also used as pointer */
426: {
1.1.1.2 root 427: error_with_file_and_line (input_filename, lineno, s, v);
1.1 root 428: }
429:
1.1.1.2 root 430: /* Report an error at line LINE of file FILE.
1.1 root 431: S and V are a string and an arg for `printf'. */
432:
1.1.1.2 root 433: void
434: error_with_file_and_line (file, line, s, v)
435: char *file;
1.1 root 436: int line;
437: char *s;
438: int v;
439: {
440: count_error (0);
441:
1.1.1.2 root 442: report_error_function ();
443:
444: if (file)
445: fprintf (stderr, "%s:%d: ", file, line);
446: else
447: fprintf (stderr, "cc1: ");
1.1 root 448: fprintf (stderr, s, v);
449: fprintf (stderr, "\n");
450: }
451:
1.1.1.2 root 452: /* Report an error at the declaration DECL.
453: S is string which uses %s to substitute the declaration name. */
1.1 root 454:
455: void
1.1.1.2 root 456: error_with_decl (decl, s)
457: tree decl;
1.1 root 458: char *s;
459: {
1.1.1.2 root 460: count_error (0);
461:
462: report_error_function ();
463:
464: fprintf (stderr, "%s:%d: ",
465: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
466:
467: if (DECL_NAME (decl))
468: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)));
469: else
470: fprintf (stderr, s, "((anonymous))");
471: fprintf (stderr, "\n");
1.1 root 472: }
473:
474: /* Report a warning at line LINE.
475: S and V are a string and an arg for `printf'. */
476:
1.1.1.2 root 477: void
1.1 root 478: warning_with_line (line, s, v)
479: int line;
480: char *s;
481: int v;
482: {
483: if (count_error (1) == 0)
484: return;
485:
1.1.1.2 root 486: report_error_function ();
487:
488: if (input_filename)
489: fprintf (stderr, "%s:%d: ", input_filename, line);
490: else
491: fprintf (stderr, "cc1: ");
1.1 root 492:
493: fprintf (stderr, "warning: ");
494: fprintf (stderr, s, v);
495: fprintf (stderr, "\n");
496: }
1.1.1.2 root 497:
498: /* Report a warning at the current line number.
499: S and V are a string and an arg for `printf'. */
500:
501: void
502: warning (s, v)
503: char *s;
504: int v; /* @@also used as pointer */
505: {
506: warning_with_line (lineno, s, v);
507: }
508:
509: /* Report a warning at the declaration DECL.
510: S is string which uses %s to substitute the declaration name. */
511:
512: void
513: warning_with_decl (decl, s)
514: tree decl;
515: char *s;
516: {
517: if (count_error (1) == 0)
518: return;
519:
520: report_error_function ();
521:
522: fprintf (stderr, "%s:%d: ",
523: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
524:
525: fprintf (stderr, "warning: ");
526: if (DECL_NAME (decl))
527: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)));
528: else
529: fprintf (stderr, s, "((anonymous))");
530: fprintf (stderr, "\n");
531: }
1.1 root 532:
533: /* When `malloc.c' is compiled with `rcheck' defined,
534: it calls this function to report clobberage. */
535:
1.1.1.2 root 536: void
1.1 root 537: botch (s)
538: {
539: abort ();
540: }
541:
542: /* Same as `malloc' but report error if no memory available. */
543:
1.1.1.2 root 544: int
1.1 root 545: xmalloc (size)
546: unsigned size;
547: {
548: register int value = (int) malloc (size);
549: if (value == 0)
550: fatal ("Virtual memory exhausted.");
551: return value;
552: }
553:
554: /* Same as `realloc' but report error if no memory available. */
555:
556: int
557: xrealloc (ptr, size)
558: char *ptr;
559: int size;
560: {
561: int result = realloc (ptr, size);
562: if (!result)
1.1.1.2 root 563: fatal ("Virtual memory exhausted.");
1.1 root 564: return result;
565: }
566:
567: /* Return the logarithm of X, base 2, considering X unsigned,
568: if X is a power of 2. Otherwise, returns -1. */
569:
570: int
571: exact_log2 (x)
572: register unsigned int x;
573: {
574: register int log = 0;
575: for (log = 0; log < HOST_BITS_PER_INT; log++)
576: if (x == (1 << log))
577: return log;
578: return -1;
579: }
580:
581: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
582: If X is 0, return -1. */
583:
584: int
585: floor_log2 (x)
586: register unsigned int x;
587: {
588: register int log = 0;
589: for (log = 0; log < HOST_BITS_PER_INT; log++)
590: if ((x & ((-1) << log)) == 0)
591: return log - 1;
592: return HOST_BITS_PER_INT - 1;
593: }
594:
595: /* Compile an entire file of output from cpp, named NAME.
596: Write a file of assembly output and various debugging dumps. */
597:
598: static void
599: compile_file (name)
600: char *name;
601: {
602: tree globals;
603: int start_time;
604: int dump_base_name_length = strlen (dump_base_name);
605:
606: parse_time = 0;
607: varconst_time = 0;
1.1.1.2 root 608: integration_time = 0;
1.1 root 609: jump_time = 0;
610: cse_time = 0;
611: loop_time = 0;
612: flow_time = 0;
613: combine_time = 0;
614: local_alloc_time = 0;
615: global_alloc_time = 0;
616: final_time = 0;
617: symout_time = 0;
1.1.1.2 root 618: dump_time = 0;
1.1 root 619:
620: /* Open input file. */
621:
622: finput = fopen (name, "r");
623: if (finput == 0)
624: pfatal_with_name (name);
625:
626: /* Initialize data in various passes. */
627:
628: init_tree ();
629: init_lex ();
630: init_rtl ();
1.1.1.2 root 631: init_emit_once ();
1.1 root 632: init_decl_processing ();
633: init_optabs ();
634:
635: /* If rtl dump desired, open the output file. */
636: if (rtl_dump)
637: {
638: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
639: strcpy (dumpname, dump_base_name);
640: strcat (dumpname, ".rtl");
641: rtl_dump_file = fopen (dumpname, "w");
642: if (rtl_dump_file == 0)
643: pfatal_with_name (dumpname);
644: }
645:
646: /* If jump_opt dump desired, open the output file. */
647: if (jump_opt_dump)
648: {
649: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
650: strcpy (dumpname, dump_base_name);
651: strcat (dumpname, ".jump");
652: jump_opt_dump_file = fopen (dumpname, "w");
653: if (jump_opt_dump_file == 0)
654: pfatal_with_name (dumpname);
655: }
656:
657: /* If cse dump desired, open the output file. */
658: if (cse_dump)
659: {
660: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
661: strcpy (dumpname, dump_base_name);
662: strcat (dumpname, ".cse");
663: cse_dump_file = fopen (dumpname, "w");
664: if (cse_dump_file == 0)
665: pfatal_with_name (dumpname);
666: }
667:
668: /* If loop dump desired, open the output file. */
669: if (loop_dump)
670: {
671: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
672: strcpy (dumpname, dump_base_name);
673: strcat (dumpname, ".loop");
674: loop_dump_file = fopen (dumpname, "w");
675: if (loop_dump_file == 0)
676: pfatal_with_name (dumpname);
677: }
678:
679: /* If flow dump desired, open the output file. */
680: if (flow_dump)
681: {
682: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
683: strcpy (dumpname, dump_base_name);
684: strcat (dumpname, ".flow");
685: flow_dump_file = fopen (dumpname, "w");
686: if (flow_dump_file == 0)
687: pfatal_with_name (dumpname);
688: }
689:
690: /* If combine dump desired, open the output file. */
691: if (combine_dump)
692: {
693: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10);
694: strcpy (dumpname, dump_base_name);
695: strcat (dumpname, ".combine");
696: combine_dump_file = fopen (dumpname, "w");
697: if (combine_dump_file == 0)
698: pfatal_with_name (dumpname);
699: }
700:
701: /* If local_reg dump desired, open the output file. */
702: if (local_reg_dump)
703: {
704: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
705: strcpy (dumpname, dump_base_name);
706: strcat (dumpname, ".lreg");
707: local_reg_dump_file = fopen (dumpname, "w");
708: if (local_reg_dump_file == 0)
709: pfatal_with_name (dumpname);
710: }
711:
712: /* If global_reg dump desired, open the output file. */
713: if (global_reg_dump)
714: {
715: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
716: strcpy (dumpname, dump_base_name);
717: strcat (dumpname, ".greg");
718: global_reg_dump_file = fopen (dumpname, "w");
719: if (global_reg_dump_file == 0)
720: pfatal_with_name (dumpname);
721: }
722:
1.1.1.2 root 723: /* If jump2_opt dump desired, open the output file. */
724: if (jump2_opt_dump)
725: {
726: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
727: strcpy (dumpname, dump_base_name);
728: strcat (dumpname, ".jump2");
729: jump2_opt_dump_file = fopen (dumpname, "w");
730: if (jump2_opt_dump_file == 0)
731: pfatal_with_name (dumpname);
732: }
733:
1.1 root 734: /* Open assembler code output file. */
735:
736: {
737: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
1.1.1.2 root 738: int len = strlen (dump_base_name);
1.1 root 739: strcpy (dumpname, dump_base_name);
1.1.1.2 root 740: if (len > 2 && ! strcmp (".c", dumpname + len - 2))
741: dumpname[len - 2] = 0;
742: else if (len > 3 && ! strcmp (".co", dumpname + len - 3))
743: dumpname[len - 3] = 0;
1.1 root 744: strcat (dumpname, ".s");
1.1.1.2 root 745: if (asm_file_name == 0)
746: {
747: asm_file_name = (char *) malloc (strlen (dumpname) + 1);
748: strcpy (asm_file_name, dumpname);
749: }
750: asm_out_file = fopen (asm_file_name, "w");
1.1 root 751: if (asm_out_file == 0)
752: pfatal_with_name (asm_file_name ? asm_file_name : dumpname);
1.1.1.2 root 753: fprintf (asm_out_file, ASM_FILE_START);
1.1 root 754: }
755:
756: input_filename = name;
757:
758: /* the beginning of the file is a new line; check for # */
759: /* With luck, we discover the real source file's name from that
760: and put it in input_filename. */
761: check_newline ();
762:
763: /* If GDB symbol table desired, open the GDB symbol output file. */
764: if (write_symbols == 1)
765: {
766: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
1.1.1.2 root 767: int len = strlen (dump_base_name);
1.1 root 768: strcpy (dumpname, dump_base_name);
1.1.1.2 root 769: if (len > 2 && ! strcmp (".c", dumpname + len - 2))
770: dumpname[len - 2] = 0;
771: else if (len > 3 && ! strcmp (".co", dumpname + len - 3))
772: dumpname[len - 3] = 0;
1.1 root 773: strcat (dumpname, ".sym");
774: if (sym_file_name == 0)
775: sym_file_name = dumpname;
776: symout_init (sym_file_name, asm_out_file, input_filename);
777: }
778:
779: /* If dbx symbol table desired, initialize writing it
780: and output the predefined types. */
781: if (write_symbols == 2)
1.1.1.2 root 782: dbxout_init (asm_out_file, main_input_filename);
1.1 root 783:
784: /* Initialize yet another pass. */
785:
1.1.1.2 root 786: init_final (main_input_filename);
1.1 root 787:
788: start_time = gettime ();
789:
790: /* Call the parser, which parses the entire file
791: (calling rest_of_compilation for each function). */
792:
793: yyparse ();
794:
795: /* Compilation is now finished except for writing
796: what's left of the symbol table output. */
797:
798: parse_time += gettime () - start_time;
799:
1.1.1.2 root 800: parse_time -= varconst_time;
801:
1.1 root 802: globals = getdecls ();
803:
1.1.1.2 root 804: /* Really define vars that have had only a tentative definition.
805: Really output inline functions that must actually be callable
806: and have not been output so far. */
807:
808: {
809: tree decl;
810: for (decl = globals; decl; decl = TREE_CHAIN (decl))
811: {
812: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
813: && ! TREE_ASM_WRITTEN (decl))
814: rest_of_decl_compilation (decl, 0, 1, 1);
815: if (TREE_CODE (decl) == FUNCTION_DECL
816: && ! TREE_ASM_WRITTEN (decl)
817: && DECL_INITIAL (decl) != 0
818: && TREE_ADDRESSABLE (decl))
819: output_inline_function (decl);
820: }
821: }
822:
1.1 root 823: /* Do dbx symbols */
824: if (write_symbols == 2)
825: TIMEVAR (symout_time,
826: {
827: dbxout_tags (gettags ());
828: dbxout_types (get_permanent_types ());
829: });
830:
831: /* Do gdb symbols */
832: if (write_symbols == 1)
833: TIMEVAR (symout_time,
834: {
835: struct stat statbuf;
836: fstat (fileno (finput), &statbuf);
837: symout_types (get_permanent_types ());
838: symout_top_blocks (globals, gettags ());
839: symout_finish (name, statbuf.st_ctime);
840: });
841:
1.1.1.2 root 842: /* Close the dump files. */
1.1 root 843:
844: if (rtl_dump)
845: fclose (rtl_dump_file);
846:
847: if (jump_opt_dump)
848: fclose (jump_opt_dump_file);
849:
850: if (cse_dump)
851: fclose (cse_dump_file);
852:
853: if (loop_dump)
854: fclose (loop_dump_file);
855:
856: if (flow_dump)
857: fclose (flow_dump_file);
858:
859: if (combine_dump)
860: {
861: dump_combine_total_stats (combine_dump_file);
862: fclose (combine_dump_file);
863: }
864:
865: if (local_reg_dump)
866: fclose (local_reg_dump_file);
867:
868: if (global_reg_dump)
869: fclose (global_reg_dump_file);
870:
1.1.1.2 root 871: if (jump2_opt_dump)
872: fclose (jump2_opt_dump_file);
873:
874: /* Close non-debugging input and output files. */
875:
876: fclose (finput);
877: if (ferror (asm_out_file) != 0)
878: fatal_io_error (asm_file_name);
879: fclose (asm_out_file);
880:
1.1 root 881: /* Print the times. */
882:
883: if (! quiet_flag)
884: {
1.1.1.2 root 885: fprintf (stderr,"\n");
1.1 root 886: print_time ("parse", parse_time);
1.1.1.2 root 887: print_time ("integration", integration_time);
1.1 root 888: print_time ("jump", jump_time);
889: print_time ("cse", cse_time);
890: print_time ("loop", loop_time);
891: print_time ("flow", flow_time);
892: print_time ("combine", combine_time);
893: print_time ("local-alloc", local_alloc_time);
894: print_time ("global-alloc", global_alloc_time);
895: print_time ("final", final_time);
896: print_time ("varconst", varconst_time);
897: print_time ("symout", symout_time);
898: print_time ("dump", dump_time);
899: }
900: }
901:
1.1.1.2 root 902: /* This is called from finish_decl (within yyparse)
903: for each declaration of a function or variable.
904: This does nothing for automatic variables.
905: Otherwise, it sets up the RTL and outputs any assembler code
906: (label definition, storage allocation and initialization).
907:
908: DECL is the declaration. If ASMSPEC is nonzero, it specifies
909: the assembler symbol name to be used. TOP_LEVEL is nonzero
910: if this declaration is not within a function. */
911:
912: void
913: rest_of_decl_compilation (decl, asmspec, top_level, at_end)
914: tree decl;
915: tree asmspec;
916: int top_level;
917: int at_end;
918: {
919: /* Declarations of variables, and of functions defined elsewhere. */
920:
921: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
922: TIMEVAR (varconst_time,
923: {
924: assemble_variable (decl, asmspec, top_level, write_symbols, at_end);
925: });
1.1.1.3 ! root 926: else if (write_symbols == 2 && TREE_CODE (decl) == TYPE_DECL)
! 927: TIMEVAR (varconst_time, dbxout_symbol (decl, 0));
1.1.1.2 root 928:
929: if (top_level)
930: {
931: if (write_symbols == 1)
932: {
933: TIMEVAR (symout_time,
934: {
935: /* The initizations make types when they contain
936: string constants. The types are on the temporary
937: obstack, so output them now before they go away. */
938: symout_types (get_temporary_types ());
939: });
940: }
941: else
942: /* Clean out the temporary type list, since the types will go away. */
943: get_temporary_types ();
944: }
945: }
946:
1.1 root 947: /* This is called from finish_function (within yyparse)
1.1.1.2 root 948: after each top-level definition is parsed.
1.1 root 949: It is supposed to compile that function or variable
950: and output the assembler code for it.
951: After we return, the tree storage is freed. */
952:
953: void
1.1.1.2 root 954: rest_of_compilation (decl)
1.1 root 955: tree decl;
956: {
957: register rtx insns;
958: int start_time = gettime ();
959: int tem;
960:
1.1.1.2 root 961: /* If we are reconsidering an inline function
962: at the end of compilation, skip the stuff for making it inline. */
1.1 root 963:
1.1.1.2 root 964: if (DECL_SAVED_INSNS (decl) == 0)
1.1 root 965: {
966:
1.1.1.2 root 967: /* If requested, consider whether to make this function inline. */
968: if (flag_inline_functions || TREE_INLINE (decl))
969: {
970: TIMEVAR (integration_time,
971: {
972: int specd = TREE_INLINE (decl);
973: char *lose = function_cannot_inline_p (decl);
974: if (lose != 0 && specd)
975: warning_with_decl (decl, lose);
976: if (lose == 0)
977: save_for_inline (decl);
978: else
979: TREE_INLINE (decl) = 0;
980: });
981: }
1.1 root 982:
1.1.1.2 root 983: insns = get_insns ();
1.1 root 984:
985: /* Dump the rtl code if we are dumping rtl. */
986:
987: if (rtl_dump)
988: TIMEVAR (dump_time,
989: {
990: fprintf (rtl_dump_file, "\n;; Function %s\n\n",
991: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.2 root 992: if (DECL_SAVED_INSNS (decl))
993: fprintf (rtl_dump_file, ";; (integrable)\n\n");
1.1 root 994: print_rtl (rtl_dump_file, insns);
995: fflush (rtl_dump_file);
996: });
997:
1.1.1.2 root 998: /* If function is inline, and we don't yet know whether to
999: compile it by itself, defer decision till end of compilation.
1000: finish_compilation will call rest_of_compilation again
1001: for those functions that need to be output. */
1002:
1003: if (TREE_PUBLIC (decl) == 0
1004: && TREE_INLINE (decl)
1005: && ! flag_keep_inline_functions)
1.1 root 1006: goto exit_rest_of_compilation;
1.1.1.2 root 1007: }
1.1 root 1008:
1.1.1.2 root 1009: if (rtl_dump_and_exit)
1010: goto exit_rest_of_compilation;
1.1 root 1011:
1.1.1.2 root 1012: TREE_ASM_WRITTEN (decl) = 1;
1.1 root 1013:
1.1.1.2 root 1014: insns = get_insns ();
1.1 root 1015:
1.1.1.2 root 1016: /* Copy any shared structure that should not be shared. */
1.1 root 1017:
1.1.1.2 root 1018: unshare_all_rtl (insns);
1.1 root 1019:
1.1.1.2 root 1020: /* See if we have allocated stack slots that are not directly addressable.
1021: If so, scan all the insns and create explicit address computation
1022: for all references to such slots. */
1023: /* fixup_stack_slots (); */
1.1 root 1024:
1.1.1.2 root 1025: /* Do jump optimization the first time, if -opt.
1026: Also do it if -W, but in that case it doesn't change the rtl code,
1027: it only computes whether control can drop off the end of the function. */
1.1 root 1028:
1.1.1.2 root 1029: if (optimize || extra_warnings || warn_return_type)
1030: TIMEVAR (jump_time, jump_optimize (insns, 0, 0));
1.1 root 1031:
1.1.1.2 root 1032: /* Dump rtl code after jump, if we are doing that. */
1.1 root 1033:
1.1.1.2 root 1034: if (jump_opt_dump)
1035: TIMEVAR (dump_time,
1036: {
1037: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
1038: IDENTIFIER_POINTER (DECL_NAME (decl)));
1039: print_rtl (jump_opt_dump_file, insns);
1040: fflush (jump_opt_dump_file);
1041: });
1.1 root 1042:
1.1.1.2 root 1043: /* Perform common subexpression elimination.
1044: Nonzero value from `cse_main' means that jumps were simplified
1045: and some code may now be unreachable, so do
1046: jump optimization again. */
1.1 root 1047:
1.1.1.2 root 1048: if (optimize)
1049: {
1050: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 0));
1.1 root 1051:
1.1.1.2 root 1052: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ()));
1.1 root 1053:
1.1.1.2 root 1054: if (tem)
1055: TIMEVAR (jump_time, jump_optimize (insns, 0, 0));
1056: }
1.1 root 1057:
1.1.1.2 root 1058: /* Dump rtl code after cse, if we are doing that. */
1.1 root 1059:
1.1.1.2 root 1060: if (cse_dump)
1061: TIMEVAR (dump_time,
1062: {
1063: fprintf (cse_dump_file, "\n;; Function %s\n\n",
1064: IDENTIFIER_POINTER (DECL_NAME (decl)));
1065: print_rtl (cse_dump_file, insns);
1066: fflush (cse_dump_file);
1067: });
1.1 root 1068:
1.1.1.2 root 1069: if (loop_dump)
1070: TIMEVAR (dump_time,
1071: {
1072: fprintf (loop_dump_file, "\n;; Function %s\n\n",
1073: IDENTIFIER_POINTER (DECL_NAME (decl)));
1074: });
1.1 root 1075:
1.1.1.2 root 1076: /* Move constant computations out of loops. */
1.1 root 1077:
1.1.1.2 root 1078: if (optimize)
1079: {
1080: TIMEVAR (loop_time,
1081: {
1082: reg_scan (insns, max_reg_num (), 1);
1083: loop_optimize (insns, max_reg_num (),
1084: loop_dump ? loop_dump_file : 0);
1085: });
1086: }
1.1 root 1087:
1.1.1.2 root 1088: /* Dump rtl code after loop opt, if we are doing that. */
1.1 root 1089:
1.1.1.2 root 1090: if (loop_dump)
1091: TIMEVAR (dump_time,
1092: {
1093: print_rtl (loop_dump_file, insns);
1094: fflush (loop_dump_file);
1095: });
1.1 root 1096:
1.1.1.2 root 1097: /* Now we choose between stupid (pcc-like) register allocation
1098: (if we got the -noreg switch and not -opt)
1099: and smart register allocation. */
1.1 root 1100:
1.1.1.2 root 1101: if (optimize) /* Stupid allocation probably won't work */
1102: obey_regdecls = 0; /* if optimizations being done. */
1.1 root 1103:
1.1.1.2 root 1104: regclass_init ();
1.1 root 1105:
1.1.1.2 root 1106: /* Print function header into flow dump now
1107: because doing the flow analysis makes some of the dump. */
1.1 root 1108:
1.1.1.2 root 1109: if (flow_dump)
1110: TIMEVAR (dump_time,
1111: {
1112: fprintf (flow_dump_file, "\n;; Function %s\n\n",
1113: IDENTIFIER_POINTER (DECL_NAME (decl)));
1114: });
1115:
1116: if (obey_regdecls)
1117: {
1118: TIMEVAR (flow_time,
1119: {
1120: regclass (insns, max_reg_num ());
1121: stupid_life_analysis (insns, max_reg_num (),
1122: flow_dump_file);
1123: });
1124: }
1125: else
1126: {
1127: /* Do control and data flow analysis,
1128: and write some of the results to dump file. */
1.1 root 1129:
1.1.1.2 root 1130: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
1131: flow_dump_file));
1132: if (extra_warnings)
1133: uninitialized_vars_warning (DECL_INITIAL (decl));
1134: }
1.1 root 1135:
1.1.1.2 root 1136: /* Dump rtl after flow analysis. */
1.1 root 1137:
1.1.1.2 root 1138: if (flow_dump)
1139: TIMEVAR (dump_time,
1140: {
1141: print_rtl (flow_dump_file, insns);
1142: fflush (flow_dump_file);
1143: });
1.1 root 1144:
1.1.1.2 root 1145: /* If -opt, try combining insns through substitution. */
1.1 root 1146:
1.1.1.2 root 1147: if (optimize)
1148: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
1.1 root 1149:
1.1.1.2 root 1150: /* Dump rtl code after insn combination. */
1.1 root 1151:
1.1.1.2 root 1152: if (combine_dump)
1153: TIMEVAR (dump_time,
1154: {
1155: fprintf (combine_dump_file, "\n;; Function %s\n\n",
1156: IDENTIFIER_POINTER (DECL_NAME (decl)));
1157: dump_combine_stats (combine_dump_file);
1158: print_rtl (combine_dump_file, insns);
1159: fflush (combine_dump_file);
1160: });
1.1 root 1161:
1.1.1.2 root 1162: /* Unless we did stupid register allocation,
1163: allocate pseudo-regs that are used only within 1 basic block. */
1.1 root 1164:
1.1.1.2 root 1165: if (!obey_regdecls)
1166: TIMEVAR (local_alloc_time,
1167: {
1168: regclass (insns, max_reg_num ());
1169: local_alloc ();
1170: });
1.1 root 1171:
1.1.1.2 root 1172: /* Dump rtl code after allocating regs within basic blocks. */
1.1 root 1173:
1.1.1.2 root 1174: if (local_reg_dump)
1175: TIMEVAR (dump_time,
1176: {
1177: fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
1178: IDENTIFIER_POINTER (DECL_NAME (decl)));
1179: dump_flow_info (local_reg_dump_file);
1180: dump_local_alloc (local_reg_dump_file);
1181: print_rtl (local_reg_dump_file, insns);
1182: fflush (local_reg_dump_file);
1183: });
1.1 root 1184:
1.1.1.2 root 1185: if (global_reg_dump)
1186: TIMEVAR (dump_time,
1187: fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
1188: IDENTIFIER_POINTER (DECL_NAME (decl))));
1189:
1190: /* Unless we did stupid register allocation,
1191: allocate remaining pseudo-regs, then do the reload pass
1192: fixing up any insns that are invalid. */
1193:
1194: TIMEVAR (global_alloc_time,
1195: {
1196: if (!obey_regdecls)
1197: global_alloc (global_reg_dump ? global_reg_dump_file : 0);
1198: else
1199: reload (insns, 0,
1200: global_reg_dump ? global_reg_dump_file : 0);
1201: });
1202:
1203: if (global_reg_dump)
1204: TIMEVAR (dump_time,
1205: {
1206: dump_global_regs (global_reg_dump_file);
1207: print_rtl (global_reg_dump_file, insns);
1208: fflush (global_reg_dump_file);
1209: });
1.1 root 1210:
1.1.1.2 root 1211: /* One more attempt to remove jumps to .+1
1212: left by dead-store-elimination.
1213: Also do cross-jumping this time
1214: and delete no-op move insns. */
1.1 root 1215:
1.1.1.2 root 1216: if (optimize)
1217: {
1218: TIMEVAR (jump_time, jump_optimize (insns, 1, 1));
1219: }
1.1 root 1220:
1.1.1.2 root 1221: /* Dump rtl code after jump, if we are doing that. */
1222:
1223: if (jump2_opt_dump)
1224: TIMEVAR (dump_time,
1225: {
1226: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
1227: IDENTIFIER_POINTER (DECL_NAME (decl)));
1228: print_rtl (jump2_opt_dump_file, insns);
1229: fflush (jump2_opt_dump_file);
1230: });
1231:
1232: /* Now turn the rtl into assembler code. */
1233:
1234: TIMEVAR (final_time,
1235: {
1236: assemble_function (decl);
1237: final_start_function (insns, asm_out_file,
1238: write_symbols, optimize);
1239: final (insns, asm_out_file,
1240: write_symbols, optimize);
1241: final_end_function (insns, asm_out_file,
1242: write_symbols, optimize);
1243: fflush (asm_out_file);
1244: });
1.1 root 1245:
1.1.1.2 root 1246: /* Write GDB symbols if requested */
1.1 root 1247:
1.1.1.2 root 1248: if (write_symbols == 1)
1249: {
1250: TIMEVAR (symout_time,
1251: {
1252: symout_types (get_permanent_types ());
1253: symout_types (get_temporary_types ());
1254:
1255: DECL_BLOCK_SYMTAB_ADDRESS (decl)
1256: = symout_function (DECL_INITIAL (decl),
1257: DECL_ARGUMENTS (decl), 0);
1258: });
1.1 root 1259: }
1.1.1.2 root 1260: else
1261: get_temporary_types ();
1262:
1263: /* Write DBX symbols if requested */
1264:
1265: if (write_symbols == 2)
1266: TIMEVAR (symout_time, dbxout_function (decl));
1.1 root 1267:
1268: exit_rest_of_compilation:
1269:
1270: /* The parsing time is all the time spent in yyparse
1271: *except* what is spent in this function. */
1272:
1273: parse_time -= gettime () - start_time;
1274: }
1275:
1276: /* Entry point of cc1. Decode command args, then call compile_file.
1.1.1.2 root 1277: Exit code is 35 if can't open files, 34 if fatal error,
1278: 33 if had nonfatal errors, else success. */
1.1 root 1279:
1280: int
1281: main (argc, argv, envp)
1282: int argc;
1283: char **argv;
1284: char **envp;
1285: {
1286: register int i;
1.1.1.2 root 1287: char *filename = 0;
1288: int print_mem_flag = 0;
1289:
1290: #ifdef RLIMIT_STACK
1291: /* Get rid of any avoidable limit on stack size. */
1292: {
1293: struct rlimit rlim;
1294:
1295: /* Set the stack limit huge so that alloca does not fail. */
1296: getrlimit (RLIMIT_STACK, &rlim);
1297: rlim.rlim_cur = rlim.rlim_max;
1298: setrlimit (RLIMIT_STACK, &rlim);
1299: }
1300: #endif /* RLIMIT_STACK */
1301:
1302: /* Initialize whether `char' is signed. */
1303: flag_signed_char = DEFAULT_SIGNED_CHAR;
1304:
1305: /* Initialize reg-sets now so switches may override. */
1306: init_reg_sets ();
1.1 root 1307:
1308: target_flags = 0;
1309: set_target_switch ("");
1310:
1311: for (i = 1; i < argc; i++)
1312: if (argv[i][0] == '-')
1313: {
1314: register char *str = argv[i] + 1;
1315: if (str[0] == 'Y')
1316: str++;
1317:
1318: if (str[0] == 'm')
1319: set_target_switch (&str[1]);
1320: else if (!strcmp (str, "dumpbase"))
1321: {
1322: dump_base_name = argv[++i];
1323: }
1324: else if (str[0] == 'd')
1325: {
1326: register char *p = &str[1];
1327: while (*p)
1328: switch (*p++)
1329: {
1330: case 'c':
1331: combine_dump = 1;
1332: break;
1333: case 'f':
1334: flow_dump = 1;
1335: break;
1336: case 'g':
1337: global_reg_dump = 1;
1338: break;
1339: case 'j':
1340: jump_opt_dump = 1;
1341: break;
1.1.1.2 root 1342: case 'J':
1343: jump2_opt_dump = 1;
1344: break;
1.1 root 1345: case 'l':
1346: local_reg_dump = 1;
1347: break;
1348: case 'L':
1349: loop_dump = 1;
1350: break;
1.1.1.2 root 1351: case 'm':
1352: print_mem_flag = 1;
1353: break;
1.1 root 1354: case 'r':
1355: rtl_dump = 1;
1356: break;
1357: case 's':
1358: cse_dump = 1;
1359: break;
1360: case 'y':
1361: yydebug = 1;
1362: break;
1363: }
1364: }
1.1.1.2 root 1365: else if (str[0] == 'f')
1366: {
1367: register char *p = &str[1];
1368: if (!strcmp (p, "float-store"))
1369: flag_float_store = 1;
1370: else if (!strcmp (p, "traditional"))
1371: flag_traditional = 1;
1372: else if (!strcmp (p, "volatile"))
1373: flag_volatile = 1;
1374: else if (!strcmp (p, "defer-pop"))
1375: flag_defer_pop = 1;
1376: else if (!strcmp (p, "no-defer-pop"))
1377: flag_defer_pop = 0;
1378: else if (!strcmp (p, "omit-frame-pointer"))
1379: flag_omit_frame_pointer = 1;
1380: else if (!strcmp (p, "no-omit-frame-pointer"))
1381: flag_omit_frame_pointer = 0;
1382: else if (!strcmp (p, "no-peephole"))
1383: flag_no_peephole = 1;
1384: else if (!strcmp (p, "signed-char"))
1385: flag_signed_char = 1;
1386: else if (!strcmp (p, "unsigned-char"))
1387: flag_signed_char = 0;
1388: else if (!strcmp (p, "force-mem"))
1389: flag_force_mem = 1;
1390: else if (!strcmp (p, "force-addr"))
1391: flag_force_addr = 1;
1392: else if (!strcmp (p, "combine-regs"))
1393: flag_combine_regs = 1;
1394: else if (!strcmp (p, "writable-strings"))
1395: flag_writable_strings = 1;
1396: else if (!strcmp (p, "no-function-cse"))
1397: flag_no_function_cse = 1;
1398: else if (!strcmp (p, "cond-mismatch"))
1399: flag_cond_mismatch = 1;
1400: else if (!strcmp (p, "no-asm"))
1401: flag_no_asm = 1;
1402: else if (!strncmp (p, "fixed-", 6))
1403: fix_register (&p[6], 1, 1);
1404: else if (!strncmp (p, "call-used-", 10))
1405: fix_register (&p[10], 0, 1);
1406: else if (!strncmp (p, "call-saved-", 11))
1407: fix_register (&p[11], 0, 0);
1408: else if (!strcmp (p, "inline-functions"))
1409: flag_inline_functions = 1;
1410: else if (!strcmp (p, "keep-inline-functions"))
1411: flag_keep_inline_functions = 1;
1412: else
1413: error ("Invalid option, `%s'", argv[i]);
1414: }
1.1 root 1415: else if (!strcmp (str, "noreg"))
1416: obey_regdecls = 1;
1.1.1.2 root 1417: else if (!strcmp (str, "opt"))
1418: optimize = 1;
1419: else if (!strcmp (str, "pedantic"))
1420: pedantic = 1;
1421: else if (!strcmp (str, "traditional"))
1422: flag_traditional = 1;
1423: else if (!strcmp (str, "ansi"))
1424: flag_no_asm = 1;
1425: else if (!strcmp (str, "quiet"))
1426: quiet_flag = 1;
1427: else if (!strcmp (str, "version"))
1428: {
1429: extern char *version_string;
1430: printf ("GNU C version %s", version_string);
1431: #ifdef TARGET_VERSION
1432: TARGET_VERSION;
1433: #endif
1434: #ifdef __GNUC__
1435: #ifndef __VERSION__
1436: #define __VERSION__ "[unknown]"
1437: #endif
1438: printf (" compiled by GNU C version %s.\n", __VERSION__);
1439: #else
1440: printf (" compiled by CC.\n");
1441: #endif
1442: }
1.1 root 1443: else if (!strcmp (str, "w"))
1444: inhibit_warnings = 1;
1.1.1.2 root 1445: else if (!strcmp (str, "W"))
1446: extra_warnings = 1;
1447: else if (!strcmp (str, "Wimplicit"))
1448: warn_implicit = 1;
1449: else if (!strcmp (str, "Wreturn-type"))
1450: warn_return_type = 1;
1.1.1.3 ! root 1451: else if (!strcmp (str, "Wcomment"))
! 1452: ; /* cpp handles this one. */
! 1453: else if (!strcmp (str, "Wall"))
! 1454: {
! 1455: extra_warnings = 1;
! 1456: warn_implicit = 1;
! 1457: warn_return_type = 1;
! 1458: }
1.1.1.2 root 1459: else if (!strcmp (str, "p"))
1460: profile_flag = 1;
1.1 root 1461: else if (!strcmp (str, "g"))
1462: write_symbols = 1;
1463: else if (!strcmp (str, "G"))
1464: write_symbols = 2;
1465: else if (!strcmp (str, "symout"))
1466: {
1467: if (write_symbols == 0)
1468: write_symbols = 1;
1469: sym_file_name = argv[++i];
1470: }
1471: else if (!strcmp (str, "o"))
1472: {
1473: asm_file_name = argv[++i];
1474: }
1475: else
1.1.1.2 root 1476: error ("Invalid switch, %s.", argv[i]);
1.1 root 1477: }
1478: else
1479: filename = argv[i];
1480:
1481: if (filename == 0)
1482: fatal ("no input file specified");
1483:
1484: if (dump_base_name == 0)
1485: dump_base_name = filename;
1.1.1.2 root 1486:
1487: #ifdef OVERRIDE_OPTIONS
1488: /* Some machines may reject certain combinations of options. */
1489: OVERRIDE_OPTIONS;
1490: #endif
1491:
1.1 root 1492: compile_file (filename);
1493:
1.1.1.2 root 1494: #ifndef USG
1495: #ifndef VMS
1496: if (print_mem_flag)
1497: {
1498: extern char **environ;
1499: caddr_t lim = (caddr_t) sbrk (0);
1500:
1501: fprintf (stderr, "Data size %d.\n",
1502: (int) lim - (int) &environ);
1503: fflush (stderr);
1504:
1505: system ("ps v");
1506: }
1507: #endif /* not VMS */
1508: #endif /* not USG */
1509:
1.1 root 1510: if (errorcount)
1.1.1.2 root 1511: exit (FATAL_EXIT_CODE);
1512: exit (SUCCESS_EXIT_CODE);
1513: return 34;
1.1 root 1514: }
1515:
1516: /* Decode -m switches. */
1517:
1518: /* Here is a table, controlled by the tm-...h file, listing each -m switch
1519: and which bits in `target_switches' it should set or clear.
1520: If VALUE is positive, it is bits to set.
1521: If VALUE is negative, -VALUE is bits to clear.
1522: (The sign bit is not used so there is no confusion.) */
1523:
1524: struct {char *name; int value;} target_switches []
1525: = TARGET_SWITCHES;
1526:
1527: /* Decode the switch -mNAME. */
1528:
1.1.1.2 root 1529: void
1.1 root 1530: set_target_switch (name)
1531: char *name;
1532: {
1.1.1.2 root 1533: register int j;
1.1 root 1534: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
1535: if (!strcmp (target_switches[j].name, name))
1536: {
1537: if (target_switches[j].value < 0)
1538: target_flags &= ~-target_switches[j].value;
1539: else
1540: target_flags |= target_switches[j].value;
1541: break;
1542: }
1543: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.