summaryrefslogtreecommitdiff
path: root/gcc/toplev.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r--gcc/toplev.c882
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 (&current_function_decl, 1);
- ggc_add_tree_root (&current_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 (&current_function_decl, 1);
+ ggc_add_tree_root (&current_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);
}