diff options
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r-- | gcc/toplev.c | 882 |
1 files changed, 473 insertions, 409 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c index 5825c554b64..3db578f6ffb 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -161,13 +161,20 @@ extern char **environ; extern int size_directive_output; extern tree last_assemble_variable_decl; +static void general_init PARAMS ((char *)); +static void parse_options_and_default_flags PARAMS ((int, char **)); +static void process_options PARAMS ((void)); +static void lang_independent_init PARAMS ((void)); +static void lang_dependent_init PARAMS ((const char *)); +static void init_asm_output PARAMS ((const char *)); + static void set_target_switch PARAMS ((const char *)); static const char *decl_name PARAMS ((tree, int)); static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN; static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN; static void set_float_handler PARAMS ((jmp_buf)); -static void compile_file PARAMS ((const char *)); +static void compile_file PARAMS ((void)); static void display_help PARAMS ((void)); static void display_target_options PARAMS ((void)); @@ -232,7 +239,7 @@ extern int target_flags; /* Debug hooks - dependent upon command line options. */ -struct gcc_debug_hooks *debug_hooks; +struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; /* Describes a dump file. */ @@ -1438,23 +1445,6 @@ int warn_unused_parameter; int warn_unused_variable; int warn_unused_value; -void -set_Wunused (setting) - int setting; -{ - warn_unused_function = setting; - warn_unused_label = setting; - /* Unused function parameter warnings are reported when either ``-W - -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate - -Wunused by setting WARN_UNUSED_PARAMETER to -1. */ - if (!setting) - warn_unused_parameter = 0; - else if (!warn_unused_parameter) - warn_unused_parameter = -1; - warn_unused_variable = setting; - warn_unused_value = setting; -} - /* Nonzero to warn about code which is never reached. */ int warn_notreached; @@ -1556,6 +1546,23 @@ lang_independent_options W_options[] = N_("Warn about functions which might be candidates for attribute noreturn") } }; +void +set_Wunused (setting) + int setting; +{ + warn_unused_function = setting; + warn_unused_label = setting; + /* Unused function parameter warnings are reported when either ``-W + -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate + -Wunused by setting WARN_UNUSED_PARAMETER to -1. */ + if (!setting) + warn_unused_parameter = 0; + else if (!warn_unused_parameter) + warn_unused_parameter = -1; + warn_unused_variable = setting; + warn_unused_value = setting; +} + /* The following routines are useful in setting all the flags that -ffast-math and -fno-fast-math imply. */ @@ -2132,203 +2139,14 @@ pop_srcloc () lineno = input_file_stack->line; } -/* Compile an entire translation unit, whose primary source file is - named NAME. Write a file of assembly output and various debugging - dumps. */ +/* Compile an entire translation unit. Write a file of assembly + output and various debugging dumps. */ static void -compile_file (name) - const char *name; +compile_file () { tree globals; - int name_specified = name != 0; - - if (dump_base_name == 0) - dump_base_name = name ? name : "gccdump"; - - if (! quiet_flag) - time_report = 1; - - /* Start timing total execution time. */ - - init_timevar (); - timevar_start (TV_TOTAL); - - /* Open assembly code output file. Do this even if -fsyntax-only is on, - because then the driver will have provided the name of a temporary - file or bit bucket for us. */ - - if (! name_specified && asm_file_name == 0) - asm_out_file = stdout; - else - { - if (asm_file_name == 0) - { - int len = strlen (dump_base_name); - char *dumpname = (char *) xmalloc (len + 6); - memcpy (dumpname, dump_base_name, len + 1); - strip_off_ending (dumpname, len); - strcat (dumpname, ".s"); - asm_file_name = dumpname; - } - if (!strcmp (asm_file_name, "-")) - asm_out_file = stdout; - else - asm_out_file = fopen (asm_file_name, "w"); - if (asm_out_file == 0) - fatal_io_error ("can't open %s for writing", asm_file_name); - } - - /* Initialize data in various passes. */ - - init_obstacks (); - name = init_parse (name); - init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL - || debug_info_level == DINFO_LEVEL_VERBOSE - || flag_test_coverage - || warn_notreached); - init_regs (); - init_alias_once (); - init_decl_processing (); - init_eh (); - init_optabs (); - init_stmt (); - init_loop (); - init_reload (); - init_function_once (); - init_stor_layout_once (); - init_varasm_once (); - init_EXPR_INSN_LIST_cache (); - - /* The following initialization functions need to generate rtl, so - provide a dummy function context for them. */ - init_dummy_function_start (); - init_expmed (); - init_expr_once (); - if (flag_caller_saves) - init_caller_save (); - expand_dummy_function_end (); - - /* If auxiliary info generation is desired, open the output file. - This goes in the same directory as the source file--unlike - all the other output files. */ - if (flag_gen_aux_info) - { - aux_info_file = fopen (aux_info_file_name, "w"); - if (aux_info_file == 0) - fatal_io_error ("can't open %s", aux_info_file_name); - } - -#ifdef IO_BUFFER_SIZE - setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), - _IOFBF, IO_BUFFER_SIZE); -#endif - - if (name != 0) - name = ggc_strdup (name); - - input_filename = name; - - /* Put an entry on the input file stack for the main input file. */ - push_srcloc (input_filename, 0); - - /* Perform language-specific initialization. - This may set main_input_filename. */ - (*lang_hooks.init) (); - - /* If the input doesn't start with a #line, use the input name - as the official input file name. */ - if (main_input_filename == 0) - main_input_filename = name; - - if (flag_syntax_only) - { - write_symbols = NO_DEBUG; - profile_flag = 0; - profile_block_flag = 0; - } - else - { -#ifdef ASM_FILE_START - ASM_FILE_START (asm_out_file); -#endif - -#ifdef ASM_COMMENT_START - if (flag_verbose_asm) - { - /* Print the list of options in effect. */ - print_version (asm_out_file, ASM_COMMENT_START); - print_switch_values (asm_out_file, 0, MAX_LINE, - ASM_COMMENT_START, " ", "\n"); - /* Add a blank line here so it appears in assembler output but not - screen output. */ - fprintf (asm_out_file, "\n"); - } -#endif - } /* ! flag_syntax_only */ - - /* Set up the debug hooks based on write_symbols. Default to doing - nothing. */ - debug_hooks = &do_nothing_debug_hooks; -#if defined(DBX_DEBUGGING_INFO) - if (write_symbols == DBX_DEBUG) - debug_hooks = &dbx_debug_hooks; -#endif -#if defined(XCOFF_DEBUGGING_INFO) - if (write_symbols == XCOFF_DEBUG) - debug_hooks = &xcoff_debug_hooks; -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - debug_hooks = &sdb_debug_hooks; -#endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - debug_hooks = &dwarf_debug_hooks; -#endif -#ifdef DWARF2_DEBUGGING_INFO - if (write_symbols == DWARF2_DEBUG) - debug_hooks = &dwarf2_debug_hooks; -#endif - - if (! targetm.have_named_sections) - { - if (flag_function_sections) - { - warning ("-ffunction-sections not supported for this target."); - flag_function_sections = 0; - } - if (flag_data_sections) - { - warning ("-fdata-sections not supported for this target."); - flag_data_sections = 0; - } - } - - if (flag_function_sections - && (profile_flag || profile_block_flag)) - { - warning ("-ffunction-sections disabled; it makes profiling impossible."); - flag_function_sections = 0; - } - -#ifndef OBJECT_FORMAT_ELF - if (flag_function_sections && write_symbols != NO_DEBUG) - warning ("-ffunction-sections may affect debugging on some targets."); -#endif - - /* If dbx symbol table desired, initialize writing it - and output the predefined types. */ - timevar_push (TV_SYMOUT); -#ifdef DWARF2_UNWIND_INFO - if (dwarf2out_do_frame ()) - dwarf2out_frame_init (); -#endif - - (*debug_hooks->init) (main_input_filename); - timevar_pop (TV_SYMOUT); - /* Initialize yet another pass. */ init_final (main_input_filename); @@ -2491,13 +2309,6 @@ compile_file (name) /* Free up memory for the benefit of leak detectors. */ free_reg_info (); - - /* Stop timing total execution time. */ - timevar_stop (TV_TOTAL); - - /* Print the times. */ - - timevar_print (stderr); } /* This is called from various places for FUNCTION_DECL, VAR_DECL, @@ -4591,27 +4402,241 @@ independent_decode_option (argc, argv) return 1; } -/* Entry point of cc1, cc1plus, jc1, f771, etc. - Decode command args, then call compile_file. - Exit code is FATAL_EXIT_CODE if can't open files or if there were - any errors, or SUCCESS_EXIT_CODE if compilation succeeded. +/* Decode -m switches. */ +/* Decode the switch -mNAME. */ - It is not safe to call this function more than once. */ +static void +set_target_switch (name) + const char *name; +{ + size_t j; + int valid_target_option = 0; -int -toplev_main (argc, argv) - int argc; - char **argv; + for (j = 0; j < ARRAY_SIZE (target_switches); j++) + if (!strcmp (target_switches[j].name, name)) + { + if (target_switches[j].value < 0) + target_flags &= ~-target_switches[j].value; + else + target_flags |= target_switches[j].value; + valid_target_option = 1; + } + +#ifdef TARGET_OPTIONS + if (!valid_target_option) + for (j = 0; j < ARRAY_SIZE (target_options); j++) + { + int len = strlen (target_options[j].prefix); + if (!strncmp (target_options[j].prefix, name, len)) + { + *target_options[j].variable = name + len; + valid_target_option = 1; + } + } +#endif + + if (!valid_target_option) + error ("Invalid option `%s'", name); +} + +/* Print version information to FILE. + Each line begins with INDENT (for the case where FILE is the + assembler output file). */ + +static void +print_version (file, indent) + FILE *file; + const char *indent; { - int i; - char *p; +#ifndef __VERSION__ +#define __VERSION__ "[?]" +#endif + fnotice (file, +#ifdef __GNUC__ + "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n" +#else + "%s%s%s version %s (%s) compiled by CC.\n" +#endif + , indent, *indent != 0 ? " " : "", + lang_hooks.name, version_string, TARGET_NAME, + indent, __VERSION__); +} - /* save in case md file wants to emit args as a comment. */ - save_argc = argc; - save_argv = argv; +/* Print an option value and return the adjusted position in the line. + ??? We don't handle error returns from fprintf (disk full); presumably + other code will catch a disk full though. */ + +static int +print_single_switch (file, pos, max, indent, sep, term, type, name) + FILE *file; + int pos, max; + const char *indent, *sep, *term, *type, *name; +{ + /* The ultrix fprintf returns 0 on success, so compute the result we want + here since we need it for the following test. */ + int len = strlen (sep) + strlen (type) + strlen (name); + + if (pos != 0 + && pos + len > max) + { + fprintf (file, "%s", term); + pos = 0; + } + if (pos == 0) + { + fprintf (file, "%s", indent); + pos = strlen (indent); + } + fprintf (file, "%s%s%s", sep, type, name); + pos += len; + return pos; +} + +/* Print active target switches to FILE. + POS is the current cursor position and MAX is the size of a "line". + Each line begins with INDENT and ends with TERM. + Each switch is separated from the next by SEP. */ + +static void +print_switch_values (file, pos, max, indent, sep, term) + FILE *file; + int pos, max; + const char *indent, *sep, *term; +{ + size_t j; + char **p; + + /* Print the options as passed. */ + + pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, + _("options passed: "), ""); + + for (p = &save_argv[1]; *p != NULL; p++) + if (**p == '-') + { + /* Ignore these. */ + if (strcmp (*p, "-o") == 0) + { + if (p[1] != NULL) + p++; + continue; + } + if (strcmp (*p, "-quiet") == 0) + continue; + if (strcmp (*p, "-version") == 0) + continue; + if ((*p)[1] == 'd') + continue; + + pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); + } + if (pos > 0) + fprintf (file, "%s", term); + + /* Print the -f and -m options that have been enabled. + We don't handle language specific options but printing argv + should suffice. */ + + pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, + _("options enabled: "), ""); + + for (j = 0; j < ARRAY_SIZE (f_options); j++) + if (*f_options[j].variable == f_options[j].on_value) + pos = print_single_switch (file, pos, max, indent, sep, term, + "-f", f_options[j].string); + + /* Print target specific options. */ + + for (j = 0; j < ARRAY_SIZE (target_switches); j++) + if (target_switches[j].name[0] != '\0' + && target_switches[j].value > 0 + && ((target_switches[j].value & target_flags) + == target_switches[j].value)) + { + pos = print_single_switch (file, pos, max, indent, sep, term, + "-m", target_switches[j].name); + } + +#ifdef TARGET_OPTIONS + for (j = 0; j < ARRAY_SIZE (target_options); j++) + if (*target_options[j].variable != NULL) + { + char prefix[256]; + sprintf (prefix, "-m%s", target_options[j].prefix); + pos = print_single_switch (file, pos, max, indent, sep, term, + prefix, *target_options[j].variable); + } +#endif + + fprintf (file, "%s", term); +} + +/* Open assembly code output file. Do this even if -fsyntax-only is + on, because then the driver will have provided the name of a + temporary file or bit bucket for us. NAME is the file specified on + the command line, possibly NULL. */ +static void +init_asm_output (name) + const char *name; +{ + if (name == NULL && asm_file_name == 0) + asm_out_file = stdout; + else + { + if (asm_file_name == 0) + { + int len = strlen (dump_base_name); + char *dumpname = (char *) xmalloc (len + 6); + memcpy (dumpname, dump_base_name, len + 1); + strip_off_ending (dumpname, len); + strcat (dumpname, ".s"); + asm_file_name = dumpname; + } + if (!strcmp (asm_file_name, "-")) + asm_out_file = stdout; + else + asm_out_file = fopen (asm_file_name, "w"); + if (asm_out_file == 0) + fatal_io_error ("can't open %s for writing", asm_file_name); + } + +#ifdef IO_BUFFER_SIZE + setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), + _IOFBF, IO_BUFFER_SIZE); +#endif + + if (!flag_syntax_only) + { +#ifdef ASM_FILE_START + ASM_FILE_START (asm_out_file); +#endif + +#ifdef ASM_COMMENT_START + if (flag_verbose_asm) + { + /* Print the list of options in effect. */ + print_version (asm_out_file, ASM_COMMENT_START); + print_switch_values (asm_out_file, 0, MAX_LINE, + ASM_COMMENT_START, " ", "\n"); + /* Add a blank line here so it appears in assembler output but not + screen output. */ + fprintf (asm_out_file, "\n"); + } +#endif + } +} + +/* Initialization of the front end environment, before command line + options are parsed. Signal handlers, internationalization etc. + ARGV0 is main's argv[0]. */ +static void +general_init (argv0) + char *argv0; +{ + char *p; - p = argv[0] + strlen (argv[0]); - while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) + p = argv0 + strlen (argv0); + while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) --p; progname = p; @@ -4640,29 +4665,28 @@ toplev_main (argc, argv) signal (SIGIOT, crash_signal); #endif - decl_printable_name = decl_name; - lang_expand_expr = (lang_expand_expr_t) do_abort; - - /* Initialize whether `char' is signed. */ - flag_signed_char = DEFAULT_SIGNED_CHAR; -#ifdef DEFAULT_SHORT_ENUMS - /* Initialize how much space enums occupy, by default. */ - flag_short_enums = DEFAULT_SHORT_ENUMS; -#endif - - tree_code_length[(int) IDENTIFIER_NODE] - = ((lang_hooks.identifier_size - sizeof (struct tree_common)) - / sizeof (tree)); + /* Initialize the diagnostics reporting machinery, so option parsing + can give warnings and errors. */ + diagnostic_initialize (global_dc); +} + +/* Parse command line options and set default flag values, called + after language-independent option-independent intialization. Do + minimal options processing. Outputting diagnostics is OK, but GC + and identifier hashtables etc. are not initialized yet. */ +static void +parse_options_and_default_flags (argc, argv) + int argc; + char **argv; +{ + int i; - /* Initialize the garbage-collector. */ - init_ggc (); - init_stringpool (); - ggc_add_rtx_root (&stack_limit_rtx, 1); - ggc_add_tree_root (¤t_function_decl, 1); - ggc_add_tree_root (¤t_function_func_begin_label, 1); + /* Save in case md file wants to emit args as a comment. */ + save_argc = argc; + save_argv = argv; - /* Initialize the diagnostics reporting machinery. */ - diagnostic_initialize (global_dc); + /* Initialize register usage now so switches may override. */ + init_reg_sets (); /* Register the language-independent parameters. */ add_params (lang_independent_params, LAST_PARAM); @@ -4758,6 +4782,13 @@ toplev_main (argc, argv) align_functions = 1; } + /* Initialize whether `char' is signed. */ + flag_signed_char = DEFAULT_SIGNED_CHAR; +#ifdef DEFAULT_SHORT_ENUMS + /* Initialize how much space enums occupy, by default. */ + flag_short_enums = DEFAULT_SHORT_ENUMS; +#endif + /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can modify it. */ target_flags = 0; @@ -4774,9 +4805,6 @@ toplev_main (argc, argv) OPTIMIZATION_OPTIONS (optimize, optimize_size); #endif - /* Initialize register usage now so switches may override. */ - init_reg_sets (); - /* Perform normal command line switch decoding. */ for (i = 1; i < argc;) { @@ -4844,10 +4872,12 @@ toplev_main (argc, argv) /* All command line options have been processed. */ (*lang_hooks.post_options) (); - - if (exit_after_options) - exit (0); - +} + +/* Process the options that have been parsed. */ +static void +process_options () +{ /* Checker uses the frame pointer. */ if (flag_check_memory_usage) flag_omit_frame_pointer = 0; @@ -4963,180 +4993,214 @@ toplev_main (argc, argv) print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); } - compile_file (filename); + if (! quiet_flag) + time_report = 1; - if (errorcount) - return (FATAL_EXIT_CODE); - if (sorrycount) - return (FATAL_EXIT_CODE); - return (SUCCESS_EXIT_CODE); + if (flag_syntax_only) + { + write_symbols = NO_DEBUG; + profile_flag = 0; + profile_block_flag = 0; + } + + /* Now we know write_symbols, set up the debug hooks based on it. + By default we do nothing for debug output. */ +#if defined(DBX_DEBUGGING_INFO) + if (write_symbols == DBX_DEBUG) + debug_hooks = &dbx_debug_hooks; +#endif +#if defined(XCOFF_DEBUGGING_INFO) + if (write_symbols == XCOFF_DEBUG) + debug_hooks = &xcoff_debug_hooks; +#endif +#ifdef SDB_DEBUGGING_INFO + if (write_symbols == SDB_DEBUG) + debug_hooks = &sdb_debug_hooks; +#endif +#ifdef DWARF_DEBUGGING_INFO + if (write_symbols == DWARF_DEBUG) + debug_hooks = &dwarf_debug_hooks; +#endif +#ifdef DWARF2_DEBUGGING_INFO + if (write_symbols == DWARF2_DEBUG) + debug_hooks = &dwarf2_debug_hooks; +#endif + + /* If auxiliary info generation is desired, open the output file. + This goes in the same directory as the source file--unlike + all the other output files. */ + if (flag_gen_aux_info) + { + aux_info_file = fopen (aux_info_file_name, "w"); + if (aux_info_file == 0) + fatal_io_error ("can't open %s", aux_info_file_name); + } + + if (! targetm.have_named_sections) + { + if (flag_function_sections) + { + warning ("-ffunction-sections not supported for this target."); + flag_function_sections = 0; + } + if (flag_data_sections) + { + warning ("-fdata-sections not supported for this target."); + flag_data_sections = 0; + } + } + + if (flag_function_sections + && (profile_flag || profile_block_flag)) + { + warning ("-ffunction-sections disabled; it makes profiling impossible."); + flag_function_sections = 0; + } + +#ifndef OBJECT_FORMAT_ELF + if (flag_function_sections && write_symbols != NO_DEBUG) + warning ("-ffunction-sections may affect debugging on some targets."); +#endif } -/* Decode -m switches. */ -/* Decode the switch -mNAME. */ - +/* Language-independent initialization, before language-dependent + initialization. */ static void -set_target_switch (name) - const char *name; +lang_independent_init () { - size_t j; - int valid_target_option = 0; + decl_printable_name = decl_name; + lang_expand_expr = (lang_expand_expr_t) do_abort; - for (j = 0; j < ARRAY_SIZE (target_switches); j++) - if (!strcmp (target_switches[j].name, name)) - { - if (target_switches[j].value < 0) - target_flags &= ~-target_switches[j].value; - else - target_flags |= target_switches[j].value; - valid_target_option = 1; - } + /* Set the language-dependent identifer size. */ + tree_code_length[(int) IDENTIFIER_NODE] + = ((lang_hooks.identifier_size - sizeof (struct tree_common)) + / sizeof (tree)); -#ifdef TARGET_OPTIONS - if (!valid_target_option) - for (j = 0; j < ARRAY_SIZE (target_options); j++) - { - int len = strlen (target_options[j].prefix); - if (!strncmp (target_options[j].prefix, name, len)) - { - *target_options[j].variable = name + len; - valid_target_option = 1; - } - } -#endif + /* Initialize the garbage-collector, and string pools. FIXME: We + should do this later, in independent_init () when we know we + actually want to compile something, but cpplib currently wants to + use the hash table immediately in cpp_create_reader. */ + init_ggc (); + ggc_add_rtx_root (&stack_limit_rtx, 1); + ggc_add_tree_root (¤t_function_decl, 1); + ggc_add_tree_root (¤t_function_func_begin_label, 1); - if (!valid_target_option) - error ("Invalid option `%s'", name); + init_stringpool (); + init_obstacks (); + + init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL + || debug_info_level == DINFO_LEVEL_VERBOSE + || flag_test_coverage + || warn_notreached); + init_regs (); + init_alias_once (); + init_stmt (); + init_loop (); + init_reload (); + init_function_once (); + init_stor_layout_once (); + init_varasm_once (); + init_EXPR_INSN_LIST_cache (); + + /* The following initialization functions need to generate rtl, so + provide a dummy function context for them. */ + init_dummy_function_start (); + init_expmed (); + init_expr_once (); + if (flag_caller_saves) + init_caller_save (); + expand_dummy_function_end (); } -/* Print version information to FILE. - Each line begins with INDENT (for the case where FILE is the - assembler output file). */ - +/* Language-dependent initialization. */ static void -print_version (file, indent) - FILE *file; - const char *indent; +lang_dependent_init (name) + const char *name; { -#ifndef __VERSION__ -#define __VERSION__ "[?]" -#endif - fnotice (file, -#ifdef __GNUC__ - "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n" -#else - "%s%s%s version %s (%s) compiled by CC.\n" -#endif - , indent, *indent != 0 ? " " : "", - lang_hooks.name, version_string, TARGET_NAME, - indent, __VERSION__); -} + if (dump_base_name == 0) + dump_base_name = name ? name : "gccdump"; -/* Print an option value and return the adjusted position in the line. - ??? We don't handle error returns from fprintf (disk full); presumably - other code will catch a disk full though. */ + /* Front-end initialization. This hook can assume that GC, + identifier hashes etc. are set up, but debug initialization is + not done yet. This routine must return the original filename + (e.g. foo.i -> foo.c) so can correctly initialize debug output. */ + name = (*lang_hooks.init) (name); -static int -print_single_switch (file, pos, max, indent, sep, term, type, name) - FILE *file; - int pos, max; - const char *indent, *sep, *term, *type, *name; -{ - /* The ultrix fprintf returns 0 on success, so compute the result we want - here since we need it for the following test. */ - int len = strlen (sep) + strlen (type) + strlen (name); + if (name) + name = ggc_strdup (name); - if (pos != 0 - && pos + len > max) - { - fprintf (file, "%s", term); - pos = 0; - } - if (pos == 0) - { - fprintf (file, "%s", indent); - pos = strlen (indent); - } - fprintf (file, "%s%s%s", sep, type, name); - pos += len; - return pos; + main_input_filename = input_filename = name; + init_asm_output (name); + + /* These create various _DECL nodes, so need to be called after the + front end is initialized. */ + init_eh (); + init_optabs (); + + /* Put an entry on the input file stack for the main input file. */ + push_srcloc (input_filename, 0); + + /* If dbx symbol table desired, initialize writing it and output the + predefined types. */ + timevar_push (TV_SYMOUT); + +#ifdef DWARF2_UNWIND_INFO + if (dwarf2out_do_frame ()) + dwarf2out_frame_init (); +#endif + + /* Now we have the correct original filename, we can initialize + debug output. */ + (*debug_hooks->init) (name); + + timevar_pop (TV_SYMOUT); } + +/* Entry point of cc1, cc1plus, jc1, f771, etc. + Decode command args, then call compile_file. + Exit code is FATAL_EXIT_CODE if can't open files or if there were + any errors, or SUCCESS_EXIT_CODE if compilation succeeded. -/* Print active target switches to FILE. - POS is the current cursor position and MAX is the size of a "line". - Each line begins with INDENT and ends with TERM. - Each switch is separated from the next by SEP. */ + It is not safe to call this function more than once. */ -static void -print_switch_values (file, pos, max, indent, sep, term) - FILE *file; - int pos, max; - const char *indent, *sep, *term; +int +toplev_main (argc, argv) + int argc; + char **argv; { - size_t j; - char **p; + /* Initialization of GCC's environment, and diagnostics. */ + general_init (argv [0]); - /* Print the options as passed. */ - - pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, - _("options passed: "), ""); + /* Parse the options and do minimal processing; basically just + enough to default flags appropriately. */ + parse_options_and_default_flags (argc, argv); - for (p = &save_argv[1]; *p != NULL; p++) - if (**p == '-') - { - /* Ignore these. */ - if (strcmp (*p, "-o") == 0) - { - if (p[1] != NULL) - p++; - continue; - } - if (strcmp (*p, "-quiet") == 0) - continue; - if (strcmp (*p, "-version") == 0) - continue; - if ((*p)[1] == 'd') - continue; + /* Exit early if we can (e.g. -help). */ + if (exit_after_options) + return (SUCCESS_EXIT_CODE); - pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); - } - if (pos > 0) - fprintf (file, "%s", term); + /* Start timing total execution time. */ + init_timevar (); + timevar_start (TV_TOTAL); - /* Print the -f and -m options that have been enabled. - We don't handle language specific options but printing argv - should suffice. */ + /* The bulk of command line switch processing. */ + process_options (); - pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, - _("options enabled: "), ""); + /* Language-independent initialization. Also sets up GC, identifier + hashes etc. */ + lang_independent_init (); - for (j = 0; j < ARRAY_SIZE (f_options); j++) - if (*f_options[j].variable == f_options[j].on_value) - pos = print_single_switch (file, pos, max, indent, sep, term, - "-f", f_options[j].string); + /* Language-dependent initialization. */ + lang_dependent_init (filename); - /* Print target specific options. */ + compile_file (); - for (j = 0; j < ARRAY_SIZE (target_switches); j++) - if (target_switches[j].name[0] != '\0' - && target_switches[j].value > 0 - && ((target_switches[j].value & target_flags) - == target_switches[j].value)) - { - pos = print_single_switch (file, pos, max, indent, sep, term, - "-m", target_switches[j].name); - } + /* Stop timing and print the times. */ + timevar_stop (TV_TOTAL); + timevar_print (stderr); -#ifdef TARGET_OPTIONS - for (j = 0; j < ARRAY_SIZE (target_options); j++) - if (*target_options[j].variable != NULL) - { - char prefix[256]; - sprintf (prefix, "-m%s", target_options[j].prefix); - pos = print_single_switch (file, pos, max, indent, sep, term, - prefix, *target_options[j].variable); - } -#endif + if (errorcount || sorrycount) + return (FATAL_EXIT_CODE); - fprintf (file, "%s", term); + return (SUCCESS_EXIT_CODE); } |