]>
Commit | Line | Data |
---|---|---|
bccafa26 | 1 | /* Top level of GCC compilers (cc1, cc1plus, etc.) |
711789cc | 2 | Copyright (C) 1987-2013 Free Software Foundation, Inc. |
3bcb26d1 | 3 | |
f12b58b3 | 4 | This file is part of GCC. |
3bcb26d1 | 5 | |
f12b58b3 | 6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free | |
8c4c00c1 | 8 | Software Foundation; either version 3, or (at your option) any later |
f12b58b3 | 9 | version. |
3bcb26d1 | 10 | |
f12b58b3 | 11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | for more details. | |
3bcb26d1 | 15 | |
16 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
3bcb26d1 | 19 | |
3bcb26d1 | 20 | /* This is the top level of cc1/c++. |
21 | It parses command args, opens files, invokes the various passes | |
22 | in the proper order, and counts the time used by each. | |
23 | Error messages and low-level interface to malloc also handled here. */ | |
24 | ||
25 | #include "config.h" | |
405711de | 26 | #include "system.h" |
805e22b2 | 27 | #include "coretypes.h" |
28 | #include "tm.h" | |
de269355 | 29 | #include "line-map.h" |
3bcb26d1 | 30 | #include "input.h" |
31 | #include "tree.h" | |
dae0b5cb | 32 | #include "realmpfr.h" /* For GMP/MPFR/MPC versions, in print_version. */ |
af225e7d | 33 | #include "version.h" |
3bcb26d1 | 34 | #include "rtl.h" |
7953c610 | 35 | #include "tm_p.h" |
3bcb26d1 | 36 | #include "flags.h" |
37 | #include "insn-attr.h" | |
997d68fe | 38 | #include "insn-config.h" |
ba38e12b | 39 | #include "insn-flags.h" |
3e9f1237 | 40 | #include "hard-reg-set.h" |
997d68fe | 41 | #include "recog.h" |
1ff68c01 | 42 | #include "output.h" |
037a5228 | 43 | #include "except.h" |
0a893c29 | 44 | #include "function.h" |
c3ab7bd5 | 45 | #include "toplev.h" |
74273693 | 46 | #include "expr.h" |
e81f50db | 47 | #include "basic-block.h" |
be2828ce | 48 | #include "intl.h" |
05513b45 | 49 | #include "ggc.h" |
5d0e87b7 | 50 | #include "regs.h" |
74d2af64 | 51 | #include "timevar.h" |
990339dd | 52 | #include "diagnostic.h" |
ce084dfc | 53 | #include "tree-diagnostic.h" |
54 | #include "tree-pretty-print.h" | |
9a33a2e8 | 55 | #include "params.h" |
75eb327c | 56 | #include "reload.h" |
47dd2e78 | 57 | #include "ira.h" |
8a34c73b | 58 | #include "dwarf2asm.h" |
b896d81b | 59 | #include "debug.h" |
2cb4ac60 | 60 | #include "target.h" |
218e3e4e | 61 | #include "common/common-target.h" |
b0278d39 | 62 | #include "langhooks.h" |
0f246197 | 63 | #include "cfgloop.h" /* for init_set_costs */ |
b197fbcf | 64 | #include "hosthooks.h" |
28992b23 | 65 | #include "cgraph.h" |
5457b645 | 66 | #include "opts.h" |
3c6a9715 | 67 | #include "opts-diagnostic.h" |
a0ed384d | 68 | #include "coverage.h" |
1c6a7b8c | 69 | #include "value-prof.h" |
15ac28e3 | 70 | #include "alloc-pool.h" |
e68ba323 | 71 | #include "tree-mudflap.h" |
b92cccf4 | 72 | #include "asan.h" |
b077695d | 73 | #include "tsan.h" |
75a70cf9 | 74 | #include "gimple.h" |
dd277d48 | 75 | #include "tree-ssa-alias.h" |
9227b6fc | 76 | #include "plugin.h" |
71eeb8d3 | 77 | #include "diagnostic-color.h" |
8d0badf1 | 78 | #include "context.h" |
bcfddb5b | 79 | #include "pass_manager.h" |
e3a24b9a | 80 | |
02da6382 | 81 | #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) |
744d3441 | 82 | #include "dbxout.h" |
83 | #endif | |
84 | ||
85 | #ifdef SDB_DEBUGGING_INFO | |
86 | #include "sdbout.h" | |
87 | #endif | |
397c7bc7 | 88 | |
89 | #ifdef XCOFF_DEBUGGING_INFO | |
90 | #include "xcoffout.h" /* Needed for external data | |
91 | declarations for e.g. AIX 4.x. */ | |
92 | #endif | |
03414cfb | 93 | |
4838a8b6 | 94 | static void general_init (const char *); |
7237deda | 95 | static void do_compile (void); |
96 | static void process_options (void); | |
97 | static void backend_init (void); | |
98 | static int lang_dependent_init (const char *); | |
99 | static void init_asm_output (const char *); | |
f666c964 | 100 | static void finalize (bool); |
7237deda | 101 | |
7237deda | 102 | static void crash_signal (int) ATTRIBUTE_NORETURN; |
7237deda | 103 | static void compile_file (void); |
7237deda | 104 | |
03bde601 | 105 | /* True if we don't need a backend (e.g. preprocessing only). */ |
106 | static bool no_backend; | |
107 | ||
e87e2aa9 | 108 | /* Length of line when printing switch values. */ |
109 | #define MAX_LINE 75 | |
110 | ||
615ef0bb | 111 | /* Decoded options, and number of such options. */ |
e3d1ab2b | 112 | struct cl_decoded_option *save_decoded_options; |
113 | unsigned int save_decoded_options_count; | |
03414cfb | 114 | |
ad469377 | 115 | /* Used to enable -fvar-tracking, -fweb and -frename-registers according |
2a95155a | 116 | to optimize in process_options (). */ |
472cd78a | 117 | #define AUTODETECT_VALUE 2 |
ad469377 | 118 | |
b896d81b | 119 | /* Debug hooks - dependent upon command line options. */ |
120 | ||
b0e56fb1 | 121 | const struct gcc_debug_hooks *debug_hooks; |
b896d81b | 122 | |
d0309f39 | 123 | /* The FUNCTION_DECL for the function currently being compiled, |
124 | or 0 if between functions. */ | |
125 | tree current_function_decl; | |
126 | ||
2d754264 | 127 | /* Set to the FUNC_BEGIN label of the current function, or NULL |
d0309f39 | 128 | if none. */ |
2d754264 | 129 | const char * current_function_func_begin_label; |
d0309f39 | 130 | |
81d47035 | 131 | /* A random sequence of characters, unless overridden by user. */ |
b6c1bd72 | 132 | static const char *flag_random_seed; |
b80f1d67 | 133 | |
134 | /* A local time stamp derived from the time of compilation. It will be | |
135 | zero if the system cannot provide a time. It will be -1u, if the | |
136 | user has specified a particular random seed. */ | |
137 | unsigned local_tick; | |
138 | ||
badc6cfa | 139 | /* Random number for this compilation */ |
140 | HOST_WIDE_INT random_seed; | |
141 | ||
3bcb26d1 | 142 | /* -f flags. */ |
143 | ||
8f8ac140 | 144 | /* When non-NULL, indicates that whenever space is allocated on the |
145 | stack, the resulting stack pointer must not pass this | |
146 | address---that is, for stacks that grow downward, the stack pointer | |
147 | must always be greater than or equal to this address; for stacks | |
148 | that grow upward, the stack pointer must be less than this address. | |
149 | At present, the rtx may be either a REG or a SYMBOL_REF, although | |
150 | the support provided depends on the backend. */ | |
151 | rtx stack_limit_rtx; | |
152 | ||
065efcb1 | 153 | /* True if the user has tagged the function with the 'section' |
154 | attribute. */ | |
155 | ||
156 | bool user_defined_section_attribute = false; | |
157 | ||
821d4118 | 158 | struct target_flag_state default_target_flag_state; |
159 | #if SWITCHABLE_TARGET | |
160 | struct target_flag_state *this_target_flag_state = &default_target_flag_state; | |
161 | #else | |
162 | #define this_target_flag_state (&default_target_flag_state) | |
163 | #endif | |
61e95947 | 164 | |
95c4b02a | 165 | /* The user symbol prefix after having resolved same. */ |
951f0f62 | 166 | const char *user_label_prefix; |
95c4b02a | 167 | |
3bcb26d1 | 168 | /* Output files for assembler code (real compiler output) |
169 | and debugging dumps. */ | |
170 | ||
171 | FILE *asm_out_file; | |
172 | FILE *aux_info_file; | |
990495a7 | 173 | FILE *stack_usage_file = NULL; |
3bcb26d1 | 174 | |
e7aa92b2 | 175 | /* The current working directory of a translation. It's generally the |
176 | directory from which compilation was initiated, but a preprocessed | |
177 | file may specify the original directory in which it was | |
178 | created. */ | |
179 | ||
180 | static const char *src_pwd; | |
181 | ||
182 | /* Initialize src_pwd with the given string, and return true. If it | |
183 | was already initialized, return false. As a special case, it may | |
184 | be called with a NULL argument to test whether src_pwd has NOT been | |
185 | initialized yet. */ | |
186 | ||
187 | bool | |
188 | set_src_pwd (const char *pwd) | |
189 | { | |
190 | if (src_pwd) | |
dc1dd09b | 191 | { |
192 | if (strcmp (src_pwd, pwd) == 0) | |
193 | return true; | |
194 | else | |
195 | return false; | |
196 | } | |
e7aa92b2 | 197 | |
198 | src_pwd = xstrdup (pwd); | |
199 | return true; | |
200 | } | |
201 | ||
202 | /* Return the directory from which the translation unit was initiated, | |
203 | in case set_src_pwd() was not called before to assign it a | |
204 | different value. */ | |
205 | ||
206 | const char * | |
207 | get_src_pwd (void) | |
208 | { | |
209 | if (! src_pwd) | |
8bc418a1 | 210 | { |
211 | src_pwd = getpwd (); | |
212 | if (!src_pwd) | |
213 | src_pwd = "."; | |
214 | } | |
e7aa92b2 | 215 | |
216 | return src_pwd; | |
217 | } | |
218 | ||
53d712d9 | 219 | /* Called when the start of a function definition is parsed, |
220 | this function prints on stderr the name of the function. */ | |
221 | void | |
222 | announce_function (tree decl) | |
223 | { | |
224 | if (!quiet_flag) | |
225 | { | |
226 | if (rtl_dump_and_exit) | |
abd3e6b5 | 227 | fprintf (stderr, "%s ", |
228 | identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (decl)))); | |
53d712d9 | 229 | else |
abd3e6b5 | 230 | fprintf (stderr, " %s", |
231 | identifier_to_locale (lang_hooks.decl_printable_name (decl, 2))); | |
53d712d9 | 232 | fflush (stderr); |
233 | pp_needs_newline (global_dc->printer) = true; | |
b8c23db3 | 234 | diagnostic_set_last_function (global_dc, (diagnostic_info *) NULL); |
53d712d9 | 235 | } |
236 | } | |
237 | ||
badc6cfa | 238 | /* Initialize local_tick with a random number or -1 if |
b6c1bd72 | 239 | flag_random_seed is set. */ |
b80f1d67 | 240 | |
241 | static void | |
b6c1bd72 | 242 | init_local_tick (void) |
b80f1d67 | 243 | { |
244 | if (!flag_random_seed) | |
245 | { | |
ad766573 | 246 | /* Try urandom first. Time of day is too likely to collide. |
247 | In case of any error we just use the local tick. */ | |
248 | ||
249 | int fd = open ("/dev/urandom", O_RDONLY); | |
250 | if (fd >= 0) | |
251 | { | |
252 | read (fd, &random_seed, sizeof (random_seed)); | |
253 | close (fd); | |
254 | } | |
255 | ||
256 | /* Now get the tick anyways */ | |
b80f1d67 | 257 | #ifdef HAVE_GETTIMEOFDAY |
258 | { | |
b6c1bd72 | 259 | struct timeval tv; |
7e614678 | 260 | |
b6c1bd72 | 261 | gettimeofday (&tv, NULL); |
b80f1d67 | 262 | local_tick = tv.tv_sec * 1000 + tv.tv_usec / 1000; |
263 | } | |
264 | #else | |
265 | { | |
c48e08ab | 266 | time_t now = time (NULL); |
b80f1d67 | 267 | |
268 | if (now != (time_t)-1) | |
269 | local_tick = (unsigned) now; | |
270 | } | |
271 | #endif | |
b80f1d67 | 272 | } |
b6c1bd72 | 273 | else |
b80f1d67 | 274 | local_tick = -1; |
275 | } | |
276 | ||
b6c1bd72 | 277 | /* Set up a default flag_random_seed and local_tick, unless the user |
278 | already specified one. Must be called after init_local_tick. */ | |
279 | ||
280 | static void | |
281 | init_random_seed (void) | |
282 | { | |
badc6cfa | 283 | if (flag_random_seed) |
284 | { | |
285 | char *endp; | |
b6c1bd72 | 286 | |
badc6cfa | 287 | /* When the driver passed in a hex number don't crc it again */ |
288 | random_seed = strtoul (flag_random_seed, &endp, 0); | |
289 | if (!(endp > flag_random_seed && *endp == 0)) | |
290 | random_seed = crc32_string (0, flag_random_seed); | |
291 | } | |
292 | else if (!random_seed) | |
293 | random_seed = local_tick ^ getpid (); /* Old racey fallback method */ | |
b6c1bd72 | 294 | } |
295 | ||
badc6cfa | 296 | /* Obtain the random_seed. Unless NOINIT, initialize it if |
b6c1bd72 | 297 | it's not provided in the command line. */ |
298 | ||
badc6cfa | 299 | HOST_WIDE_INT |
b6c1bd72 | 300 | get_random_seed (bool noinit) |
301 | { | |
302 | if (!flag_random_seed && !noinit) | |
303 | init_random_seed (); | |
badc6cfa | 304 | return random_seed; |
b6c1bd72 | 305 | } |
306 | ||
307 | /* Modify the random_seed string to VAL. Return its previous | |
308 | value. */ | |
309 | ||
310 | const char * | |
311 | set_random_seed (const char *val) | |
312 | { | |
313 | const char *old = flag_random_seed; | |
314 | flag_random_seed = val; | |
315 | return old; | |
316 | } | |
b80f1d67 | 317 | |
b9b90cce | 318 | /* Handler for fatal signals, such as SIGSEGV. These are transformed |
3a2aee0e | 319 | into ICE messages, which is much more user friendly. In case the |
320 | error printer crashes, reset the signal to prevent infinite recursion. */ | |
3bcb26d1 | 321 | |
322 | static void | |
7237deda | 323 | crash_signal (int signo) |
3bcb26d1 | 324 | { |
3a2aee0e | 325 | signal (signo, SIG_DFL); |
c706a9d9 | 326 | |
327 | /* If we crashed while processing an ASM statement, then be a little more | |
328 | graceful. It's most likely the user's fault. */ | |
329 | if (this_is_asm_operands) | |
330 | { | |
331 | output_operand_lossage ("unrecoverable error"); | |
332 | exit (FATAL_EXIT_CODE); | |
333 | } | |
334 | ||
59b7a777 | 335 | internal_error ("%s", strsignal (signo)); |
3bcb26d1 | 336 | } |
337 | ||
c131e678 | 338 | /* A subroutine of wrapup_global_declarations. We've come to the end of |
339 | the compilation unit. All deferred variables should be undeferred, | |
340 | and all incomplete decls should be finalized. */ | |
341 | ||
342 | void | |
343 | wrapup_global_declaration_1 (tree decl) | |
344 | { | |
345 | /* We're not deferring this any longer. Assignment is conditional to | |
346 | avoid needlessly dirtying PCH pages. */ | |
347 | if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS) | |
348 | && DECL_DEFER_OUTPUT (decl) != 0) | |
349 | DECL_DEFER_OUTPUT (decl) = 0; | |
350 | ||
351 | if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0) | |
352 | lang_hooks.finish_incomplete_decl (decl); | |
353 | } | |
354 | ||
355 | /* A subroutine of wrapup_global_declarations. Decide whether or not DECL | |
356 | needs to be output. Return true if it is output. */ | |
357 | ||
358 | bool | |
359 | wrapup_global_declaration_2 (tree decl) | |
360 | { | |
3d1c0354 | 361 | if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl) |
362 | || (TREE_CODE (decl) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (decl))) | |
c131e678 | 363 | return false; |
364 | ||
365 | /* Don't write out static consts, unless we still need them. | |
366 | ||
367 | We also keep static consts if not optimizing (for debugging), | |
368 | unless the user specified -fno-keep-static-consts. | |
369 | ??? They might be better written into the debug information. | |
370 | This is possible when using DWARF. | |
371 | ||
372 | A language processor that wants static constants to be always | |
373 | written out (even if it is not used) is responsible for | |
374 | calling rest_of_decl_compilation itself. E.g. the C front-end | |
375 | calls rest_of_decl_compilation from finish_decl. | |
376 | One motivation for this is that is conventional in some | |
377 | environments to write things like: | |
378 | static const char rcsid[] = "... version string ..."; | |
379 | intending to force the string to be in the executable. | |
380 | ||
381 | A language processor that would prefer to have unneeded | |
382 | static constants "optimized away" would just defer writing | |
383 | them out until here. E.g. C++ does this, because static | |
384 | constants are often defined in header files. | |
385 | ||
386 | ??? A tempting alternative (for both C and C++) would be | |
387 | to force a constant to be written if and only if it is | |
388 | defined in a main file, as opposed to an include file. */ | |
389 | ||
390 | if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) | |
391 | { | |
1d416bd7 | 392 | struct varpool_node *node; |
c131e678 | 393 | bool needed = true; |
c087e689 | 394 | node = varpool_get_node (decl); |
c131e678 | 395 | |
c087e689 | 396 | if (!node && flag_ltrans) |
c131e678 | 397 | needed = false; |
15ca8f90 | 398 | else if (node && node->symbol.definition) |
c087e689 | 399 | needed = false; |
15ca8f90 | 400 | else if (node && node->symbol.alias) |
c131e678 | 401 | needed = false; |
402 | else if (!cgraph_global_info_ready | |
403 | && (TREE_USED (decl) | |
404 | || TREE_USED (DECL_ASSEMBLER_NAME (decl)))) | |
405 | /* needed */; | |
15ca8f90 | 406 | else if (node && node->symbol.analyzed) |
c131e678 | 407 | /* needed */; |
408 | else if (DECL_COMDAT (decl)) | |
409 | needed = false; | |
410 | else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) | |
411 | && (optimize || !flag_keep_static_consts | |
412 | || DECL_ARTIFICIAL (decl))) | |
413 | needed = false; | |
414 | ||
415 | if (needed) | |
416 | { | |
417 | rest_of_decl_compilation (decl, 1, 1); | |
418 | return true; | |
419 | } | |
420 | } | |
421 | ||
422 | return false; | |
423 | } | |
424 | ||
a84da62d | 425 | /* Do any final processing required for the declarations in VEC, of |
426 | which there are LEN. We write out inline functions and variables | |
427 | that have been deferred until this point, but which are required. | |
f712a0dc | 428 | Returns nonzero if anything was put out. */ |
89a75961 | 429 | |
c131e678 | 430 | bool |
7237deda | 431 | wrapup_global_declarations (tree *vec, int len) |
a84da62d | 432 | { |
c131e678 | 433 | bool reconsider, output_something = false; |
a84da62d | 434 | int i; |
a84da62d | 435 | |
436 | for (i = 0; i < len; i++) | |
c131e678 | 437 | wrapup_global_declaration_1 (vec[i]); |
a84da62d | 438 | |
439 | /* Now emit any global variables or functions that we have been | |
440 | putting off. We need to loop in case one of the things emitted | |
441 | here references another one which comes earlier in the list. */ | |
442 | do | |
443 | { | |
c131e678 | 444 | reconsider = false; |
a84da62d | 445 | for (i = 0; i < len; i++) |
c131e678 | 446 | reconsider |= wrapup_global_declaration_2 (vec[i]); |
a84da62d | 447 | if (reconsider) |
c131e678 | 448 | output_something = true; |
a84da62d | 449 | } |
450 | while (reconsider); | |
451 | ||
452 | return output_something; | |
453 | } | |
454 | ||
c131e678 | 455 | /* A subroutine of check_global_declarations. Issue appropriate warnings |
456 | for the global declaration DECL. */ | |
457 | ||
458 | void | |
459 | check_global_declaration_1 (tree decl) | |
460 | { | |
461 | /* Warn about any function declared static but not defined. We don't | |
462 | warn about variables, because many programs have static variables | |
463 | that exist only to get some text into the object file. */ | |
464 | if (TREE_CODE (decl) == FUNCTION_DECL | |
465 | && DECL_INITIAL (decl) == 0 | |
466 | && DECL_EXTERNAL (decl) | |
467 | && ! DECL_ARTIFICIAL (decl) | |
468 | && ! TREE_NO_WARNING (decl) | |
469 | && ! TREE_PUBLIC (decl) | |
470 | && (warn_unused_function | |
471 | || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) | |
472 | { | |
473 | if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | |
21ca8540 | 474 | pedwarn (input_location, 0, "%q+F used but never defined", decl); |
c131e678 | 475 | else |
2006d7dc | 476 | warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl); |
c131e678 | 477 | /* This symbol is effectively an "extern" declaration now. */ |
478 | TREE_PUBLIC (decl) = 1; | |
c131e678 | 479 | } |
480 | ||
481 | /* Warn about static fns or vars defined but not used. */ | |
482 | if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL) | |
483 | /* We don't warn about "static const" variables because the | |
484 | "rcs_id" idiom uses that construction. */ | |
485 | || (warn_unused_variable | |
486 | && TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) | |
487 | && ! DECL_IN_SYSTEM_HEADER (decl) | |
488 | && ! TREE_USED (decl) | |
489 | /* The TREE_USED bit for file-scope decls is kept in the identifier, | |
490 | to handle multiple external decls in different scopes. */ | |
1563f282 | 491 | && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl))) |
c131e678 | 492 | && ! DECL_EXTERNAL (decl) |
493 | && ! TREE_PUBLIC (decl) | |
494 | /* A volatile variable might be used in some non-obvious way. */ | |
495 | && ! TREE_THIS_VOLATILE (decl) | |
496 | /* Global register variables must be declared to reserve them. */ | |
497 | && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) | |
498 | /* Otherwise, ask the language. */ | |
499 | && lang_hooks.decls.warn_unused_global (decl)) | |
48e1416a | 500 | warning ((TREE_CODE (decl) == FUNCTION_DECL) |
501 | ? OPT_Wunused_function | |
502 | : OPT_Wunused_variable, | |
2006d7dc | 503 | "%q+D defined but not used", decl); |
c131e678 | 504 | } |
505 | ||
f1f41a6c | 506 | /* Issue appropriate warnings for the global declarations in V (of |
c131e678 | 507 | which there are LEN). */ |
89a75961 | 508 | |
a84da62d | 509 | void |
f1f41a6c | 510 | check_global_declarations (tree *v, int len) |
a84da62d | 511 | { |
a84da62d | 512 | int i; |
513 | ||
514 | for (i = 0; i < len; i++) | |
f1f41a6c | 515 | check_global_declaration_1 (v[i]); |
c131e678 | 516 | } |
a84da62d | 517 | |
c131e678 | 518 | /* Emit debugging information for all global declarations in VEC. */ |
519 | ||
520 | void | |
521 | emit_debug_global_declarations (tree *vec, int len) | |
522 | { | |
523 | int i; | |
524 | ||
525 | /* Avoid confusing the debug information machinery when there are errors. */ | |
852f689e | 526 | if (seen_error ()) |
c131e678 | 527 | return; |
528 | ||
529 | timevar_push (TV_SYMOUT); | |
530 | for (i = 0; i < len; i++) | |
531 | debug_hooks->global_decl (vec[i]); | |
532 | timevar_pop (TV_SYMOUT); | |
a84da62d | 533 | } |
7291115d | 534 | |
9ceb1c29 | 535 | /* Compile an entire translation unit. Write a file of assembly |
536 | output and various debugging dumps. */ | |
3bcb26d1 | 537 | |
538 | static void | |
7237deda | 539 | compile_file (void) |
3bcb26d1 | 540 | { |
6198e8f6 | 541 | timevar_start (TV_PHASE_PARSING); |
542 | timevar_push (TV_PARSE_GLOBAL); | |
3bcb26d1 | 543 | |
b78207a0 | 544 | /* Call the parser, which parses the entire file (calling |
545 | rest_of_compilation for each function). */ | |
b8ba44e7 | 546 | lang_hooks.parse_file (); |
3bcb26d1 | 547 | |
6198e8f6 | 548 | timevar_pop (TV_PARSE_GLOBAL); |
549 | timevar_stop (TV_PHASE_PARSING); | |
550 | ||
3bcb26d1 | 551 | /* Compilation is now finished except for writing |
552 | what's left of the symbol table output. */ | |
3bcb26d1 | 553 | |
57305941 | 554 | if (flag_syntax_only || flag_wpa) |
cdc9fa3e | 555 | return; |
a7b7430b | 556 | |
dfecde36 | 557 | ggc_protect_identifiers = false; |
558 | ||
cf951b1a | 559 | /* This must also call finalize_compilation_unit. */ |
dc24ddbd | 560 | lang_hooks.decls.final_write_globals (); |
15daca6e | 561 | |
852f689e | 562 | if (seen_error ()) |
161121a9 | 563 | return; |
564 | ||
565 | timevar_start (TV_PHASE_LATE_ASM); | |
15daca6e | 566 | |
b33542ab | 567 | /* Compilation unit is finalized. When producing non-fat LTO object, we are |
568 | basically finished. */ | |
569 | if (in_lto_p || !flag_lto || flag_fat_lto_objects) | |
570 | { | |
b33542ab | 571 | /* Likewise for mudflap static object registrations. */ |
572 | if (flag_mudflap) | |
573 | mudflap_finish_file (); | |
e68ba323 | 574 | |
b92cccf4 | 575 | /* File-scope initialization for AddressSanitizer. */ |
9e46467d | 576 | if (flag_sanitize & SANITIZE_ADDRESS) |
b92cccf4 | 577 | asan_finish_file (); |
578 | ||
9e46467d | 579 | if (flag_sanitize & SANITIZE_THREAD) |
b077695d | 580 | tsan_finish_file (); |
581 | ||
b33542ab | 582 | output_shared_constant_pool (); |
583 | output_object_blocks (); | |
ea259bbe | 584 | finish_tm_clone_pairs (); |
f2d0e9f1 | 585 | |
b33542ab | 586 | /* Write out any pending weak symbol declarations. */ |
587 | weak_finish (); | |
df1c8607 | 588 | |
b33542ab | 589 | /* This must be at the end before unwind and debug info. |
590 | Some target ports emit PIC setup thunks here. */ | |
591 | targetm.asm_out.code_end (); | |
5cbd74a3 | 592 | |
b33542ab | 593 | /* Do dbx symbols. */ |
594 | timevar_push (TV_SYMOUT); | |
c140b944 | 595 | |
b33542ab | 596 | #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO |
597 | if (dwarf2out_do_frame ()) | |
598 | dwarf2out_frame_finish (); | |
599 | #endif | |
d757b8c9 | 600 | |
b33542ab | 601 | (*debug_hooks->finish) (main_input_filename); |
602 | timevar_pop (TV_SYMOUT); | |
be6eb971 | 603 | |
b33542ab | 604 | /* Output some stuff at end of file if nec. */ |
3bcb26d1 | 605 | |
b33542ab | 606 | dw2_output_indirect_constants (); |
ad5818ae | 607 | |
b33542ab | 608 | /* Flush any pending external directives. */ |
609 | process_pending_assemble_externals (); | |
610 | } | |
4ffeedd3 | 611 | |
7bfefa9d | 612 | /* Emit LTO marker if LTO info has been previously emitted. This is |
613 | used by collect2 to determine whether an object file contains IL. | |
614 | We used to emit an undefined reference here, but this produces | |
615 | link errors if an object file with IL is stored into a shared | |
616 | library without invoking lto1. */ | |
617 | if (flag_generate_lto) | |
51eafa60 | 618 | { |
619 | #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON | |
620 | ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, | |
621 | "__gnu_lto_v1", | |
622 | (unsigned HOST_WIDE_INT) 1, 8); | |
623 | #elif defined ASM_OUTPUT_ALIGNED_COMMON | |
624 | ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_v1", | |
625 | (unsigned HOST_WIDE_INT) 1, 8); | |
626 | #else | |
627 | ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_v1", | |
628 | (unsigned HOST_WIDE_INT) 1, | |
629 | (unsigned HOST_WIDE_INT) 1); | |
630 | #endif | |
b33542ab | 631 | /* Let linker plugin know that this is a slim object and must be LTOed |
632 | even when user did not ask for it. */ | |
633 | if (!flag_fat_lto_objects) | |
634 | { | |
635 | #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON | |
636 | ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, | |
be3b489b | 637 | "__gnu_lto_slim", |
b33542ab | 638 | (unsigned HOST_WIDE_INT) 1, 8); |
639 | #elif defined ASM_OUTPUT_ALIGNED_COMMON | |
be3b489b | 640 | ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim", |
b33542ab | 641 | (unsigned HOST_WIDE_INT) 1, 8); |
642 | #else | |
be3b489b | 643 | ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim", |
b33542ab | 644 | (unsigned HOST_WIDE_INT) 1, |
645 | (unsigned HOST_WIDE_INT) 1); | |
646 | #endif | |
647 | } | |
51eafa60 | 648 | } |
7bfefa9d | 649 | |
f006a2e6 | 650 | /* Attach a special .ident directive to the end of the file to identify |
651 | the version of GCC which compiled this code. The format of the .ident | |
652 | string is patterned after the ones produced by native SVR4 compilers. */ | |
f006a2e6 | 653 | if (!flag_no_ident) |
d25dc80e | 654 | { |
655 | const char *pkg_version = "(GNU) "; | |
367b1459 | 656 | char *ident_str; |
d25dc80e | 657 | |
658 | if (strcmp ("(GCC) ", pkgversion_string)) | |
659 | pkg_version = pkgversion_string; | |
367b1459 | 660 | |
661 | ident_str = ACONCAT (("GCC: ", pkg_version, version_string, NULL)); | |
662 | targetm.asm_out.output_ident (ident_str); | |
d25dc80e | 663 | } |
5cf09555 | 664 | |
67a2b55a | 665 | /* Invoke registered plugin callbacks. */ |
666 | invoke_plugin_callbacks (PLUGIN_FINISH_UNIT, NULL); | |
48e1416a | 667 | |
5cf09555 | 668 | /* This must be at the end. Some target ports emit end of file directives |
669 | into the assembly file here, and hence we can not output anything to the | |
670 | assembly file after this point. */ | |
671 | targetm.asm_out.file_end (); | |
6198e8f6 | 672 | |
161121a9 | 673 | timevar_stop (TV_PHASE_LATE_ASM); |
3bcb26d1 | 674 | } |
03414cfb | 675 | |
a49a878f | 676 | /* Print version information to FILE. |
677 | Each line begins with INDENT (for the case where FILE is the | |
678 | assembler output file). */ | |
9dda7915 | 679 | |
a49a878f | 680 | void |
681 | print_version (FILE *file, const char *indent) | |
9ceb1c29 | 682 | { |
0a81f5a0 | 683 | static const char fmt1[] = |
9ceb1c29 | 684 | #ifdef __GNUC__ |
d25dc80e | 685 | N_("%s%s%s %sversion %s (%s)\n%s\tcompiled by GNU C version %s, ") |
9ceb1c29 | 686 | #else |
d25dc80e | 687 | N_("%s%s%s %sversion %s (%s) compiled by CC, ") |
9ceb1c29 | 688 | #endif |
0a81f5a0 | 689 | ; |
690 | static const char fmt2[] = | |
239d491a | 691 | N_("GMP version %s, MPFR version %s, MPC version %s\n"); |
bd0d5325 | 692 | static const char fmt3[] = |
ceb21d85 | 693 | N_("%s%swarning: %s header version %s differs from library version %s.\n"); |
bd0d5325 | 694 | static const char fmt4[] = |
0a81f5a0 | 695 | N_("%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n"); |
696 | #ifndef __VERSION__ | |
697 | #define __VERSION__ "[?]" | |
698 | #endif | |
699 | fprintf (file, | |
700 | file == stderr ? _(fmt1) : fmt1, | |
701 | indent, *indent != 0 ? " " : "", | |
d25dc80e | 702 | lang_hooks.name, pkgversion_string, version_string, TARGET_NAME, |
9ceb1c29 | 703 | indent, __VERSION__); |
bd0d5325 | 704 | |
705 | /* We need to stringify the GMP macro values. Ugh, gmp_version has | |
660b6c15 | 706 | two string formats, "i.j.k" and "i.j" when k is zero. As of |
707 | gmp-4.3.0, GMP always uses the 3 number format. */ | |
bd0d5325 | 708 | #define GCC_GMP_STRINGIFY_VERSION3(X) #X |
709 | #define GCC_GMP_STRINGIFY_VERSION2(X) GCC_GMP_STRINGIFY_VERSION3(X) | |
660b6c15 | 710 | #define GCC_GMP_VERSION_NUM(X,Y,Z) (((X) << 16L) | ((Y) << 8) | (Z)) |
711 | #define GCC_GMP_VERSION \ | |
712 | GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL) | |
713 | #if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,0) && __GNU_MP_VERSION_PATCHLEVEL == 0 | |
bd0d5325 | 714 | #define GCC_GMP_STRINGIFY_VERSION GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION) "." \ |
715 | GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_MINOR) | |
716 | #else | |
717 | #define GCC_GMP_STRINGIFY_VERSION GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION) "." \ | |
718 | GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_MINOR) "." \ | |
719 | GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_PATCHLEVEL) | |
720 | #endif | |
0a81f5a0 | 721 | fprintf (file, |
722 | file == stderr ? _(fmt2) : fmt2, | |
965d0f29 | 723 | GCC_GMP_STRINGIFY_VERSION, MPFR_VERSION_STRING, MPC_VERSION_STRING); |
bd0d5325 | 724 | if (strcmp (GCC_GMP_STRINGIFY_VERSION, gmp_version)) |
725 | fprintf (file, | |
726 | file == stderr ? _(fmt3) : fmt3, | |
ceb21d85 | 727 | indent, *indent != 0 ? " " : "", |
bd0d5325 | 728 | "GMP", GCC_GMP_STRINGIFY_VERSION, gmp_version); |
729 | if (strcmp (MPFR_VERSION_STRING, mpfr_get_version ())) | |
730 | fprintf (file, | |
731 | file == stderr ? _(fmt3) : fmt3, | |
ceb21d85 | 732 | indent, *indent != 0 ? " " : "", |
bd0d5325 | 733 | "MPFR", MPFR_VERSION_STRING, mpfr_get_version ()); |
239d491a | 734 | if (strcmp (MPC_VERSION_STRING, mpc_get_version ())) |
735 | fprintf (file, | |
736 | file == stderr ? _(fmt3) : fmt3, | |
737 | indent, *indent != 0 ? " " : "", | |
738 | "MPC", MPC_VERSION_STRING, mpc_get_version ()); | |
bd0d5325 | 739 | fprintf (file, |
740 | file == stderr ? _(fmt4) : fmt4, | |
e4de0dc0 | 741 | indent, *indent != 0 ? " " : "", |
742 | PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE)); | |
e16288b4 | 743 | |
744 | print_plugins_versions (file, indent); | |
9ceb1c29 | 745 | } |
746 | ||
7c6733e8 | 747 | static int |
748 | print_to_asm_out_file (print_switch_type type, const char * text) | |
749 | { | |
750 | bool prepend_sep = true; | |
751 | ||
752 | switch (type) | |
753 | { | |
754 | case SWITCH_TYPE_LINE_END: | |
755 | putc ('\n', asm_out_file); | |
756 | return 1; | |
757 | ||
758 | case SWITCH_TYPE_LINE_START: | |
759 | fputs (ASM_COMMENT_START, asm_out_file); | |
760 | return strlen (ASM_COMMENT_START); | |
761 | ||
762 | case SWITCH_TYPE_DESCRIPTIVE: | |
763 | if (ASM_COMMENT_START[0] == 0) | |
764 | prepend_sep = false; | |
765 | /* Drop through. */ | |
766 | case SWITCH_TYPE_PASSED: | |
767 | case SWITCH_TYPE_ENABLED: | |
768 | if (prepend_sep) | |
769 | fputc (' ', asm_out_file); | |
609e7ca1 | 770 | fputs (text, asm_out_file); |
7c6733e8 | 771 | /* No need to return the length here as |
772 | print_single_switch has already done it. */ | |
773 | return 0; | |
774 | ||
775 | default: | |
776 | return -1; | |
777 | } | |
778 | } | |
7c6733e8 | 779 | |
780 | static int | |
781 | print_to_stderr (print_switch_type type, const char * text) | |
782 | { | |
783 | switch (type) | |
784 | { | |
785 | case SWITCH_TYPE_LINE_END: | |
786 | putc ('\n', stderr); | |
787 | return 1; | |
788 | ||
789 | case SWITCH_TYPE_LINE_START: | |
790 | return 0; | |
48e1416a | 791 | |
7c6733e8 | 792 | case SWITCH_TYPE_PASSED: |
793 | case SWITCH_TYPE_ENABLED: | |
794 | fputc (' ', stderr); | |
795 | /* Drop through. */ | |
796 | ||
797 | case SWITCH_TYPE_DESCRIPTIVE: | |
609e7ca1 | 798 | fputs (text, stderr); |
7c6733e8 | 799 | /* No need to return the length here as |
800 | print_single_switch has already done it. */ | |
801 | return 0; | |
802 | ||
803 | default: | |
804 | return -1; | |
805 | } | |
806 | } | |
807 | ||
9ceb1c29 | 808 | /* Print an option value and return the adjusted position in the line. |
7c6733e8 | 809 | ??? print_fn doesn't handle errors, eg disk full; presumably other |
810 | code will catch a disk full though. */ | |
9ceb1c29 | 811 | |
812 | static int | |
7c6733e8 | 813 | print_single_switch (print_switch_fn_type print_fn, |
814 | int pos, | |
815 | print_switch_type type, | |
816 | const char * text) | |
9ceb1c29 | 817 | { |
7c6733e8 | 818 | /* The ultrix fprintf returns 0 on success, so compute the result |
819 | we want here since we need it for the following test. The +1 | |
7920eed5 | 820 | is for the separator character that will probably be emitted. */ |
7c6733e8 | 821 | int len = strlen (text) + 1; |
9ceb1c29 | 822 | |
823 | if (pos != 0 | |
7c6733e8 | 824 | && pos + len > MAX_LINE) |
9ceb1c29 | 825 | { |
7c6733e8 | 826 | print_fn (SWITCH_TYPE_LINE_END, NULL); |
9ceb1c29 | 827 | pos = 0; |
828 | } | |
7c6733e8 | 829 | |
9ceb1c29 | 830 | if (pos == 0) |
7c6733e8 | 831 | pos += print_fn (SWITCH_TYPE_LINE_START, NULL); |
832 | ||
833 | print_fn (type, text); | |
834 | return pos + len; | |
9ceb1c29 | 835 | } |
836 | ||
7c6733e8 | 837 | /* Print active target switches using PRINT_FN. |
9ceb1c29 | 838 | POS is the current cursor position and MAX is the size of a "line". |
839 | Each line begins with INDENT and ends with TERM. | |
840 | Each switch is separated from the next by SEP. */ | |
841 | ||
842 | static void | |
7c6733e8 | 843 | print_switch_values (print_switch_fn_type print_fn) |
9ceb1c29 | 844 | { |
7c6733e8 | 845 | int pos = 0; |
9ceb1c29 | 846 | size_t j; |
9ceb1c29 | 847 | |
eb54bdbd | 848 | /* Fill in the -frandom-seed option, if the user didn't pass it, so |
b80f1d67 | 849 | that it can be printed below. This helps reproducibility. */ |
b6c1bd72 | 850 | if (!flag_random_seed) |
851 | init_random_seed (); | |
eb54bdbd | 852 | |
9ceb1c29 | 853 | /* Print the options as passed. */ |
7c6733e8 | 854 | pos = print_single_switch (print_fn, pos, |
855 | SWITCH_TYPE_DESCRIPTIVE, _("options passed: ")); | |
9ceb1c29 | 856 | |
615ef0bb | 857 | for (j = 1; j < save_decoded_options_count; j++) |
7c6733e8 | 858 | { |
615ef0bb | 859 | switch (save_decoded_options[j].opt_index) |
7c6733e8 | 860 | { |
615ef0bb | 861 | case OPT_o: |
862 | case OPT_d: | |
863 | case OPT_dumpbase: | |
864 | case OPT_dumpdir: | |
865 | case OPT_auxbase: | |
866 | case OPT_quiet: | |
867 | case OPT_version: | |
7c6733e8 | 868 | /* Ignore these. */ |
615ef0bb | 869 | continue; |
7c6733e8 | 870 | } |
871 | ||
615ef0bb | 872 | pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED, |
873 | save_decoded_options[j].orig_option_with_args_text); | |
7c6733e8 | 874 | } |
875 | ||
9ceb1c29 | 876 | if (pos > 0) |
7c6733e8 | 877 | print_fn (SWITCH_TYPE_LINE_END, NULL); |
9ceb1c29 | 878 | |
879 | /* Print the -f and -m options that have been enabled. | |
880 | We don't handle language specific options but printing argv | |
881 | should suffice. */ | |
7c6733e8 | 882 | pos = print_single_switch (print_fn, 0, |
883 | SWITCH_TYPE_DESCRIPTIVE, _("options enabled: ")); | |
9ceb1c29 | 884 | |
2e9da478 | 885 | for (j = 0; j < cl_options_count; j++) |
ec840af4 | 886 | if (cl_options[j].cl_report |
2c5d2e39 | 887 | && option_enabled (j, &global_options) > 0) |
7c6733e8 | 888 | pos = print_single_switch (print_fn, pos, |
889 | SWITCH_TYPE_ENABLED, cl_options[j].opt_text); | |
9ceb1c29 | 890 | |
7c6733e8 | 891 | print_fn (SWITCH_TYPE_LINE_END, NULL); |
9ceb1c29 | 892 | } |
03414cfb | 893 | |
9ceb1c29 | 894 | /* Open assembly code output file. Do this even if -fsyntax-only is |
895 | on, because then the driver will have provided the name of a | |
896 | temporary file or bit bucket for us. NAME is the file specified on | |
897 | the command line, possibly NULL. */ | |
898 | static void | |
7237deda | 899 | init_asm_output (const char *name) |
9ceb1c29 | 900 | { |
901 | if (name == NULL && asm_file_name == 0) | |
902 | asm_out_file = stdout; | |
903 | else | |
904 | { | |
905 | if (asm_file_name == 0) | |
b1157638 | 906 | { |
907 | int len = strlen (dump_base_name); | |
eb59413a | 908 | char *dumpname = XNEWVEC (char, len + 6); |
7c6733e8 | 909 | |
b1157638 | 910 | memcpy (dumpname, dump_base_name, len + 1); |
911 | strip_off_ending (dumpname, len); | |
912 | strcat (dumpname, ".s"); | |
913 | asm_file_name = dumpname; | |
914 | } | |
9ceb1c29 | 915 | if (!strcmp (asm_file_name, "-")) |
b1157638 | 916 | asm_out_file = stdout; |
9ceb1c29 | 917 | else |
c2a65b90 | 918 | asm_out_file = fopen (asm_file_name, "w"); |
9ceb1c29 | 919 | if (asm_out_file == 0) |
eb586f2c | 920 | fatal_error ("can%'t open %s for writing: %m", asm_file_name); |
9ceb1c29 | 921 | } |
922 | ||
9ceb1c29 | 923 | if (!flag_syntax_only) |
924 | { | |
92c473b8 | 925 | targetm.asm_out.file_start (); |
9ceb1c29 | 926 | |
7c6733e8 | 927 | if (flag_record_gcc_switches) |
928 | { | |
929 | if (targetm.asm_out.record_gcc_switches) | |
930 | { | |
931 | /* Let the target know that we are about to start recording. */ | |
932 | targetm.asm_out.record_gcc_switches (SWITCH_TYPE_DESCRIPTIVE, | |
933 | NULL); | |
934 | /* Now record the switches. */ | |
935 | print_switch_values (targetm.asm_out.record_gcc_switches); | |
936 | /* Let the target know that the recording is over. */ | |
937 | targetm.asm_out.record_gcc_switches (SWITCH_TYPE_DESCRIPTIVE, | |
938 | NULL); | |
939 | } | |
940 | else | |
5bcc316e | 941 | inform (input_location, "-frecord-gcc-switches is not supported by the current target"); |
7c6733e8 | 942 | } |
943 | ||
9ceb1c29 | 944 | if (flag_verbose_asm) |
945 | { | |
7c6733e8 | 946 | /* Print the list of switches in effect |
947 | into the assembler file as comments. */ | |
9ceb1c29 | 948 | print_version (asm_out_file, ASM_COMMENT_START); |
7c6733e8 | 949 | print_switch_values (print_to_asm_out_file); |
609e7ca1 | 950 | putc ('\n', asm_out_file); |
9ceb1c29 | 951 | } |
9ceb1c29 | 952 | } |
953 | } | |
03414cfb | 954 | |
931b0a0f | 955 | /* A helper function; used as the reallocator function for cpp's line |
956 | table. */ | |
957 | static void * | |
958 | realloc_for_line_map (void *ptr, size_t len) | |
959 | { | |
ba72912a | 960 | return GGC_RESIZEVAR (void, ptr, len); |
931b0a0f | 961 | } |
962 | ||
ddcdd2ab | 963 | /* A helper function: used as the allocator function for |
964 | identifier_to_locale. */ | |
965 | static void * | |
966 | alloc_for_identifier_to_locale (size_t len) | |
967 | { | |
ba72912a | 968 | return ggc_alloc_atomic (len); |
ddcdd2ab | 969 | } |
970 | ||
990495a7 | 971 | /* Output stack usage information. */ |
972 | void | |
973 | output_stack_usage (void) | |
974 | { | |
975 | static bool warning_issued = false; | |
976 | enum stack_usage_kind_type { STATIC = 0, DYNAMIC, DYNAMIC_BOUNDED }; | |
977 | const char *stack_usage_kind_str[] = { | |
978 | "static", | |
979 | "dynamic", | |
980 | "dynamic,bounded" | |
981 | }; | |
982 | HOST_WIDE_INT stack_usage = current_function_static_stack_size; | |
983 | enum stack_usage_kind_type stack_usage_kind; | |
990495a7 | 984 | |
985 | if (stack_usage < 0) | |
986 | { | |
987 | if (!warning_issued) | |
988 | { | |
8c0dd614 | 989 | warning (0, "stack usage computation not supported for this target"); |
990495a7 | 990 | warning_issued = true; |
991 | } | |
992 | return; | |
993 | } | |
994 | ||
995 | stack_usage_kind = STATIC; | |
996 | ||
997 | /* Add the maximum amount of space pushed onto the stack. */ | |
998 | if (current_function_pushed_stack_size > 0) | |
999 | { | |
1000 | stack_usage += current_function_pushed_stack_size; | |
1001 | stack_usage_kind = DYNAMIC_BOUNDED; | |
1002 | } | |
1003 | ||
1004 | /* Now on to the tricky part: dynamic stack allocation. */ | |
1005 | if (current_function_allocates_dynamic_stack_space) | |
1006 | { | |
1007 | if (current_function_has_unbounded_dynamic_stack_size) | |
1008 | stack_usage_kind = DYNAMIC; | |
1009 | else | |
1010 | stack_usage_kind = DYNAMIC_BOUNDED; | |
1011 | ||
1012 | /* Add the size even in the unbounded case, this can't hurt. */ | |
1013 | stack_usage += current_function_dynamic_stack_size; | |
1014 | } | |
1015 | ||
8c0dd614 | 1016 | if (flag_stack_usage) |
1017 | { | |
1018 | expanded_location loc | |
1019 | = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); | |
1020 | const char *raw_id, *id; | |
1021 | ||
1022 | /* Strip the scope prefix if any. */ | |
1023 | raw_id = lang_hooks.decl_printable_name (current_function_decl, 2); | |
1024 | id = strrchr (raw_id, '.'); | |
1025 | if (id) | |
1026 | id++; | |
1027 | else | |
1028 | id = raw_id; | |
1029 | ||
1030 | fprintf (stack_usage_file, | |
1031 | "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n", | |
1032 | lbasename (loc.file), | |
1033 | loc.line, | |
1034 | loc.column, | |
1035 | id, | |
1036 | stack_usage, | |
1037 | stack_usage_kind_str[stack_usage_kind]); | |
1038 | } | |
990495a7 | 1039 | |
8c0dd614 | 1040 | if (warn_stack_usage >= 0) |
1041 | { | |
1042 | if (stack_usage_kind == DYNAMIC) | |
1043 | warning (OPT_Wstack_usage_, "stack usage might be unbounded"); | |
1044 | else if (stack_usage > warn_stack_usage) | |
1045 | { | |
1046 | if (stack_usage_kind == DYNAMIC_BOUNDED) | |
1047 | warning (OPT_Wstack_usage_, "stack usage might be %wd bytes", | |
1048 | stack_usage); | |
1049 | else | |
1050 | warning (OPT_Wstack_usage_, "stack usage is %wd bytes", | |
1051 | stack_usage); | |
1052 | } | |
1053 | } | |
990495a7 | 1054 | } |
1055 | ||
1056 | /* Open an auxiliary output file. */ | |
1057 | static FILE * | |
1058 | open_auxiliary_file (const char *ext) | |
1059 | { | |
1060 | char *filename; | |
1061 | FILE *file; | |
1062 | ||
1063 | filename = concat (aux_base_name, ".", ext, NULL); | |
1064 | file = fopen (filename, "w"); | |
1065 | if (!file) | |
bf776685 | 1066 | fatal_error ("can%'t open %s for writing: %m", filename); |
990495a7 | 1067 | free (filename); |
1068 | return file; | |
1069 | } | |
1070 | ||
9ceb1c29 | 1071 | /* Initialization of the front end environment, before command line |
1072 | options are parsed. Signal handlers, internationalization etc. | |
1073 | ARGV0 is main's argv[0]. */ | |
1074 | static void | |
4838a8b6 | 1075 | general_init (const char *argv0) |
9ceb1c29 | 1076 | { |
4838a8b6 | 1077 | const char *p; |
9ceb1c29 | 1078 | |
1079 | p = argv0 + strlen (argv0); | |
1080 | while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) | |
1081 | --p; | |
1082 | progname = p; | |
1083 | ||
1084 | xmalloc_set_program_name (progname); | |
6deeea15 | 1085 | |
77e1a5df | 1086 | hex_init (); |
1087 | ||
4367c81f | 1088 | /* Unlock the stdio streams. */ |
9c8f076b | 1089 | unlock_std_streams (); |
4367c81f | 1090 | |
eb718689 | 1091 | gcc_init_libintl (); |
be2828ce | 1092 | |
ddcdd2ab | 1093 | identifier_to_locale_alloc = alloc_for_identifier_to_locale; |
1094 | identifier_to_locale_free = ggc_free; | |
1095 | ||
aa6db498 | 1096 | /* Initialize the diagnostics reporting machinery, so option parsing |
1097 | can give warnings and errors. */ | |
3c6a9715 | 1098 | diagnostic_initialize (global_dc, N_OPTS); |
aa6db498 | 1099 | /* Set a default printer. Language specific initializations will |
1100 | override it later. */ | |
c224fa34 | 1101 | tree_diagnostics_defaults (global_dc); |
1102 | /* FIXME: This should probably be moved to C-family | |
1103 | language-specific initializations. */ | |
1104 | /* By default print macro expansion contexts in the diagnostic | |
1105 | finalizer -- for tokens resulting from macro expansion. */ | |
1106 | diagnostic_finalizer (global_dc) = virt_loc_aware_diagnostic_finalizer; | |
1107 | ||
5a983084 | 1108 | global_dc->show_caret |
1109 | = global_options_init.x_flag_diagnostics_show_caret; | |
f3f006ad | 1110 | global_dc->show_option_requested |
1111 | = global_options_init.x_flag_diagnostics_show_option; | |
1112 | global_dc->show_column | |
1113 | = global_options_init.x_flag_show_column; | |
1f63d337 | 1114 | global_dc->internal_error = plugins_internal_error_function; |
3c6a9715 | 1115 | global_dc->option_enabled = option_enabled; |
2c5d2e39 | 1116 | global_dc->option_state = &global_options; |
3c6a9715 | 1117 | global_dc->option_name = option_name; |
aa6db498 | 1118 | |
b9b90cce | 1119 | /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ |
1120 | #ifdef SIGSEGV | |
1121 | signal (SIGSEGV, crash_signal); | |
004cf1e3 | 1122 | #endif |
b9b90cce | 1123 | #ifdef SIGILL |
1124 | signal (SIGILL, crash_signal); | |
1125 | #endif | |
1126 | #ifdef SIGBUS | |
1127 | signal (SIGBUS, crash_signal); | |
1128 | #endif | |
1129 | #ifdef SIGABRT | |
1130 | signal (SIGABRT, crash_signal); | |
1131 | #endif | |
1132 | #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT) | |
1133 | signal (SIGIOT, crash_signal); | |
1134 | #endif | |
536f5fb1 | 1135 | #ifdef SIGFPE |
1136 | signal (SIGFPE, crash_signal); | |
1137 | #endif | |
89a75961 | 1138 | |
b197fbcf | 1139 | /* Other host-specific signal setup. */ |
1140 | (*host_hooks.extra_signals)(); | |
1141 | ||
5934ea7a | 1142 | /* Initialize the garbage-collector, string pools and tree type hash |
1143 | table. */ | |
1144 | init_ggc (); | |
1145 | init_stringpool (); | |
ba72912a | 1146 | line_table = ggc_alloc_line_maps (); |
931b0a0f | 1147 | linemap_init (line_table); |
1148 | line_table->reallocator = realloc_for_line_map; | |
1ae3520e | 1149 | line_table->round_alloc_size = ggc_round_alloc_size; |
5934ea7a | 1150 | init_ttree (); |
262444a6 | 1151 | |
9ceb1c29 | 1152 | /* Initialize register usage now so switches may override. */ |
1153 | init_reg_sets (); | |
990339dd | 1154 | |
9a33a2e8 | 1155 | /* Register the language-independent parameters. */ |
6a2fc14e | 1156 | global_init_params (); |
9a33a2e8 | 1157 | |
6a2fc14e | 1158 | /* This must be done after global_init_params but before argument |
1159 | processing. */ | |
7d83df95 | 1160 | init_ggc_heuristics(); |
8d0badf1 | 1161 | |
3ea50c01 | 1162 | /* Create the singleton holder for global state. |
1163 | Doing so also creates the pass manager and with it the passes. */ | |
8d0badf1 | 1164 | g = new gcc::context(); |
1165 | ||
9659d177 | 1166 | statistics_early_init (); |
56f280c4 | 1167 | finish_params (); |
5764e93a | 1168 | } |
03414cfb | 1169 | |
f2d0e9f1 | 1170 | /* Return true if the current target supports -fsection-anchors. */ |
1171 | ||
1172 | static bool | |
1173 | target_supports_section_anchors_p (void) | |
1174 | { | |
1175 | if (targetm.min_anchor_offset == 0 && targetm.max_anchor_offset == 0) | |
1176 | return false; | |
1177 | ||
1178 | if (targetm.asm_out.output_anchor == NULL) | |
1179 | return false; | |
1180 | ||
1181 | return true; | |
1182 | } | |
1183 | ||
6d8b68a3 | 1184 | /* Default the align_* variables to 1 if they're still unset, and |
1185 | set up the align_*_log variables. */ | |
1186 | static void | |
1187 | init_alignments (void) | |
1188 | { | |
1189 | if (align_loops <= 0) | |
1190 | align_loops = 1; | |
1191 | if (align_loops_max_skip > align_loops) | |
1192 | align_loops_max_skip = align_loops - 1; | |
1193 | align_loops_log = floor_log2 (align_loops * 2 - 1); | |
1194 | if (align_jumps <= 0) | |
1195 | align_jumps = 1; | |
1196 | if (align_jumps_max_skip > align_jumps) | |
1197 | align_jumps_max_skip = align_jumps - 1; | |
1198 | align_jumps_log = floor_log2 (align_jumps * 2 - 1); | |
1199 | if (align_labels <= 0) | |
1200 | align_labels = 1; | |
1201 | align_labels_log = floor_log2 (align_labels * 2 - 1); | |
1202 | if (align_labels_max_skip > align_labels) | |
1203 | align_labels_max_skip = align_labels - 1; | |
1204 | if (align_functions <= 0) | |
1205 | align_functions = 1; | |
1206 | align_functions_log = floor_log2 (align_functions * 2 - 1); | |
1207 | } | |
1208 | ||
5764e93a | 1209 | /* Process the options that have been parsed. */ |
1210 | static void | |
7237deda | 1211 | process_options (void) |
5764e93a | 1212 | { |
0c5e3a3d | 1213 | /* Just in case lang_hooks.post_options ends up calling a debug_hook. |
1214 | This can happen with incorrect pre-processed input. */ | |
1215 | debug_hooks = &do_nothing_debug_hooks; | |
1216 | ||
9faf44d6 | 1217 | maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT; |
1218 | ||
71eeb8d3 | 1219 | /* Default to -fdiagnostics-color=auto if GCC_COLORS is in the environment, |
1220 | otherwise default to -fdiagnostics-color=never. */ | |
1221 | if (!global_options_set.x_flag_diagnostics_show_color | |
1222 | && getenv ("GCC_COLORS")) | |
1223 | pp_show_color (global_dc->printer) | |
1224 | = colorize_init (DIAGNOSTICS_COLOR_AUTO); | |
1225 | ||
03bde601 | 1226 | /* Allow the front end to perform consistency checks and do further |
1227 | initialization based on the command line options. This hook also | |
1228 | sets the original filename if appropriate (e.g. foo.i -> foo.c) | |
1229 | so we can correctly initialize debug output. */ | |
dc24ddbd | 1230 | no_backend = lang_hooks.post_options (&main_input_filename); |
03bde601 | 1231 | |
3bcb26d1 | 1232 | /* Some machines may reject certain combinations of options. */ |
cc5d3821 | 1233 | targetm.target_option.override (); |
3bcb26d1 | 1234 | |
16b4d5bb | 1235 | /* Avoid any informative notes in the second run of -fcompare-debug. */ |
1236 | if (flag_compare_debug) | |
1237 | diagnostic_inhibit_notes (global_dc); | |
1238 | ||
f2d0e9f1 | 1239 | if (flag_section_anchors && !target_supports_section_anchors_p ()) |
1240 | { | |
1241 | warning (OPT_fsection_anchors, | |
1242 | "this target does not support %qs", "-fsection-anchors"); | |
1243 | flag_section_anchors = 0; | |
1244 | } | |
1245 | ||
5bf3fee3 | 1246 | if (flag_short_enums == 2) |
1247 | flag_short_enums = targetm.default_short_enums (); | |
1248 | ||
a766fb27 | 1249 | /* Set aux_base_name if not already set. */ |
1250 | if (aux_base_name) | |
1251 | ; | |
3272db82 | 1252 | else if (main_input_filename) |
a766fb27 | 1253 | { |
3272db82 | 1254 | char *name = xstrdup (lbasename (main_input_filename)); |
7237deda | 1255 | |
a766fb27 | 1256 | strip_off_ending (name, strlen (name)); |
1257 | aux_base_name = name; | |
1258 | } | |
1259 | else | |
1260 | aux_base_name = "gccaux"; | |
1261 | ||
abb60a19 | 1262 | #ifndef HAVE_cloog |
1263 | if (flag_graphite | |
63c5b29f | 1264 | || flag_graphite_identity |
abb60a19 | 1265 | || flag_loop_block |
1266 | || flag_loop_interchange | |
f4c4e2a2 | 1267 | || flag_loop_strip_mine |
16848556 | 1268 | || flag_loop_parallelize_all) |
63c5b29f | 1269 | sorry ("Graphite loop optimizations cannot be used (-fgraphite, " |
d094f1d6 | 1270 | "-fgraphite-identity, -floop-block, " |
63c5b29f | 1271 | "-floop-interchange, -floop-strip-mine, -floop-parallelize-all, " |
1272 | "and -ftree-loop-linear)"); | |
abb60a19 | 1273 | #endif |
1274 | ||
9ea022ce | 1275 | if (flag_mudflap && flag_lto) |
1276 | sorry ("mudflap cannot be used together with link-time optimization"); | |
1277 | ||
0cb057cb | 1278 | /* One region RA really helps to decrease the code size. */ |
1279 | if (flag_ira_region == IRA_REGION_AUTODETECT) | |
1280 | flag_ira_region | |
1281 | = optimize_size || !optimize ? IRA_REGION_ONE : IRA_REGION_MIXED; | |
1282 | ||
941a2396 | 1283 | if (flag_strict_volatile_bitfields > 0 && !abi_version_at_least (2)) |
1284 | { | |
dc024a04 | 1285 | warning (0, "-fstrict-volatile-bitfields disabled; " |
941a2396 | 1286 | "it is incompatible with ABI versions < 2"); |
1287 | flag_strict_volatile_bitfields = 0; | |
1288 | } | |
1289 | ||
3bcb26d1 | 1290 | /* Unrolling all loops implies that standard loop unrolling must also |
1291 | be done. */ | |
1292 | if (flag_unroll_all_loops) | |
1293 | flag_unroll_loops = 1; | |
ce32fe65 | 1294 | |
c17f64cc | 1295 | /* web and rename-registers help when run after loop unrolling. */ |
472cd78a | 1296 | if (flag_web == AUTODETECT_VALUE) |
1297 | flag_web = flag_unroll_loops || flag_peel_loops; | |
a64054c0 | 1298 | |
472cd78a | 1299 | if (flag_rename_registers == AUTODETECT_VALUE) |
1300 | flag_rename_registers = flag_unroll_loops || flag_peel_loops; | |
3bcb26d1 | 1301 | |
9645fa4f | 1302 | if (flag_non_call_exceptions) |
1303 | flag_asynchronous_unwind_tables = 1; | |
1304 | if (flag_asynchronous_unwind_tables) | |
1305 | flag_unwind_tables = 1; | |
1306 | ||
1c6a7b8c | 1307 | if (flag_value_profile_transformations) |
1308 | flag_profile_values = 1; | |
1309 | ||
3bcb26d1 | 1310 | /* Warn about options that are not supported on this machine. */ |
1311 | #ifndef INSN_SCHEDULING | |
1312 | if (flag_schedule_insns || flag_schedule_insns_after_reload) | |
c3ceba8e | 1313 | warning (0, "instruction scheduling not supported on this target machine"); |
3bcb26d1 | 1314 | #endif |
1315 | #ifndef DELAY_SLOTS | |
1316 | if (flag_delayed_branch) | |
c3ceba8e | 1317 | warning (0, "this target machine does not have delayed branches"); |
3bcb26d1 | 1318 | #endif |
1319 | ||
95c4b02a | 1320 | user_label_prefix = USER_LABEL_PREFIX; |
1321 | if (flag_leading_underscore != -1) | |
1322 | { | |
89a75961 | 1323 | /* If the default prefix is more complicated than "" or "_", |
95c4b02a | 1324 | issue a warning and ignore this option. */ |
1325 | if (user_label_prefix[0] == 0 || | |
1326 | (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) | |
1327 | { | |
1328 | user_label_prefix = flag_leading_underscore ? "_" : ""; | |
1329 | } | |
1330 | else | |
c3ceba8e | 1331 | warning (0, "-f%sleading-underscore not supported on this target machine", |
95c4b02a | 1332 | flag_leading_underscore ? "" : "no-"); |
1333 | } | |
1334 | ||
3bcb26d1 | 1335 | /* If we are in verbose mode, write out the version and maybe all the |
1336 | option flags in use. */ | |
1337 | if (version_flag) | |
1338 | { | |
e87e2aa9 | 1339 | print_version (stderr, ""); |
3bcb26d1 | 1340 | if (! quiet_flag) |
7c6733e8 | 1341 | print_switch_values (print_to_stderr); |
3bcb26d1 | 1342 | } |
1343 | ||
9ceb1c29 | 1344 | if (flag_syntax_only) |
1345 | { | |
1346 | write_symbols = NO_DEBUG; | |
1347 | profile_flag = 0; | |
9ceb1c29 | 1348 | } |
3bcb26d1 | 1349 | |
71278019 | 1350 | if (flag_gtoggle) |
1351 | { | |
1352 | if (debug_info_level == DINFO_LEVEL_NONE) | |
bb6e20de | 1353 | { |
1354 | debug_info_level = DINFO_LEVEL_NORMAL; | |
1355 | ||
1356 | if (write_symbols == NO_DEBUG) | |
1357 | write_symbols = PREFERRED_DEBUGGING_TYPE; | |
1358 | } | |
71278019 | 1359 | else |
1360 | debug_info_level = DINFO_LEVEL_NONE; | |
1361 | } | |
1362 | ||
9845d120 | 1363 | if (flag_dump_final_insns && !flag_syntax_only && !no_backend) |
71278019 | 1364 | { |
1365 | FILE *final_output = fopen (flag_dump_final_insns, "w"); | |
1366 | if (!final_output) | |
1367 | { | |
8fb69344 | 1368 | error ("could not open final insn dump file %qs: %m", |
1369 | flag_dump_final_insns); | |
71278019 | 1370 | flag_dump_final_insns = NULL; |
1371 | } | |
1372 | else if (fclose (final_output)) | |
1373 | { | |
8fb69344 | 1374 | error ("could not close zeroed insn dump file %qs: %m", |
1375 | flag_dump_final_insns); | |
71278019 | 1376 | flag_dump_final_insns = NULL; |
1377 | } | |
1378 | } | |
1379 | ||
b0e56fb1 | 1380 | /* A lot of code assumes write_symbols == NO_DEBUG if the debugging |
1381 | level is 0. */ | |
1382 | if (debug_info_level == DINFO_LEVEL_NONE) | |
1383 | write_symbols = NO_DEBUG; | |
1384 | ||
b0e56fb1 | 1385 | if (write_symbols == NO_DEBUG) |
8b7af0c0 | 1386 | ; |
9ceb1c29 | 1387 | #if defined(DBX_DEBUGGING_INFO) |
b0e56fb1 | 1388 | else if (write_symbols == DBX_DEBUG) |
9ceb1c29 | 1389 | debug_hooks = &dbx_debug_hooks; |
3bcb26d1 | 1390 | #endif |
9ceb1c29 | 1391 | #if defined(XCOFF_DEBUGGING_INFO) |
b0e56fb1 | 1392 | else if (write_symbols == XCOFF_DEBUG) |
9ceb1c29 | 1393 | debug_hooks = &xcoff_debug_hooks; |
e87e2aa9 | 1394 | #endif |
9ceb1c29 | 1395 | #ifdef SDB_DEBUGGING_INFO |
b0e56fb1 | 1396 | else if (write_symbols == SDB_DEBUG) |
9ceb1c29 | 1397 | debug_hooks = &sdb_debug_hooks; |
1398 | #endif | |
9ceb1c29 | 1399 | #ifdef DWARF2_DEBUGGING_INFO |
b0e56fb1 | 1400 | else if (write_symbols == DWARF2_DEBUG) |
9ceb1c29 | 1401 | debug_hooks = &dwarf2_debug_hooks; |
e87e2aa9 | 1402 | #endif |
8d60d2bc | 1403 | #ifdef VMS_DEBUGGING_INFO |
b0e56fb1 | 1404 | else if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) |
8d60d2bc | 1405 | debug_hooks = &vmsdbg_debug_hooks; |
1406 | #endif | |
b0e56fb1 | 1407 | else |
1408 | error ("target system does not support the \"%s\" debug format", | |
1409 | debug_type_names[write_symbols]); | |
3bcb26d1 | 1410 | |
a64054c0 | 1411 | /* We know which debug output will be used so we can set flag_var_tracking |
1412 | and flag_var_tracking_uninit if the user has not specified them. */ | |
ad469377 | 1413 | if (debug_info_level < DINFO_LEVEL_NORMAL |
1414 | || debug_hooks->var_location == do_nothing_debug_hooks.var_location) | |
5923a5e7 | 1415 | { |
d53bb226 | 1416 | if (flag_var_tracking == 1 |
1417 | || flag_var_tracking_uninit == 1) | |
ad469377 | 1418 | { |
1419 | if (debug_info_level < DINFO_LEVEL_NORMAL) | |
c3ceba8e | 1420 | warning (0, "variable tracking requested, but useless unless " |
ad469377 | 1421 | "producing debug info"); |
1422 | else | |
c3ceba8e | 1423 | warning (0, "variable tracking requested, but not supported " |
ad469377 | 1424 | "by this debug format"); |
1425 | } | |
1426 | flag_var_tracking = 0; | |
d53bb226 | 1427 | flag_var_tracking_uninit = 0; |
5923a5e7 | 1428 | } |
1429 | ||
929d2a90 | 1430 | /* The debug hooks are used to implement -fdump-go-spec because it |
1431 | gives a simple and stable API for all the information we need to | |
1432 | dump. */ | |
1433 | if (flag_dump_go_spec != NULL) | |
1434 | debug_hooks = dump_go_spec_init (flag_dump_go_spec, debug_hooks); | |
1435 | ||
8f7630da | 1436 | /* If the user specifically requested variable tracking with tagging |
1437 | uninitialized variables, we need to turn on variable tracking. | |
1438 | (We already determined above that variable tracking is feasible.) */ | |
3e1cce93 | 1439 | if (flag_var_tracking_uninit == 1) |
8f7630da | 1440 | flag_var_tracking = 1; |
ad469377 | 1441 | |
472cd78a | 1442 | if (flag_var_tracking == AUTODETECT_VALUE) |
ad469377 | 1443 | flag_var_tracking = optimize >= 1; |
1444 | ||
3e1cce93 | 1445 | if (flag_var_tracking_uninit == AUTODETECT_VALUE) |
1446 | flag_var_tracking_uninit = flag_var_tracking; | |
1447 | ||
9845d120 | 1448 | if (flag_var_tracking_assignments == AUTODETECT_VALUE) |
8f7630da | 1449 | flag_var_tracking_assignments = flag_var_tracking |
1450 | && !(flag_selective_scheduling || flag_selective_scheduling2); | |
9845d120 | 1451 | |
1452 | if (flag_var_tracking_assignments_toggle) | |
1453 | flag_var_tracking_assignments = !flag_var_tracking_assignments; | |
1454 | ||
1455 | if (flag_var_tracking_assignments && !flag_var_tracking) | |
1456 | flag_var_tracking = flag_var_tracking_assignments = -1; | |
1457 | ||
8f7630da | 1458 | if (flag_var_tracking_assignments |
1459 | && (flag_selective_scheduling || flag_selective_scheduling2)) | |
1460 | warning (0, "var-tracking-assignments changes selective scheduling"); | |
1461 | ||
e6d0e152 | 1462 | if (flag_tree_cselim == AUTODETECT_VALUE) |
1463 | #ifdef HAVE_conditional_move | |
1464 | flag_tree_cselim = 1; | |
1465 | #else | |
1466 | flag_tree_cselim = 0; | |
1467 | #endif | |
1468 | ||
9ceb1c29 | 1469 | /* If auxiliary info generation is desired, open the output file. |
1470 | This goes in the same directory as the source file--unlike | |
1471 | all the other output files. */ | |
1472 | if (flag_gen_aux_info) | |
1473 | { | |
1474 | aux_info_file = fopen (aux_info_file_name, "w"); | |
1475 | if (aux_info_file == 0) | |
eb586f2c | 1476 | fatal_error ("can%'t open %s: %m", aux_info_file_name); |
9ceb1c29 | 1477 | } |
56a44361 | 1478 | |
218e3e4e | 1479 | if (!targetm_common.have_named_sections) |
3bcb26d1 | 1480 | { |
9ceb1c29 | 1481 | if (flag_function_sections) |
1482 | { | |
c3ceba8e | 1483 | warning (0, "-ffunction-sections not supported for this target"); |
9ceb1c29 | 1484 | flag_function_sections = 0; |
1485 | } | |
1486 | if (flag_data_sections) | |
1487 | { | |
c3ceba8e | 1488 | warning (0, "-fdata-sections not supported for this target"); |
9ceb1c29 | 1489 | flag_data_sections = 0; |
1490 | } | |
3bcb26d1 | 1491 | } |
9ceb1c29 | 1492 | |
ba38e12b | 1493 | #ifndef HAVE_prefetch |
cd459e62 | 1494 | if (flag_prefetch_loop_arrays > 0) |
ba38e12b | 1495 | { |
c3ceba8e | 1496 | warning (0, "-fprefetch-loop-arrays not supported for this target"); |
ba38e12b | 1497 | flag_prefetch_loop_arrays = 0; |
1498 | } | |
1499 | #else | |
cd459e62 | 1500 | if (flag_prefetch_loop_arrays > 0 && !HAVE_prefetch) |
ba38e12b | 1501 | { |
c3ceba8e | 1502 | warning (0, "-fprefetch-loop-arrays not supported for this target (try -march switches)"); |
ba38e12b | 1503 | flag_prefetch_loop_arrays = 0; |
1504 | } | |
1505 | #endif | |
1506 | ||
9544445b | 1507 | /* This combination of options isn't handled for i386 targets and doesn't |
1508 | make much sense anyway, so don't allow it. */ | |
cd459e62 | 1509 | if (flag_prefetch_loop_arrays > 0 && optimize_size) |
9544445b | 1510 | { |
c3ceba8e | 1511 | warning (0, "-fprefetch-loop-arrays is not supported with -Os"); |
9544445b | 1512 | flag_prefetch_loop_arrays = 0; |
1513 | } | |
1514 | ||
4ee9c684 | 1515 | /* The presence of IEEE signaling NaNs, implies all math can trap. */ |
1516 | if (flag_signaling_nans) | |
1517 | flag_trapping_math = 1; | |
45b9d334 | 1518 | |
26c166eb | 1519 | /* We cannot reassociate if we want traps or signed zeros. */ |
4a2a1c11 | 1520 | if (flag_associative_math && (flag_trapping_math || flag_signed_zeros)) |
1521 | { | |
1522 | warning (0, "-fassociative-math disabled; other options take precedence"); | |
1523 | flag_associative_math = 0; | |
1524 | } | |
1525 | ||
45b9d334 | 1526 | /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */ |
1527 | if (flag_cx_limited_range) | |
1528 | flag_complex_method = 0; | |
f1a0edff | 1529 | |
608256a0 | 1530 | /* With -fcx-fortran-rules, we do something in-between cheap and C99. */ |
1531 | if (flag_cx_fortran_rules) | |
1532 | flag_complex_method = 1; | |
1533 | ||
f1a0edff | 1534 | /* Targets must be able to place spill slots at lower addresses. If the |
1535 | target already uses a soft frame pointer, the transition is trivial. */ | |
3837145e | 1536 | if (!FRAME_GROWS_DOWNWARD && flag_stack_protect) |
f1a0edff | 1537 | { |
1538 | warning (0, "-fstack-protector not supported for this target"); | |
1539 | flag_stack_protect = 0; | |
1540 | } | |
f1a0edff | 1541 | if (!flag_stack_protect) |
1542 | warn_stack_protect = 0; | |
77ff57c8 | 1543 | |
7ad5fd20 | 1544 | /* Address Sanitizer needs porting to each target architecture. */ |
9e46467d | 1545 | if ((flag_sanitize & SANITIZE_ADDRESS) |
3c919612 | 1546 | && (targetm.asan_shadow_offset == NULL |
1547 | || !FRAME_GROWS_DOWNWARD)) | |
7ad5fd20 | 1548 | { |
5ab1f49e | 1549 | warning (0, "-fsanitize=address not supported for this target"); |
9e46467d | 1550 | flag_sanitize &= ~SANITIZE_ADDRESS; |
7ad5fd20 | 1551 | } |
1552 | ||
68ebb06f | 1553 | /* Enable -Werror=coverage-mismatch when -Werror and -Wno-error |
1554 | have not been set. */ | |
1555 | if (!global_options_set.x_warnings_are_errors | |
1556 | && warn_coverage_mismatch | |
1557 | && (global_dc->classify_diagnostic[OPT_Wcoverage_mismatch] == | |
1558 | DK_UNSPECIFIED)) | |
1559 | diagnostic_classify_diagnostic (global_dc, OPT_Wcoverage_mismatch, | |
1560 | DK_ERROR, UNKNOWN_LOCATION); | |
1561 | ||
1da23459 | 1562 | /* Save the current optimization options. */ |
1563 | optimization_default_node = build_optimization_node (); | |
1564 | optimization_current_node = optimization_default_node; | |
3bcb26d1 | 1565 | } |
03414cfb | 1566 | |
6d8b68a3 | 1567 | /* This function can be called multiple times to reinitialize the compiler |
1568 | back end when register classes or instruction sets have changed, | |
1569 | before each function. */ | |
1570 | static void | |
1571 | backend_init_target (void) | |
1572 | { | |
1573 | /* Initialize alignment variables. */ | |
1574 | init_alignments (); | |
1575 | ||
1576 | /* This reinitializes hard_frame_pointer, and calls init_reg_modes_target() | |
1577 | to initialize reg_raw_mode[]. */ | |
1578 | init_emit_regs (); | |
1579 | ||
1580 | /* This invokes target hooks to set fixed_reg[] etc, which is | |
1581 | mode-dependent. */ | |
1582 | init_regs (); | |
1583 | ||
1584 | /* This depends on stack_pointer_rtx. */ | |
1585 | init_fake_stack_mems (); | |
1586 | ||
1587 | /* Sets static_base_value[HARD_FRAME_POINTER_REGNUM], which is | |
1588 | mode-dependent. */ | |
1589 | init_alias_target (); | |
1590 | ||
1591 | /* Depends on HARD_FRAME_POINTER_REGNUM. */ | |
1592 | init_reload (); | |
1593 | ||
1594 | /* The following initialization functions need to generate rtl, so | |
1595 | provide a dummy function context for them. */ | |
1596 | init_dummy_function_start (); | |
1597 | ||
1598 | /* rtx_cost is mode-dependent, so cached values need to be recomputed | |
1599 | on a mode change. */ | |
1600 | init_expmed (); | |
c7944dce | 1601 | init_lower_subreg (); |
6d8b68a3 | 1602 | |
1603 | /* We may need to recompute regno_save_code[] and regno_restore_code[] | |
1604 | after a mode change as well. */ | |
4e4c89ec | 1605 | caller_save_initialized_p = false; |
1606 | ||
6d8b68a3 | 1607 | expand_dummy_function_end (); |
1608 | } | |
1609 | ||
1610 | /* Initialize the compiler back end. This function is called only once, | |
1611 | when starting the compiler. */ | |
9ceb1c29 | 1612 | static void |
7237deda | 1613 | backend_init (void) |
9ceb1c29 | 1614 | { |
01703575 | 1615 | init_emit_once (); |
c235b58a | 1616 | |
a87cf6e5 | 1617 | init_rtlanal (); |
bc8bb825 | 1618 | init_inline_once (); |
9ceb1c29 | 1619 | init_varasm_once (); |
7fecc8b3 | 1620 | save_register_info (); |
9ceb1c29 | 1621 | |
6d8b68a3 | 1622 | /* Initialize the target-specific back end pieces. */ |
47dd2e78 | 1623 | ira_init_once (); |
6d8b68a3 | 1624 | backend_init_target (); |
1625 | } | |
1626 | ||
c6418a4e | 1627 | /* Initialize excess precision settings. */ |
1628 | static void | |
1629 | init_excess_precision (void) | |
1630 | { | |
1631 | /* Adjust excess precision handling based on the target options. If | |
1632 | the front end cannot handle it, flag_excess_precision_cmdline | |
1633 | will already have been set accordingly in the post_options | |
1634 | hook. */ | |
1635 | gcc_assert (flag_excess_precision_cmdline != EXCESS_PRECISION_DEFAULT); | |
1636 | flag_excess_precision = flag_excess_precision_cmdline; | |
1637 | if (flag_unsafe_math_optimizations) | |
1638 | flag_excess_precision = EXCESS_PRECISION_FAST; | |
1639 | if (flag_excess_precision == EXCESS_PRECISION_STANDARD) | |
1640 | { | |
1641 | int flt_eval_method = TARGET_FLT_EVAL_METHOD; | |
1642 | switch (flt_eval_method) | |
1643 | { | |
1644 | case -1: | |
1645 | case 0: | |
1646 | /* Either the target acts unpredictably (-1) or has all the | |
1647 | operations required not to have excess precision (0). */ | |
1648 | flag_excess_precision = EXCESS_PRECISION_FAST; | |
1649 | break; | |
1650 | case 1: | |
1651 | case 2: | |
1652 | /* In these cases, predictable excess precision makes | |
1653 | sense. */ | |
1654 | break; | |
1655 | default: | |
1656 | /* Any other implementation-defined FLT_EVAL_METHOD values | |
1657 | require the compiler to handle the associated excess | |
1658 | precision rules in excess_precision_type. */ | |
1659 | gcc_unreachable (); | |
1660 | } | |
1661 | } | |
1662 | } | |
1663 | ||
6d8b68a3 | 1664 | /* Initialize things that are both lang-dependent and target-dependent. |
1665 | This function can be called more than once if target parameters change. */ | |
1666 | static void | |
1667 | lang_dependent_init_target (void) | |
1668 | { | |
c6418a4e | 1669 | /* This determines excess precision settings. */ |
1670 | init_excess_precision (); | |
1671 | ||
6d8b68a3 | 1672 | /* This creates various _DECL nodes, so needs to be called after the |
1673 | front end is initialized. It also depends on the HAVE_xxx macros | |
1674 | generated from the target machine description. */ | |
1675 | init_optabs (); | |
1676 | ||
9ceb1c29 | 1677 | /* The following initialization functions need to generate rtl, so |
1678 | provide a dummy function context for them. */ | |
1679 | init_dummy_function_start (); | |
6d8b68a3 | 1680 | |
1681 | /* Do the target-specific parts of expr initialization. */ | |
1682 | init_expr_target (); | |
1683 | ||
47dd2e78 | 1684 | /* Although the actions of these functions are language-independent, |
1685 | they use optabs, so we cannot call them from backend_init. */ | |
6d8b68a3 | 1686 | init_set_costs (); |
47dd2e78 | 1687 | ira_init (); |
6d8b68a3 | 1688 | |
9ceb1c29 | 1689 | expand_dummy_function_end (); |
1690 | } | |
03414cfb | 1691 | |
f712a0dc | 1692 | /* Language-dependent initialization. Returns nonzero on success. */ |
cdc9fa3e | 1693 | static int |
7237deda | 1694 | lang_dependent_init (const char *name) |
3bcb26d1 | 1695 | { |
fdfe4b3f | 1696 | location_t save_loc = input_location; |
9ceb1c29 | 1697 | if (dump_base_name == 0) |
0f9005dd | 1698 | dump_base_name = name && name[0] ? name : "gccdump"; |
da980a43 | 1699 | |
03bde601 | 1700 | /* Other front-end initialization. */ |
fdfe4b3f | 1701 | input_location = BUILTINS_LOCATION; |
dc24ddbd | 1702 | if (lang_hooks.init () == 0) |
cdc9fa3e | 1703 | return 0; |
fdfe4b3f | 1704 | input_location = save_loc; |
3bcb26d1 | 1705 | |
f463da94 | 1706 | if (!flag_wpa) |
1707 | { | |
1708 | init_asm_output (name); | |
e87e2aa9 | 1709 | |
f463da94 | 1710 | /* If stack usage information is desired, open the output file. */ |
1711 | if (flag_stack_usage) | |
1712 | stack_usage_file = open_auxiliary_file ("su"); | |
1713 | } | |
990495a7 | 1714 | |
6d8b68a3 | 1715 | /* This creates various _DECL nodes, so needs to be called after the |
9ceb1c29 | 1716 | front end is initialized. */ |
1717 | init_eh (); | |
7a9ae52e | 1718 | |
6d8b68a3 | 1719 | /* Do the target-specific parts of the initialization. */ |
1720 | lang_dependent_init_target (); | |
e87e2aa9 | 1721 | |
f463da94 | 1722 | if (!flag_wpa) |
1723 | { | |
1724 | /* If dbx symbol table desired, initialize writing it and output the | |
1725 | predefined types. */ | |
1726 | timevar_push (TV_SYMOUT); | |
3bcb26d1 | 1727 | |
f463da94 | 1728 | /* Now we have the correct original filename, we can initialize |
1729 | debug output. */ | |
1730 | (*debug_hooks->init) (name); | |
3bcb26d1 | 1731 | |
f463da94 | 1732 | timevar_pop (TV_SYMOUT); |
1733 | } | |
cdc9fa3e | 1734 | |
1735 | return 1; | |
1736 | } | |
03414cfb | 1737 | |
6d8b68a3 | 1738 | |
1739 | /* Reinitialize everything when target parameters, such as register usage, | |
1740 | have changed. */ | |
1741 | void | |
1742 | target_reinit (void) | |
1743 | { | |
7b29dd2f | 1744 | struct rtl_data saved_x_rtl; |
1745 | rtx *saved_regno_reg_rtx; | |
1746 | ||
1747 | /* Save *crtl and regno_reg_rtx around the reinitialization | |
1748 | to allow target_reinit being called even after prepare_function_start. */ | |
1749 | saved_regno_reg_rtx = regno_reg_rtx; | |
1750 | if (saved_regno_reg_rtx) | |
1751 | { | |
1752 | saved_x_rtl = *crtl; | |
1753 | memset (crtl, '\0', sizeof (*crtl)); | |
1754 | regno_reg_rtx = NULL; | |
1755 | } | |
1756 | ||
c7684b8e | 1757 | /* Reinitialize RTL backend. */ |
6d8b68a3 | 1758 | backend_init_target (); |
1759 | ||
1760 | /* Reinitialize lang-dependent parts. */ | |
1761 | lang_dependent_init_target (); | |
7b29dd2f | 1762 | |
1763 | /* And restore it at the end, as free_after_compilation from | |
1764 | expand_dummy_function_end clears it. */ | |
1765 | if (saved_regno_reg_rtx) | |
1766 | { | |
1767 | *crtl = saved_x_rtl; | |
1768 | regno_reg_rtx = saved_regno_reg_rtx; | |
1769 | saved_regno_reg_rtx = NULL; | |
1770 | } | |
6d8b68a3 | 1771 | } |
1772 | ||
51949610 | 1773 | void |
1774 | dump_memory_report (bool final) | |
1775 | { | |
e77b8253 | 1776 | dump_line_table_statistics (); |
51949610 | 1777 | ggc_print_statistics (); |
1778 | stringpool_statistics (); | |
1779 | dump_tree_statistics (); | |
75a70cf9 | 1780 | dump_gimple_statistics (); |
51949610 | 1781 | dump_rtx_statistics (); |
51949610 | 1782 | dump_alloc_pool_statistics (); |
1783 | dump_bitmap_statistics (); | |
eec2888b | 1784 | dump_vec_loc_statistics (); |
51949610 | 1785 | dump_ggc_loc_statistics (final); |
dd277d48 | 1786 | dump_alias_stats (stderr); |
1787 | dump_pta_stats (stderr); | |
51949610 | 1788 | } |
1789 | ||
cdc9fa3e | 1790 | /* Clean up: close opened files, etc. */ |
1791 | ||
1792 | static void | |
f666c964 | 1793 | finalize (bool no_backend) |
cdc9fa3e | 1794 | { |
1795 | /* Close the dump files. */ | |
1796 | if (flag_gen_aux_info) | |
1797 | { | |
1798 | fclose (aux_info_file); | |
852f689e | 1799 | if (seen_error ()) |
cdc9fa3e | 1800 | unlink (aux_info_file_name); |
1801 | } | |
1802 | ||
1803 | /* Close non-debugging input and output files. Take special care to note | |
1804 | whether fclose returns an error, since the pages might still be on the | |
1805 | buffer chain while the file is open. */ | |
1806 | ||
1807 | if (asm_out_file) | |
1808 | { | |
1809 | if (ferror (asm_out_file) != 0) | |
d07c9932 | 1810 | fatal_error ("error writing to %s: %m", asm_file_name); |
cdc9fa3e | 1811 | if (fclose (asm_out_file) != 0) |
d07c9932 | 1812 | fatal_error ("error closing %s: %m", asm_file_name); |
cdc9fa3e | 1813 | } |
1814 | ||
990495a7 | 1815 | if (stack_usage_file) |
1816 | fclose (stack_usage_file); | |
1817 | ||
f666c964 | 1818 | if (!no_backend) |
1819 | { | |
1820 | statistics_fini (); | |
1821 | ||
bcfddb5b | 1822 | g->get_passes ()->finish_optimization_passes (); |
cdc9fa3e | 1823 | |
f666c964 | 1824 | ira_finish_once (); |
1825 | } | |
47dd2e78 | 1826 | |
cdc9fa3e | 1827 | if (mem_report) |
51949610 | 1828 | dump_memory_report (true); |
cdc9fa3e | 1829 | |
2fc0fcf7 | 1830 | if (profile_report) |
5168ef25 | 1831 | dump_profile_report (); |
1832 | ||
cdc9fa3e | 1833 | /* Language-specific end of compilation actions. */ |
dc24ddbd | 1834 | lang_hooks.finish (); |
9ceb1c29 | 1835 | } |
03414cfb | 1836 | |
435fb09b | 1837 | /* Initialize the compiler, and compile the input file. */ |
1838 | static void | |
7237deda | 1839 | do_compile (void) |
9ceb1c29 | 1840 | { |
9a35b648 | 1841 | /* Initialize timing first. The C front ends read the main file in |
1842 | the post_options hook, and C++ does file timings. */ | |
1843 | if (time_report || !quiet_flag || flag_detailed_statistics) | |
1844 | timevar_init (); | |
cd7fc18a | 1845 | timevar_start (TV_TOTAL); |
1846 | ||
9a35b648 | 1847 | process_options (); |
1848 | ||
1849 | /* Don't do any more if an error has already occurred. */ | |
852f689e | 1850 | if (!seen_error ()) |
9a35b648 | 1851 | { |
6198e8f6 | 1852 | timevar_start (TV_PHASE_SETUP); |
1853 | ||
2b4ca870 | 1854 | /* This must be run always, because it is needed to compute the FP |
1855 | predefined macros, such as __LDBL_MAX__, for targets using non | |
1856 | default FP formats. */ | |
1857 | init_adjust_machine_modes (); | |
1858 | ||
9a35b648 | 1859 | /* Set up the back-end if requested. */ |
1860 | if (!no_backend) | |
1861 | backend_init (); | |
9ceb1c29 | 1862 | |
9a35b648 | 1863 | /* Language-dependent initialization. Returns true on success. */ |
3272db82 | 1864 | if (lang_dependent_init (main_input_filename)) |
6198e8f6 | 1865 | { |
1866 | /* Initialize yet another pass. */ | |
1867 | ||
1868 | ggc_protect_identifiers = true; | |
1869 | ||
1870 | init_cgraph (); | |
1871 | init_final (main_input_filename); | |
1872 | coverage_init (aux_base_name); | |
1873 | statistics_init (); | |
1874 | invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL); | |
1875 | ||
1876 | timevar_stop (TV_PHASE_SETUP); | |
1877 | ||
1878 | compile_file (); | |
1879 | } | |
1880 | else | |
1881 | { | |
1882 | timevar_stop (TV_PHASE_SETUP); | |
1883 | } | |
1884 | ||
1885 | timevar_start (TV_PHASE_FINALIZE); | |
f79b6507 | 1886 | |
f666c964 | 1887 | finalize (no_backend); |
6198e8f6 | 1888 | |
1889 | timevar_stop (TV_PHASE_FINALIZE); | |
9a35b648 | 1890 | } |
9ceb1c29 | 1891 | |
1892 | /* Stop timing and print the times. */ | |
1893 | timevar_stop (TV_TOTAL); | |
1894 | timevar_print (stderr); | |
435fb09b | 1895 | } |
03414cfb | 1896 | |
435fb09b | 1897 | /* Entry point of cc1, cc1plus, jc1, f771, etc. |
435fb09b | 1898 | Exit code is FATAL_EXIT_CODE if can't open files or if there were |
1899 | any errors, or SUCCESS_EXIT_CODE if compilation succeeded. | |
1900 | ||
1901 | It is not safe to call this function more than once. */ | |
1902 | ||
1903 | int | |
46782931 | 1904 | toplev_main (int argc, char **argv) |
435fb09b | 1905 | { |
00dacc40 | 1906 | /* Parsing and gimplification sometimes need quite large stack. |
1907 | Increase stack size limits if possible. */ | |
1908 | stack_limit_increase (64 * 1024 * 1024); | |
1909 | ||
46782931 | 1910 | expandargv (&argc, &argv); |
1911 | ||
435fb09b | 1912 | /* Initialization of GCC's environment, and diagnostics. */ |
b1157638 | 1913 | general_init (argv[0]); |
435fb09b | 1914 | |
f3f006ad | 1915 | /* One-off initialization of options that does not need to be |
1916 | repeated when options are added for particular functions. */ | |
1917 | init_options_once (); | |
1918 | ||
1919 | /* Initialize global options structures; this must be repeated for | |
1920 | each structure used for parsing options. */ | |
1921 | init_options_struct (&global_options, &global_options_set); | |
1922 | lang_hooks.init_options_struct (&global_options); | |
1923 | ||
1924 | /* Convert the options to an array. */ | |
1925 | decode_cmdline_options_to_array_default_mask (argc, | |
1926 | CONST_CAST2 (const char **, | |
1927 | char **, argv), | |
1928 | &save_decoded_options, | |
1929 | &save_decoded_options_count); | |
1930 | ||
1931 | /* Perform language-specific options initialization. */ | |
1932 | lang_hooks.init_options (save_decoded_options_count, save_decoded_options); | |
1933 | ||
435fb09b | 1934 | /* Parse the options and do minimal processing; basically just |
1935 | enough to default flags appropriately. */ | |
f3f006ad | 1936 | decode_options (&global_options, &global_options_set, |
6bd9d862 | 1937 | save_decoded_options, save_decoded_options_count, |
3c6c0e40 | 1938 | UNKNOWN_LOCATION, global_dc); |
435fb09b | 1939 | |
f0da0668 | 1940 | handle_common_deferred_options (); |
1941 | ||
b6c1bd72 | 1942 | init_local_tick (); |
b80f1d67 | 1943 | |
e16288b4 | 1944 | initialize_plugins (); |
1945 | ||
1946 | if (version_flag) | |
1947 | print_version (stderr, ""); | |
1948 | ||
2dfeb300 | 1949 | if (help_flag) |
1950 | print_plugins_help (stderr, ""); | |
1951 | ||
435fb09b | 1952 | /* Exit early if we can (e.g. -help). */ |
5934ea7a | 1953 | if (!exit_after_options) |
9a35b648 | 1954 | do_compile (); |
9ceb1c29 | 1955 | |
d9d1b0a4 | 1956 | if (warningcount || errorcount || werrorcount) |
ddb48b82 | 1957 | print_ignored_options (); |
543725f3 | 1958 | diagnostic_finish (global_dc); |
ddb48b82 | 1959 | |
9227b6fc | 1960 | /* Invoke registered plugin callbacks if any. */ |
1961 | invoke_plugin_callbacks (PLUGIN_FINISH, NULL); | |
1962 | ||
e16288b4 | 1963 | finalize_plugins (); |
5169661d | 1964 | location_adhoc_data_fini (line_table); |
d9d1b0a4 | 1965 | if (seen_error () || werrorcount) |
9ceb1c29 | 1966 | return (FATAL_EXIT_CODE); |
1967 | ||
1968 | return (SUCCESS_EXIT_CODE); | |
3bcb26d1 | 1969 | } |