This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Reorganise cc command line parsing
- To: gcc-patches at gcc dot gnu dot org
- Subject: Reorganise cc command line parsing
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Tue, 14 Sep 1999 11:19:43 +0100
- Reply-to: nickc at cygnus dot co dot uk
Hi Guys,
Here is the reworked version of my -pedantic patch. This patch
reorganises the command line parsing of toplev.c so that both the
language dependent decoder and the language independent decoder are
given a chance to see all options. It streamlines the code, making
it simpler and cleaner, and removes some hackery to cope with a bug
in the vax c compiler.
One thing that might be a problem with this patch is that
lang_decode_option() is now called for every command line option, not
just the ones that it has placed into documented_lang_options[].
This solves the problem with -pedantic and cpplib, but it does rely
upon lang_decode_option() not complaining if it sees an option that
it was not expecting. Is this guaranteed for all current language
front ends ?
Another point is that code anticipates that in the future we might
want to add a language independent option which should only be
decoded if it has not been decoded by the language dependent
decoder. I am not sure if this is actually necessary, but the code
for this support is very small, so I doubt if it matters.
May I apply this patch ?
Cheers
Nick
Tue Sep 14 10:53:19 1999 Nick Clifton <nickc@cygnus.com>
* toplev.c (progname): Make 'const char *'
(flag_print_mem): Move out of main.
(version_flag): Move out of main.
(filename): Move out of main.
(debug_args): Remove g prefix from options.
(display_help): Add g prefix to debug options.
(check_lang_option): Delete this function.
(decode_d_option): New function: Decode -d... option.
(decode_f_option): New function: Decode -f... option.
(decode_W_option): New function: Decode -W... option.
(decode_g_option): New function: Decode -g... option.
(independent_decode_option): New function: Decode a language
independent command line option.
(main): Invoke lang_decode_option and then
independent_decode_option on each command line option in
turn.
Index: gcc/toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.219
diff -p -w -r1.219 toplev.c
*** toplev.c 1999/09/12 12:45:39 1.219
--- toplev.c 1999/09/14 09:52:02
*************** static void clean_dump_file PROTO((const
*** 217,222 ****
--- 217,228 ----
static void compile_file PROTO((char *));
static void display_help PROTO ((void));
+ static void decode_d_option PROTO ((const char *));
+ static int decode_f_option PROTO ((const char *));
+ static int decode_W_option PROTO ((const char *));
+ static int decode_g_option PROTO ((const char *));
+ static unsigned independent_decode_option PROTO ((int, char **, unsigned));
+
static void print_version PROTO((FILE *, const char *));
static int print_single_switch PROTO((FILE *, int, int, const char *,
const char *, const char *,
*************** void finish_graph_dump_file PROTO ((cons
*** 232,238 ****
/* Name of program invoked, sans directories. */
! char *progname;
/* Copy of arguments to main. */
int save_argc;
--- 238,244 ----
/* Name of program invoked, sans directories. */
! const char *progname;
/* Copy of arguments to main. */
int save_argc;
*************** int stack_reg_dump = 0;
*** 304,309 ****
--- 310,318 ----
#ifdef MACHINE_DEPENDENT_REORG
int mach_dep_reorg_dump = 0;
#endif
+ static int flag_print_mem = 0;
+ static int version_flag = 0;
+ static char * filename = 0;
enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
*************** static struct
*** 792,818 ****
} *da,
debug_args[] =
{
! { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
"Generate default debug format output" },
! { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
#ifdef DBX_DEBUGGING_INFO
! { "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" },
! { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
#endif
#ifdef DWARF_DEBUGGING_INFO
! { "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
! { "gdwarf+", DWARF_DEBUG, 1,
"Generated extended DWARF-1 format debug output" },
#endif
#ifdef DWARF2_DEBUGGING_INFO
! { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
#endif
#ifdef XCOFF_DEBUGGING_INFO
! { "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
! { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
#endif
#ifdef SDB_DEBUGGING_INFO
! { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
#endif
{ 0, 0, 0, 0 }
};
--- 801,827 ----
} *da,
debug_args[] =
{
! { "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
"Generate default debug format output" },
! { "gdb", NO_DEBUG, 1, "Generate default extended debug format output" },
#ifdef DBX_DEBUGGING_INFO
! { "stabs", DBX_DEBUG, 0, "Generate STABS format debug output" },
! { "stabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
#endif
#ifdef DWARF_DEBUGGING_INFO
! { "dwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
! { "dwarf+", DWARF_DEBUG, 1,
"Generated extended DWARF-1 format debug output" },
#endif
#ifdef DWARF2_DEBUGGING_INFO
! { "dwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
#endif
#ifdef XCOFF_DEBUGGING_INFO
! { "xcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
! { "xcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
#endif
#ifdef SDB_DEBUGGING_INFO
! { "coff", SDB_DEBUG, 0, "Generate COFF format debug output" },
#endif
{ 0, 0, 0, 0 }
};
*************** display_help ()
*** 4541,4547 ****
for (i = NUM_ELEM (debug_args); i--;)
{
if (debug_args[i].description != NULL)
! printf (" -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
}
printf (" -aux-info <file> Emit declaration info into <file>.X\n");
--- 4550,4556 ----
for (i = NUM_ELEM (debug_args); i--;)
{
if (debug_args[i].description != NULL)
! printf (" -g%-21s %s\n", debug_args[i].arg, debug_args[i].description);
}
printf (" -aux-info <file> Emit declaration info into <file>.X\n");
*************** display_help ()
*** 4661,4942 ****
}
}
}
-
- /* Compare the user specified 'option' with the language
- specific 'lang_option'. Return true if they match, or
- if 'option' is a viable prefix of 'lang_option'. */
-
- static int
- check_lang_option (option, lang_option)
- char * option;
- char * lang_option;
- {
- lang_independent_options * indep_options;
- int len;
- long k;
- char * space;
-
- /* Ignore NULL entries. */
- if (option == NULL || lang_option == NULL)
- return 0;
-
- if ((space = strchr (lang_option, ' ')) != NULL)
- len = space - lang_option;
- else
- len = strlen (lang_option);
-
- /* If they do not match to the first n characters then fail. */
- if (strncmp (option, lang_option, len) != 0)
- return 0;
-
- /* Do not accept a lang option, if it matches a normal -f or -W
- option. Chill defines a -fpack, but we want to support
- -fpack-struct. */
-
- /* An exact match is OK */
- if ((int) strlen (option) == len)
- return 1;
-
- /* If it is not an -f or -W option allow the match */
- if (option[0] != '-')
- return 1;
-
- switch (option[1])
- {
- case 'f': indep_options = f_options; break;
- case 'W': indep_options = W_options; break;
- default: return 1;
- }
-
- /* The option is a -f or -W option.
- Skip past the prefix and search for the remainder in the
- appropriate table of options. */
- option += 2;
-
- if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
- option += 3;
-
- for (k = NUM_ELEM (indep_options); k--;)
- {
- if (!strcmp (option, indep_options[k].string))
- {
- /* The option matched a language independent option,
- do not allow the language specific match. */
-
- return 0;
- }
- }
-
- /* The option matches the start of the langauge specific option
- and it is not an exact match for a language independent option. */
- return 1;
- }
-
- /* Entry point of cc1/c++. Decode command args, then call compile_file.
- Exit code is 35 if can't open files, 34 if fatal error,
- 33 if had nonfatal errors, else success. */
-
- int
- main (argc, argv)
- int argc;
- char **argv;
- {
- register int i;
- char *filename = 0;
- int flag_print_mem = 0;
- int version_flag = 0;
- char *p;
-
- /* save in case md file wants to emit args as a comment. */
- save_argc = argc;
- save_argv = argv;
-
- p = argv[0] + strlen (argv[0]);
- while (p != argv[0] && p[-1] != '/'
- #ifdef DIR_SEPARATOR
- && p[-1] != DIR_SEPARATOR
- #endif
- )
- --p;
- progname = p;
-
- #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
- /* Get rid of any avoidable limit on stack size. */
- {
- struct rlimit rlim;
-
- /* Set the stack limit huge so that alloca does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
- #endif
-
- #ifdef HAVE_LC_MESSAGES
- setlocale (LC_MESSAGES, "");
- #endif
- (void) bindtextdomain (PACKAGE, localedir);
- (void) textdomain (PACKAGE);
-
- signal (SIGFPE, float_signal);
-
- #ifdef SIGPIPE
- signal (SIGPIPE, pipe_closed);
- #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
-
- /* Initialize the garbage-collector. */
- init_ggc ();
- ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
- &mark_file_stack);
-
- /* Perform language-specific options intialization. */
- lang_init_options ();
-
- /* Scan to see what optimization level has been specified. That will
- determine the default value of many flags. */
- for (i = 1; i < argc; i++)
- {
- if (!strcmp (argv[i], "-O"))
- {
- optimize = 1;
- optimize_size = 0;
- }
- else if (argv[i][0] == '-' && argv[i][1] == 'O')
- {
- /* Handle -Os, -O2, -O3, -O69, ... */
- char *p = &argv[i][2];
-
- if ((p[0] == 's') && (p[1] == 0))
- {
- optimize_size = 1;
-
- /* Optimizing for size forces optimize to be 2. */
- optimize = 2;
- }
- else
- {
- const int optimize_val = read_integral_parameter (p, p - 2, -1);
- if (optimize_val != -1)
- {
- optimize = optimize_val;
- optimize_size = 0;
- }
- }
- }
- }
-
- obey_regdecls = (optimize == 0);
-
- if (optimize >= 1)
- {
- flag_defer_pop = 1;
- flag_thread_jumps = 1;
- #ifdef DELAY_SLOTS
- flag_delayed_branch = 1;
- #endif
- #ifdef CAN_DEBUG_WITHOUT_FP
- flag_omit_frame_pointer = 1;
- #endif
- }
-
- if (optimize >= 2)
- {
- flag_cse_follow_jumps = 1;
- flag_cse_skip_blocks = 1;
- flag_gcse = 1;
- flag_expensive_optimizations = 1;
- flag_strength_reduce = 1;
- flag_rerun_cse_after_loop = 1;
- flag_rerun_loop_opt = 1;
- flag_caller_saves = 1;
- flag_force_mem = 1;
- flag_peephole2 = 1;
- #ifdef INSN_SCHEDULING
- flag_schedule_insns = 1;
- flag_schedule_insns_after_reload = 1;
- #endif
- flag_regmove = 1;
- flag_strict_aliasing = 1;
- }
-
- if (optimize >= 3)
- {
- flag_inline_functions = 1;
- }
-
- if (optimize < 2 || optimize_size)
- {
- align_loops = 1;
- align_jumps = 1;
- align_labels = 1;
- align_functions = 1;
- }
-
- /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
- modify it. */
- target_flags = 0;
- set_target_switch ("");
-
- #ifdef OPTIMIZATION_OPTIONS
- /* Allow default optimizations to be specified on a per-machine basis. */
- OPTIMIZATION_OPTIONS (optimize, optimize_size);
- #endif
-
- /* Initialize register usage now so switches may override. */
- init_reg_sets ();
-
- for (i = 1; i < argc; i++)
- {
- size_t j;
-
- /* If this is a language-specific option,
- decode it in a language-specific way. */
- for (j = NUM_ELEM (documented_lang_options); j--;)
- if (check_lang_option (argv[i], documented_lang_options[j].option))
- break;
-
- if (j != (size_t)-1)
- {
- /* If the option is valid for *some* language,
- treat it as valid even if this language doesn't understand it. */
- int strings_processed = lang_decode_option (argc - i, argv + i);
-
- if (!strcmp (argv[i], "--help"))
- {
- display_help ();
- exit (0);
- }
! if (strings_processed != 0)
! i += strings_processed - 1;
! }
! else if (argv[i][0] == '-' && argv[i][1] != 0)
! {
! register char *str = argv[i] + 1;
! if (str[0] == 'Y')
! str++;
! if (str[0] == 'm')
! set_target_switch (&str[1]);
! else if (!strcmp (str, "dumpbase"))
! {
! dump_base_name = argv[++i];
! }
! else if (str[0] == 'd')
{
! register char *p = &str[1];
! while (*p)
! switch (*p++)
{
case 'a':
branch_prob_dump = 1;
--- 4670,4684 ----
}
}
}
! /* Parse a -d... comand line switch. */
! static void
! decode_d_option (arg)
! const char * arg;
{
! while (* arg)
! switch (* arg ++)
{
case 'a':
branch_prob_dump = 1;
*************** main (argc, argv)
*** 4954,4960 ****
loop_dump = 1;
regmove_dump = 1;
rtl_dump = 1;
! cse_dump = 1, cse2_dump = 1;
gcse_dump = 1;
sched_dump = 1;
sched2_dump = 1;
--- 4696,4703 ----
loop_dump = 1;
regmove_dump = 1;
rtl_dump = 1;
! cse_dump = 1;
! cse2_dump = 1;
gcse_dump = 1;
sched_dump = 1;
sched2_dump = 1;
*************** main (argc, argv)
*** 5053,5192 ****
case 'z':
peephole2_dump = 1;
break;
! case 'D': /* these are handled by the preprocessor */
case 'I':
break;
default:
! warning ("unrecognised gcc debugging option: %c", p[-1]);
break;
}
}
- else if (str[0] == 'f')
- {
- register char *p = &str[1];
- int found = 0;
! /* Some kind of -f option.
! P's value is the option sans `-f'.
! Search for it in the table of options. */
! for (j = 0;
! !found && j < sizeof (f_options) / sizeof (f_options[0]);
! j++)
{
! if (!strcmp (p, f_options[j].string))
{
*f_options[j].variable = f_options[j].on_value;
! /* A goto here would be cleaner,
! but breaks the vax pcc. */
! found = 1;
}
! if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
! && ! strcmp (p+3, f_options[j].string))
{
*f_options[j].variable = ! f_options[j].on_value;
! found = 1;
}
}
! if (found)
! ;
! else if (!strncmp (p, "inline-limit-", 13)
! || !strncmp (p, "inline-limit=", 13))
inline_max_insns =
! read_integral_parameter (p + 13, p - 2, inline_max_insns);
#ifdef INSN_SCHEDULING
! else if (!strncmp (p, "sched-verbose=",14))
! fix_sched_param("verbose",&p[14]);
#endif
! else if (!strncmp (p, "fixed-", 6))
! fix_register (&p[6], 1, 1);
! else if (!strncmp (p, "call-used-", 10))
! fix_register (&p[10], 0, 1);
! else if (!strncmp (p, "call-saved-", 11))
! fix_register (&p[11], 0, 0);
! else if (!strncmp (p, "align-loops=", 12))
! align_loops = read_integral_parameter (p + 12, p - 2,
! align_loops);
! else if (!strncmp (p, "align-functions=", 16))
! align_functions = read_integral_parameter (p + 16, p - 2,
! align_functions);
! else if (!strncmp (p, "align-jumps=", 12))
! align_jumps = read_integral_parameter (p + 12, p - 2,
! align_jumps);
! else if (!strncmp (p, "align-labels=", 13))
! align_labels = read_integral_parameter (p + 13, p - 2,
! align_labels);
else
! error ("Invalid option `%s'", argv[i]);
! }
! else if (str[0] == 'O')
! {
! /* Already been treated above. Do nothing. */
! }
! else if (!strcmp (str, "pedantic"))
! pedantic = 1;
! else if (!strcmp (str, "pedantic-errors"))
! flag_pedantic_errors = pedantic = 1;
! else if (!strcmp (str, "quiet"))
! quiet_flag = 1;
! else if (!strcmp (str, "version"))
! version_flag = 1;
! else if (!strcmp (str, "w"))
! inhibit_warnings = 1;
! else if (!strcmp (str, "W"))
! {
! extra_warnings = 1;
! /* We save the value of warn_uninitialized, since if they put
! -Wuninitialized on the command line, we need to generate a
! warning about not using it without also specifying -O. */
! if (warn_uninitialized != 1)
! warn_uninitialized = 2;
}
! else if (str[0] == 'W')
{
! register char *p = &str[1];
! int found = 0;
! /* Some kind of -W option.
! P's value is the option sans `-W'.
! Search for it in the table of options. */
! for (j = 0;
! !found && j < sizeof (W_options) / sizeof (W_options[0]);
! j++)
{
! if (!strcmp (p, W_options[j].string))
{
*W_options[j].variable = W_options[j].on_value;
! /* A goto here would be cleaner,
! but breaks the vax pcc. */
! found = 1;
}
! if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
! && ! strcmp (p+3, W_options[j].string))
{
*W_options[j].variable = ! W_options[j].on_value;
! found = 1;
}
}
! if (found)
! ;
! else if (!strncmp (p, "id-clash-", 9))
{
! const int id_clash_val
! = read_integral_parameter (p + 9, p - 2, -1);
if (id_clash_val != -1)
{
id_clash_len = id_clash_val;
warn_id_clash = 1;
}
}
! else if (!strncmp (p, "larger-than-", 12))
{
! const int larger_than_val
! = read_integral_parameter (p + 12, p - 2, -1);
if (larger_than_val != -1)
{
larger_than_size = larger_than_val;
--- 4796,4907 ----
case 'z':
peephole2_dump = 1;
break;
! case 'D': /* These are handled by the preprocessor. */
case 'I':
break;
default:
! warning ("unrecognised gcc debugging option: %c", arg[-1]);
break;
}
}
! /* Parse a -f... comand line switch. ARG is the value after the -f.
! It is safe to access 'ARG - 2' to generate the full switch name.
! Return the number of strings consumed. */
!
! static int
! decode_f_option (arg)
! const char * arg;
! {
! int j;
! /* Search for the option in the table of binary f options. */
! for (j = sizeof (f_options) / sizeof (f_options[0]); j--;)
{
! if (!strcmp (arg, f_options[j].string))
{
*f_options[j].variable = f_options[j].on_value;
! return 1;
}
!
! if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
! && ! strcmp (arg + 3, f_options[j].string))
{
*f_options[j].variable = ! f_options[j].on_value;
! return 1;
}
}
! if (!strncmp (arg, "inline-limit-", 13)
! || !strncmp (arg, "inline-limit=", 13))
inline_max_insns =
! read_integral_parameter (arg + 13, arg - 2, inline_max_insns);
#ifdef INSN_SCHEDULING
! else if (!strncmp (arg, "sched-verbose=", 14))
! fix_sched_param ("verbose", (char *)(arg + 14));
#endif
! else if (!strncmp (arg, "fixed-", 6))
! fix_register ((char *)(arg + 6), 1, 1);
! else if (!strncmp (arg, "call-used-", 10))
! fix_register ((char *)(arg + 10), 0, 1);
! else if (!strncmp (arg, "call-saved-", 11))
! fix_register ((char *)(arg + 11), 0, 0);
! else if (!strncmp (arg, "align-loops=", 12))
! align_loops = read_integral_parameter (arg + 12, arg - 2, align_loops);
! else if (!strncmp (arg, "align-functions=", 16))
! align_functions =
! read_integral_parameter (arg + 16, arg - 2, align_functions);
! else if (!strncmp (arg, "align-jumps=", 12))
! align_jumps = read_integral_parameter (arg + 12, arg - 2, align_jumps);
! else if (!strncmp (arg, "align-labels=", 13))
! align_labels = read_integral_parameter (arg + 13, arg - 2, align_labels);
else
! return 0;
!
! return 1;
}
!
! /* Parse a -W... comand line switch. ARG is the value after the -W.
! It is safe to access 'ARG - 2' to generate the full switch name.
! Return the number of strings consumed. */
! static int
! decode_W_option (arg)
! const char * arg;
{
! int j;
! /* Search for the option in the table of binary W options. */
! for (j = sizeof (W_options) / sizeof (W_options[0]); j--;)
{
! if (!strcmp (arg, W_options[j].string))
{
*W_options[j].variable = W_options[j].on_value;
! return 1;
}
!
! if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
! && ! strcmp (arg + 3, W_options[j].string))
{
*W_options[j].variable = ! W_options[j].on_value;
! return 1;
}
}
! if (!strncmp (arg, "id-clash-", 9))
{
! const int id_clash_val = read_integral_parameter (arg + 9, arg - 2, -1);
!
if (id_clash_val != -1)
{
id_clash_len = id_clash_val;
warn_id_clash = 1;
}
}
! else if (!strncmp (arg, "larger-than-", 12))
{
! const int larger_than_val =
! read_integral_parameter (arg + 12, arg - 2, -1);
if (larger_than_val != -1)
{
larger_than_size = larger_than_val;
*************** main (argc, argv)
*** 5194,5224 ****
}
}
else
! error ("Invalid option `%s'", argv[i]);
}
! else if (!strcmp (str, "p"))
{
- profile_flag = 1;
- }
- else if (!strcmp (str, "a"))
- {
- #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- warning ("`-a' option (basic block profile) not supported");
- #else
- profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
- #endif
- }
- else if (!strcmp (str, "ax"))
- {
- #if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- warning ("`-ax' option (jump profiling) not supported");
- #else
- profile_block_flag = (!profile_block_flag
- || profile_block_flag == 2) ? 2 : 3;
- #endif
- }
- else if (str[0] == 'g')
- {
unsigned level;
/* A lot of code assumes write_symbols == NO_DEBUG if the
debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
--- 4909,4926 ----
}
}
else
! return 0;
!
! return 1;
}
!
! /* Parse a -g... comand line switch. ARG is the value after the -g.
! It is safe to access 'ARG - 2' to generate the full switch name.
! Return the number of strings consumed. */
! static int
! decode_g_option (arg)
! const char * arg;
{
unsigned level;
/* A lot of code assumes write_symbols == NO_DEBUG if the
debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
*************** main (argc, argv)
*** 5239,5253 ****
/* The maximum admissible debug level value. */
static const unsigned max_debug_level = 3;
! /* Look up STR in the table. */
for (da = debug_args; da->arg; da++)
{
const int da_len = strlen (da->arg);
! if (! strncmp (str, da->arg, da_len))
{
enum debug_info_type type = da->debug_type;
! const char *p = str + da_len;
if (*p && (*p < '0' || *p > '9'))
continue;
--- 4941,4955 ----
/* The maximum admissible debug level value. */
static const unsigned max_debug_level = 3;
! /* Look up ARG in the table. */
for (da = debug_args; da->arg; da++)
{
const int da_len = strlen (da->arg);
! if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
{
enum debug_info_type type = da->debug_type;
! const char * p = arg + da_len;
if (*p && (*p < '0' || *p > '9'))
continue;
*************** main (argc, argv)
*** 5261,5272 ****
read_integral_parameter to better handle this case
if this case shows up often. */
if (*p)
! level = read_integral_parameter (p, 0,
! max_debug_level + 1);
else
level = 2;
! if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
{
error ("use -gdwarf -g%d for DWARF v1, level %d",
level, level);
--- 4963,4973 ----
read_integral_parameter to better handle this case
if this case shows up often. */
if (*p)
! level = read_integral_parameter (p, 0, max_debug_level + 1);
else
level = 2;
! if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
{
error ("use -gdwarf -g%d for DWARF v1, level %d",
level, level);
*************** main (argc, argv)
*** 5276,5290 ****
if (level > max_debug_level)
{
! warning ("ignoring option `%s' due to invalid debug level specification",
! str - 1);
level = debug_info_level;
}
if (type == NO_DEBUG)
{
type = PREFERRED_DEBUGGING_TYPE;
! if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
{
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
type = DWARF2_DEBUG;
--- 4977,4993 ----
if (level > max_debug_level)
{
! warning ("\
! ignoring option `%s' due to invalid debug level specification",
! arg - 2);
level = debug_info_level;
}
if (type == NO_DEBUG)
{
type = PREFERRED_DEBUGGING_TYPE;
!
! if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
{
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
type = DWARF2_DEBUG;
*************** main (argc, argv)
*** 5297,5374 ****
}
if (type == NO_DEBUG)
! warning ("`-%s' not supported by this configuration of GCC",
! str);
/* Does it conflict with an already selected type? */
if (type_explicitly_set_p
/* -g/-ggdb don't conflict with anything */
&& da->debug_type != NO_DEBUG
&& type != selected_debug_type)
! warning ("`-%s' ignored, conflicts with `-g%s'",
! str, debug_type_names[(int) selected_debug_type]);
else
{
/* If the format has already been set, -g/-ggdb
only change the debug level. */
! if (type_explicitly_set_p
! && da->debug_type == NO_DEBUG)
; /* don't change debugging type */
else
{
selected_debug_type = type;
type_explicitly_set_p = da->debug_type != NO_DEBUG;
}
write_symbols = (level == 0
? NO_DEBUG
: selected_debug_type);
use_gnu_debug_info_extensions = da->use_extensions_p;
debug_info_level = (enum debug_info_level) level;
}
break;
}
}
if (! da->arg)
! warning ("`-%s' not supported by this configuration of GCC",
! str);
}
! else if (!strcmp (str, "o"))
{
! asm_file_name = argv[++i];
}
! else if (str[0] == 'G')
{
! const int g_switch_val = (str[1] != '\0') ?
! read_integral_parameter(str + 1, 0, -1) :
! read_integral_parameter(argv[++i], 0, -1);
! if (g_switch_val != -1)
{
g_switch_set = TRUE;
g_switch_value = g_switch_val;
}
else
{
! error("Invalid option `-%s'",str);
}
}
! else if (!strncmp (str, "aux-info", 8))
{
! flag_gen_aux_info = 1;
! aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
}
! else if (!strcmp (str, "-help"))
{
! display_help ();
! exit (0);
}
else
error ("Invalid option `%s'", argv[i]);
}
- else if (argv[i][0] == '+')
- error ("Invalid option `%s'", argv[i]);
- else
- filename = argv[i];
}
/* Checker uses the frame pointer. */
--- 5000,5422 ----
}
if (type == NO_DEBUG)
! warning ("`%s' not supported by this configuration of GCC",
! arg - 2);
/* Does it conflict with an already selected type? */
if (type_explicitly_set_p
/* -g/-ggdb don't conflict with anything */
&& da->debug_type != NO_DEBUG
&& type != selected_debug_type)
! warning ("`%s' ignored, conflicts with `-g%s'",
! arg - 2, debug_type_names[(int) selected_debug_type]);
else
{
/* If the format has already been set, -g/-ggdb
only change the debug level. */
! if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
; /* don't change debugging type */
else
{
selected_debug_type = type;
type_explicitly_set_p = da->debug_type != NO_DEBUG;
}
+
write_symbols = (level == 0
? NO_DEBUG
: selected_debug_type);
use_gnu_debug_info_extensions = da->use_extensions_p;
debug_info_level = (enum debug_info_level) level;
}
+
break;
}
}
+
if (! da->arg)
! warning ("`%s' not supported by this configuration of GCC", arg - 2);
!
! return 1;
! }
!
! /* Decode the first argument in the argv as a language-independent option.
! Return the number of strings consumed. 'strings_processed' is the
! number of strings that have already been decoded in a language
! specific fashion before this function was invoked. */
!
! static unsigned
! independent_decode_option (argc, argv, strings_processed)
! int argc;
! char ** argv;
! unsigned strings_processed ATTRIBUTE_UNUSED;
! {
! char * arg = argv[0];
!
! if (arg[0] != '-' || arg[1] == 0)
! {
! if (arg[0] == '+')
! return 0;
!
! filename = arg;
!
! return 1;
! }
!
! arg ++;
!
! if (!strcmp (arg, "-help"))
! {
! display_help ();
! exit (0);
! }
!
! if (* arg == 'Y')
! arg ++;
!
! switch (* arg)
! {
! default:
! return 0;
!
! case 'O':
! /* Already been treated in main (). Do nothing. */
! break;
!
! case 'm':
! set_target_switch (arg + 1);
! break;
!
! case 'f':
! return decode_f_option (arg + 1);
!
! case 'g':
! return decode_g_option (arg + 1);
!
! case 'd':
! if (!strcmp (arg, "dumpbase"))
! {
! if (argc == 1)
! return 0;
!
! dump_base_name = argv[1];
! return 2;
! }
! else
! decode_d_option (arg + 1);
! break;
!
! case 'p':
! if (!strcmp (arg, "pedantic"))
! pedantic = 1;
! else if (!strcmp (arg, "pedantic-errors"))
! flag_pedantic_errors = pedantic = 1;
! else if (arg[1] == 0)
! profile_flag = 1;
! else
! return 0;
! break;
!
! case 'q':
! if (!strcmp (arg, "quiet"))
! quiet_flag = 1;
! else
! return 0;
! break;
!
! case 'v':
! if (!strcmp (arg, "version"))
! version_flag = 1;
! else
! return 0;
! break;
!
! case 'w':
! if (arg[1] == 0)
! inhibit_warnings = 1;
! else
! return 0;
! break;
!
! case 'W':
! if (arg[1] == 0)
! {
! extra_warnings = 1;
! /* We save the value of warn_uninitialized, since if they put
! -Wuninitialized on the command line, we need to generate a
! warning about not using it without also specifying -O. */
! if (warn_uninitialized != 1)
! warn_uninitialized = 2;
! }
! else
! return decode_W_option (arg + 1);
! break;
!
! case 'a':
! if (arg[1] == 0)
! {
! #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
! warning ("`-a' option (basic block profile) not supported");
! #else
! profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
! #endif
! }
! else if (!strcmp (arg, "ax"))
! {
! #if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
! warning ("`-ax' option (jump profiling) not supported");
! #else
! profile_block_flag = (!profile_block_flag
! || profile_block_flag == 2) ? 2 : 3;
! #endif
! }
! else if (!strncmp (arg, "aux-info", 8))
! {
! flag_gen_aux_info = 1;
! if (arg[8] == '\0')
! {
! if (argc == 1)
! return 0;
!
! aux_info_file_name = argv[1];
! return 2;
}
! else
! aux_info_file_name = arg + 8;
! }
! else
! return 0;
! break;
!
! case 'o':
! if (arg[1] == 0)
{
! if (argc == 1)
! return 0;
!
! asm_file_name = argv[1];
! return 2;
}
! return 0;
!
! case 'G':
{
! int g_switch_val;
! int return_val;
! if (arg[1] == 0)
{
+ if (argc == 1)
+ return 0;
+
+ g_switch_val = read_integral_parameter (argv[1], 0, -1);
+ return_val = 2;
+ }
+ else
+ {
+ g_switch_val = read_integral_parameter (arg + 1, 0, -1);
+ return_val = 1;
+ }
+
+ if (g_switch_val == -1)
+ return_val = 0;
+ else
+ {
g_switch_set = TRUE;
g_switch_value = g_switch_val;
}
+
+ return return_val;
+ }
+ }
+
+ return 1;
+ }
+
+ /* Entry point of cc1/c++. Decode command args, then call compile_file.
+ Exit code is 35 if can't open files, 34 if fatal error,
+ 33 if had nonfatal errors, else success. */
+
+ int
+ main (argc, argv)
+ int argc;
+ char **argv;
+ {
+ register int i;
+ char *p;
+
+ /* save in case md file wants to emit args as a comment. */
+ save_argc = argc;
+ save_argv = argv;
+
+ p = argv[0] + strlen (argv[0]);
+ while (p != argv[0] && p[-1] != '/'
+ #ifdef DIR_SEPARATOR
+ && p[-1] != DIR_SEPARATOR
+ #endif
+ )
+ --p;
+ progname = p;
+
+ #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
+ /* Get rid of any avoidable limit on stack size. */
+ {
+ struct rlimit rlim;
+
+ /* Set the stack limit huge so that alloca does not fail. */
+ getrlimit (RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max;
+ setrlimit (RLIMIT_STACK, &rlim);
+ }
+ #endif
+
+ #ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+ #endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
+ signal (SIGFPE, float_signal);
+
+ #ifdef SIGPIPE
+ signal (SIGPIPE, pipe_closed);
+ #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
+
+ /* Initialize the garbage-collector. */
+ init_ggc ();
+ ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
+ &mark_file_stack);
+
+ /* Perform language-specific options intialization. */
+ lang_init_options ();
+
+ /* Scan to see what optimization level has been specified. That will
+ determine the default value of many flags. */
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp (argv[i], "-O"))
+ {
+ optimize = 1;
+ optimize_size = 0;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'O')
+ {
+ /* Handle -Os, -O2, -O3, -O69, ... */
+ char *p = &argv[i][2];
+
+ if ((p[0] == 's') && (p[1] == 0))
+ {
+ optimize_size = 1;
+
+ /* Optimizing for size forces optimize to be 2. */
+ optimize = 2;
+ }
else
+ {
+ const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ if (optimize_val != -1)
{
! optimize = optimize_val;
! optimize_size = 0;
! }
! }
}
}
!
! obey_regdecls = (optimize == 0);
!
! if (optimize >= 1)
{
! flag_defer_pop = 1;
! flag_thread_jumps = 1;
! #ifdef DELAY_SLOTS
! flag_delayed_branch = 1;
! #endif
! #ifdef CAN_DEBUG_WITHOUT_FP
! flag_omit_frame_pointer = 1;
! #endif
}
!
! if (optimize >= 2)
{
! flag_cse_follow_jumps = 1;
! flag_cse_skip_blocks = 1;
! flag_gcse = 1;
! flag_expensive_optimizations = 1;
! flag_strength_reduce = 1;
! flag_rerun_cse_after_loop = 1;
! flag_rerun_loop_opt = 1;
! flag_caller_saves = 1;
! flag_force_mem = 1;
! flag_peephole2 = 1;
! #ifdef INSN_SCHEDULING
! flag_schedule_insns = 1;
! flag_schedule_insns_after_reload = 1;
! #endif
! flag_regmove = 1;
! flag_strict_aliasing = 1;
! }
!
! if (optimize >= 3)
! {
! flag_inline_functions = 1;
! }
!
! if (optimize < 2 || optimize_size)
! {
! align_loops = 1;
! align_jumps = 1;
! align_labels = 1;
! align_functions = 1;
}
+
+ /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
+ modify it. */
+ target_flags = 0;
+ set_target_switch ("");
+
+ #ifdef OPTIMIZATION_OPTIONS
+ /* Allow default optimizations to be specified on a per-machine basis. */
+ 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;)
+ {
+ unsigned lang_processed;
+ unsigned indep_processed;
+
+ /* Give the language a chance to decode the option for itself. */
+ lang_processed = lang_decode_option (argc - i, argv + i);
+
+ /* Now see if the option also has a language independent meaning.
+ Some options are both language specific and language independent,
+ eg --help. It is possible that there might be options that should
+ only be decoded in a language independent way if the were not
+ decoded in a langauge specific way, which is why 'lang_processed'
+ is passed in. */
+
+ indep_processed = independent_decode_option (argc - i, argv + i, lang_processed);
+
+ if (lang_processed || indep_processed)
+ i += lang_processed > indep_processed ? lang_processed : indep_processed;
else
+ {
error ("Invalid option `%s'", argv[i]);
+ i++;
}
}
/* Checker uses the frame pointer. */