This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Move handling of lang-specific switches to toplev


This handles C switches in opts.c, a sister of toplev.c that will
ultimately contain all of toplev's switch code.

At present, only the C front end uses the new scheme; the next
step is to convert the other front ends.  The C front option
handler is now little more than a large switch statement.

I wanted options.h for a header file; unfortunately that is
already used for a generated file.  I renamed the exisiting
one options_.h; eventually I don't think it will be needed.

Kaveh will be glad to know that I've removed the #include-ing
of .c files.

Neil.

	* Makefile.in (OJBS, c-opts.o): Update.
	(c-options.c, c-options.h): Rename options.h and options.c.
	(options.h): Rename options_.h.
	(opts.o): New.
	* c-common.h (c_common_handle_option): Replace c_common_decode_option.
	(c_common_init_options): Update prototype.
	* c-lang.c (c_init_options): Update prototype.
	(LANG_HOOKS_HANDLE_OPTION): Override.
	(LANG_HOOKS_DECODE_OPTION): Drop.
	* c-opts.c: Include opts.h and options.h instead of c-options.h
	and c-options.c.
	(lang_flags): Move to file scope.
	(find_opt, c_common_decode_option): Remove.
	(CL_C, CL_OBJC, CL_CXX, CL_OBJCXX, CL_JOINED, CL_SEPARATE,
	CL_REJECT_NEGATIVE): Move to opts.h.
	(missing_arg): Update prototype.
	(c_common_init_options): Update for new prototype.
	(c_common_handle_options): Filenames are passed as N_OPTS.
	* hooks.c (hook_int_void_0): New.
	* hooks.h (hook_int_void_0): New.
	* langhooks-def.h (LANG_HOOKS_INIT_OPTIONS): New default.
	(LANG_HOOKS_HANDLE_OPTION): Default to NULL for now.
	(LANG_HOOKS_INITIALIZER): Update.
	* langhooks.h (init_options): Update.
	(handle_option): New.
	* opts.c, opts.h: New files.
	* opts.sh: Update c file to include opts.h and options.h.
	* toplev.c: Include opts.h; change options.h to options_.h.
	(parse_options_and_default_flags): Get lang_mask, use
	handle_option for language-specific handling.
	* objc/objc-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
	(LANG_HOOKS_HANDLE_OPTION): Override.
	(objc_init_options): Update.
ada:
	* misc.c (gnat_init_options): Update.
cp:
	* cp-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
	(LANG_HOOKS_HANDLE_OPTION): Override.
	* cp-tree.h (cxx_init_options): Update.
	* lex.c (cxx_init_options): Update.
f:
	* com.c (ffe_init_options): Update.
java:
	* lang.c (java_init_options): Update.

============================================================
Index: gcc/Makefile.in
--- gcc/Makefile.in	6 Jun 2003 09:24:21 -0000	1.1070
+++ gcc/Makefile.in	6 Jun 2003 20:31:57 -0000
@@ -812,7 +812,8 @@ OBJS = alias.o bb-reorder.o bitmap.o bui
  haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o	   \
  insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o	   \
  integrate.o intl.o jump.o  langhooks.o lcm.o lists.o local-alloc.o  	   \
- loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o	   \
+ loop.o mbchar.o optabs.o options.o opts.o params.o predict.o		   \
+ print-rtl.o print-tree.o						   \
  profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o	   \
  real.o recog.o reg-stack.o regclass.o regmove.o regrename.o		   \
  reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o	   \
@@ -1316,15 +1317,14 @@ c-pretty-print.o : c-pretty-print.c c-pr
 
 c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
         c-pragma.h flags.h toplev.h langhooks.h tree-inline.h diagnostic.h \
-	intl.h debug.h $(C_COMMON_H) c-options.h c-options.c
+	intl.h debug.h $(C_COMMON_H) opts.h options.h
 	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
 
-c-options.c: c.opt $(srcdir)/opts.sh
-	AWK=$(AWK) $(SHELL) $(srcdir)/opts.sh c-options.c c-options.h $(srcdir)/c.opt
+options.c: c.opt $(srcdir)/opts.sh options.h
 
-c-options.h: c-options.c
-	@true
+options.h: c.opt $(srcdir)/opts.sh
+	AWK=$(AWK) $(SHELL) $(srcdir)/opts.sh options.c options.h $(srcdir)/c.opt
 
 c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 	$(TREE_H) $(C_COMMON_H) c-pragma.h flags.h toplev.h langhooks.h \
@@ -1404,12 +1404,12 @@ s-gencheck : Makefile
 	$(SHELL) $(srcdir)/move-if-change tmp-gencheck.h gencheck.h
 	$(STAMP) s-gencheck
 
-options.h : s-options ; @true
+options_.h : s-options ; @true
 s-options : Makefile
 	lof="$(lang_options_files)"; for f in $$lof; do \
 	    echo "#include \"$$f\""; \
-	done | sed 's|$(srcdir)/||' > tmp-options.h
-	$(SHELL) $(srcdir)/move-if-change tmp-options.h options.h
+	done | sed 's|$(srcdir)/||' > tmp-options_.h
+	$(SHELL) $(srcdir)/move-if-change tmp-options_.h options_.h
 	$(STAMP) s-options
 
 specs.h : s-specs ; @true
@@ -1479,13 +1479,15 @@ fold-const.o : fold-const.c $(CONFIG_H) 
 diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \
    $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(TM_P_H) flags.h $(GGC_H) \
    input.h toplev.h intl.h langhooks.h $(LANGHOOKS_DEF_H)
+opts.o : opts.c opts.h options.h $(CONFIG_H) $(SYSTEM_H) \
+	coretypes.h $(TREE_H) $(TM_H) $(LANGHOOKS_H)
 toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
    function.h flags.h xcoffout.h input.h $(INSN_ATTR_H) output.h diagnostic.h \
    debug.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h \
    dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
    graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) $(lang_options_files) \
    ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
-   langhooks.h insn-flags.h options.h cfglayout.h real.h cfgloop.h \
+   langhooks.h insn-flags.h options_.h cfglayout.h real.h cfgloop.h \
    hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h
 	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 	  -DTARGET_NAME=\"$(target_alias)\" \
@@ -2785,7 +2787,7 @@ mostlyclean: $(INTL_MOSTLYCLEAN) lang.mo
 	-rm -f xlimits.h
 # Delete other built files.
 	-rm -f xsys-protos.hT
-	-rm -f specs.h options.h gencheck.h c-options.c c-options.h
+	-rm -f specs.h options_.h gencheck.h options.c options.h
 # Delete the stamp and temporary files.
 	-rm -f s-* tmp-* stamp-* stmp-*
 	-rm -f */stamp-* */tmp-*
============================================================
Index: gcc/c-common.h
--- gcc/c-common.h	21 May 2003 11:13:17 -0000	1.181
+++ gcc/c-common.h	6 Jun 2003 20:31:57 -0000
@@ -901,7 +901,7 @@ extern tree handle_format_attribute		PAR
 extern tree handle_format_arg_attribute		PARAMS ((tree *, tree, tree,
 							 int, bool *));
 extern void c_common_insert_default_attributes	PARAMS ((tree));
-extern int c_common_decode_option		PARAMS ((int, char **));
+extern int c_common_handle_option (size_t code, const char *arg, int value);
 extern tree c_common_type_for_mode		PARAMS ((enum machine_mode,
 							 int));
 extern tree c_common_type_for_size		PARAMS ((unsigned int, int));
@@ -959,7 +959,7 @@ extern void disable_builtin_function		PA
 
 extern tree build_va_arg			PARAMS ((tree, tree));
 
-extern void c_common_init_options		PARAMS ((enum c_language_kind));
+extern int c_common_init_options		PARAMS ((enum c_language_kind));
 extern bool c_common_post_options		PARAMS ((const char **));
 extern bool c_common_init			PARAMS ((void));
 extern void c_common_finish			PARAMS ((void));
============================================================
Index: gcc/c-lang.c
--- gcc/c-lang.c	12 Feb 2003 21:48:57 -0000	1.102
+++ gcc/c-lang.c	6 Jun 2003 20:31:57 -0000
@@ -31,7 +31,7 @@ Software Foundation, 59 Temple Place - S
 #include "langhooks.h"
 #include "langhooks-def.h"
 
-static void c_init_options PARAMS ((void));
+static int c_init_options PARAMS ((void));
 
 /* ### When changing hooks, consider if ObjC needs changing too!! ### */
 
@@ -43,8 +43,8 @@ static void c_init_options PARAMS ((void
 #define LANG_HOOKS_FINISH c_common_finish
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS c_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
 #undef LANG_HOOKS_POST_OPTIONS
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_GET_ALIAS_SET
@@ -157,10 +157,10 @@ const char *const tree_code_name[] = {
 };
 #undef DEFTREECODE
 
-static void
+static int
 c_init_options ()
 {
-  c_common_init_options (clk_c);
+  return c_common_init_options (clk_c);
 }
 
 /* Used by c-lex.c, but only for objc.  */
============================================================
Index: gcc/c-opts.c
--- gcc/c-opts.c	3 Jun 2003 05:42:25 -0000	1.52
+++ gcc/c-opts.c	6 Jun 2003 20:31:58 -0000
@@ -35,7 +35,8 @@ Software Foundation, 59 Temple Place - S
 #include "cppdefault.h"
 #include "c-incpath.h"
 #include "debug.h"		/* For debug_hooks.  */
-#include "c-options.h"
+#include "opts.h"
+#include "options.h"
 
 #ifndef DOLLARS_IN_IDENTIFIERS
 # define DOLLARS_IN_IDENTIFIERS true
@@ -49,6 +50,8 @@ Software Foundation, 59 Temple Place - S
 # define TARGET_EBCDIC 0
 #endif
 
+static const int lang_flags[] = {CL_C, CL_OBJC, CL_CXX, CL_OBJCXX};
+
 static int saved_lineno;
 
 /* CPP's options.  */
@@ -97,8 +100,7 @@ static size_t deferred_count, deferred_s
 /* Number of deferred options scanned for -include.  */
 static size_t include_cursor;
 
-static void missing_arg PARAMS ((size_t));
-static size_t find_opt PARAMS ((const char *, int));
+static void missing_arg PARAMS ((enum opt_code));
 static void set_Wimplicit PARAMS ((int));
 static void complain_wrong_lang PARAMS ((size_t));
 static void write_langs PARAMS ((char *, int));
@@ -114,36 +116,12 @@ static void add_prefixed_path PARAMS ((c
 static void push_command_line_include PARAMS ((void));
 static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
 static void finish_options PARAMS ((void));
-static int c_common_handle_option (enum opt_code, const char *arg, int on);
 
 #ifndef STDC_0_IN_SYSTEM_HEADERS
 #define STDC_0_IN_SYSTEM_HEADERS 0
 #endif
 
-#define CL_C			(1 << 0) /* Only C.  */
-#define CL_OBJC			(1 << 1) /* Only ObjC.  */
-#define CL_CXX			(1 << 2) /* Only C++.  */
-#define CL_OBJCXX		(1 << 3) /* Only ObjC++.  */
-#define CL_JOINED		(1 << 4) /* If takes joined argument.  */
-#define CL_SEPARATE		(1 << 5) /* If takes a separate argument.  */
-#define CL_REJECT_NEGATIVE	(1 << 6) /* Reject no- form.  */
-
-#include "c-options.c"
-
-/* If the user gives an option to a front end that doesn't support it,
-   an error is output, mentioning which front ends the option is valid
-   for.  If you don't want this, you must accept it for all front
-   ends, and test for the front end in the option handler.  See, for
-   example, the handling of -fcond-mismatch.
-
-   If you requested a joined or separate argument, it is stored in the
-   variable "arg", which is guaranteed to be non-NULL and to not be an
-   empty string.  It points to the argument either within the argv[]
-   vector or within one of that vector's strings, and so the text is
-   permanent and copies need not be made.  Be sure to add an error
-   message in missing_arg() if the default is not appropriate.  */
-
-/* Holds switches parsed by c_common_decode_option (), but whose
+/* Holds switches parsed by c_common_handle_option (), but whose
    handling is deferred to c_common_post_options ().  */
 static void defer_opt PARAMS ((enum opt_code, const char *));
 static struct deferred_opt
@@ -155,12 +133,11 @@ static struct deferred_opt
 /* Complain that switch OPT_INDEX expects an argument but none was
    provided.  */
 static void
-missing_arg (opt_index)
-     size_t opt_index;
+missing_arg (enum opt_code code)
 {
-  const char *opt_text = cl_options[opt_index].opt_text;
+  const char *opt_text = cl_options[code].opt_text;
 
-  switch (opt_index)
+  switch (code)
     {
     case OPT__output_pch_:
     case OPT_Wformat_:
@@ -214,95 +191,6 @@ missing_arg (opt_index)
     }
 }
 
-/* Perform a binary search to find which option the command-line INPUT
-   matches.  Returns its index in the option array, and N_OPTS on
-   failure.
-
-   Complications arise since some options can be suffixed with an
-   argument, and multiple complete matches can occur, e.g. -pedantic
-   and -pedantic-errors.  Also, some options are only accepted by some
-   languages.  If a switch matches for a different language and
-   doesn't match any alternatives for the true front end, the index of
-   the matched switch is returned anyway.  The caller should check for
-   this case.  */
-static size_t
-find_opt (input, lang_flag)
-     const char *input;
-     int lang_flag;
-{
-  size_t md, mn, mx;
-  size_t opt_len;
-  size_t result = N_OPTS;
-  int comp;
-
-  mn = 0;
-  mx = N_OPTS;
-
-  while (mx > mn)
-    {
-      md = (mn + mx) / 2;
-
-      opt_len = cl_options[md].opt_len;
-      comp = strncmp (input, cl_options[md].opt_text, opt_len);
-
-      if (comp < 0)
-	mx = md;
-      else if (comp > 0)
-	mn = md + 1;
-      else
-	{
-	  /* The switch matches.  It it an exact match?  */
-	  if (input[opt_len] == '\0')
-	    return md;
-	  else
-	    {
-	      mn = md + 1;
-
-	      /* If the switch takes no arguments this is not a proper
-		 match, so we continue the search (e.g. input="stdc++"
-		 match was "stdc").  */
-	      if (!(cl_options[md].flags & CL_JOINED))
-		continue;
-
-	      /* Is this switch valid for this front end?  */
-	      if (!(cl_options[md].flags & lang_flag))
-		{
-		  /* If subsequently we don't find a better match,
-		     return this and let the caller report it as a bad
-		     match.  */
-		  result = md;
-		  continue;
-		}
-
-	      /* Two scenarios remain: we have the switch's argument,
-		 or we match a longer option.  This can happen with
-		 -iwithprefix and -withprefixbefore.  The longest
-		 possible option match succeeds.
-
-		 Scan forwards, and return an exact match.  Otherwise
-		 return the longest valid option-accepting match (mx).
-		 This loops at most twice with current options.  */
-	      mx = md;
-	      for (md = md + 1; md < (size_t) N_OPTS; md++)
-		{
-		  opt_len = cl_options[md].opt_len;
-		  if (strncmp (input, cl_options[md].opt_text, opt_len))
-		    break;
-		  if (input[opt_len] == '\0')
-		    return md;
-		  if (cl_options[md].flags & lang_flag
-		      && cl_options[md].flags & CL_JOINED)
-		    mx = md;
-		}
-
-	      return mx;
-	    }
-	}
-    }
-
-  return result;
-}
-
 /* Defer option CODE with argument ARG.  */
 static void
 defer_opt (code, arg)
@@ -328,7 +216,7 @@ defer_opt (code, arg)
 }
 
 /* Common initialization before parsing options.  */
-void
+int
 c_common_init_options (lang)
      enum c_language_kind lang;
 {
@@ -342,134 +230,50 @@ c_common_init_options (lang)
 
   flag_const_strings = (lang == clk_cplusplus);
   warn_pointer_arith = (lang == clk_cplusplus);
+
+  return lang_flags[(c_language << 1) + flag_objc];
 }
 
-/* Handle one command-line option in (argc, argv).
-   Can be called multiple times, to handle multiple sets of options.
-   Returns number of strings consumed.  */
+/* Handle switch SCODE with argument ARG.  ON is true, unless no-
+   form of an -f or -W option was given.  Returns 0 if the switch was
+   invalid, a negative number to prevent language-independent
+   processing in toplev.c (a hack necessary for the short-term).  */
 int
-c_common_decode_option (argc, argv)
-     int argc;
-     char **argv;
+c_common_handle_option (size_t scode, const char *arg, int on)
 {
-  static const int lang_flags[] = {CL_C, CL_OBJC, CL_CXX, CL_OBJCXX};
-  size_t opt_index;
-  const char *opt, *arg = 0;
-  char *dup = 0;
-  bool on = true;
-  int result = 0, temp, lang_flag;
-  const struct cl_option *option;
+  const struct cl_option *option = &cl_options[scode];
+  enum opt_code code = (enum opt_code) scode;
+  int result = 1, lang_mask;
 
-  opt = argv[0];
-
-  /* Interpret "-" or a non-switch as a file name.  */
-  if (opt[0] != '-' || opt[1] == '\0')
+  if (code == N_OPTS)
     {
       if (!in_fname)
-	in_fname = opt;
+	in_fname = arg;
       else if (!out_fname)
-	out_fname = opt;
+	out_fname = arg;
       else
-	{
 	  error ("too many filenames given.  Type %s --help for usage",
 		 progname);
-	  return argc;
-	}
-
       return 1;
     }
 
-  /* Drop the "no-" from negative switches.  */
-  if ((opt[1] == 'W' || opt[1] == 'f')
-      && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+  lang_mask = lang_flags[(c_language << 1) + flag_objc];
+  if (!(option->flags & lang_mask))
     {
-      size_t len = strlen (opt) - 3;
-
-      dup = xmalloc (len + 1);
-      dup[0] = '-';
-      dup[1] = opt[1];
-      memcpy (dup + 2, opt + 5, len - 2 + 1);
-      opt = dup;
-      on = false;
-    }
-
-  /* Skip over '-'.  */
-  lang_flag = lang_flags[(c_language << 1) + flag_objc];
-  opt_index = find_opt (opt + 1, lang_flag);
-  if (opt_index == N_OPTS)
-    goto done;
-
-  option = &cl_options[opt_index];
-
-  /* Reject negative form of switches that don't take negatives.  */
-  if (!on && (option->flags & CL_REJECT_NEGATIVE))
-    goto done;
-
-  /* We've recognised this switch.  */
-  result = 1;
-
-  /* Sort out any argument the switch takes.  */
-  if (option->flags & (CL_JOINED | CL_SEPARATE))
-    {
-      if (option->flags & CL_JOINED)
-	{
-	  /* Have arg point to the original switch.  This is because
-	     some code, such as disable_builtin_function, expects its
-	     argument to be persistent until the program exits.  */
-	  arg = argv[0] + cl_options[opt_index].opt_len + 1;
-	  if (!on)
-	    arg += strlen ("no-");
-	}
-
-      /* If we don't have an argument, and CL_SEPARATE, try the next
-	 argument in the vector.  */
-      if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
-	{
-	  arg = argv[1];
-	  result = 2;
-	}
-
-      if (!arg || *arg == '\0')
-	{
-	  missing_arg (opt_index);
-	  result = argc;
-	  goto done;
-	}
+      complain_wrong_lang (code);
+      return 1;
     }
 
-  /* Complain about the wrong language after we've swallowed any
-     necessary extra argument.  Eventually make this a hard error
-     after the call to find_opt, and return argc.  */
-  if (!(cl_options[opt_index].flags & lang_flag))
+  if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
     {
-      complain_wrong_lang (opt_index);
-      goto done;
+      missing_arg (code);
+      return 1;
     }
 
-  temp = c_common_handle_option (opt_index, arg, on);
-  if (temp <= 0)
-    result = temp;
-
- done:
-  if (dup)
-    free (dup);
-  return result;
-}
-
-/* Handle switch OPT_INDEX with argument ARG.  ON is true, unless no-
-   form of an -f or -W option was given.  Returns 0 if the switch was
-   invalid, a negative number to prevent language-independent
-   processing in toplev.c (a hack necessary for the short-term).  */
-static int
-c_common_handle_option (enum opt_code code, const char *arg, int on)
-{
-  const struct cl_option *option = &cl_options[code];
-  int result = 1;
-
   switch (code)
     {
-    case N_OPTS: /* Shut GCC up.  */
-      break;
+    default:
+      return 0;
 
     case OPT__help:
       print_help ();
@@ -1740,6 +1544,7 @@ complain_wrong_lang (opt_index)
 
   write_langs (ok_langs, ok_flags);
   write_langs (bad_langs, ~ok_flags);
+  /* Eventually this should become a hard error.  */
   warning ("\"-%s\" is valid for %s but not for %s",
 	   cl_options[opt_index].opt_text, ok_langs, bad_langs);
 }
============================================================
Index: gcc/hooks.c
--- gcc/hooks.c	5 Mar 2003 22:37:47 -0000	1.13
+++ gcc/hooks.c	6 Jun 2003 20:31:58 -0000
@@ -104,6 +104,12 @@ hook_int_rtx_0 (a)
   return 0;
 }
 
+int
+hook_int_void_0 (void)
+{
+  return 0;
+}
+
 void
 hook_void_tree (a)
      tree a ATTRIBUTE_UNUSED;
============================================================
Index: gcc/hooks.h
--- gcc/hooks.h	5 Mar 2003 22:37:51 -0000	1.13
+++ gcc/hooks.h	6 Jun 2003 20:31:58 -0000
@@ -39,6 +39,7 @@ void hook_void_tree_treeptr PARAMS ((tre
 
 int hook_int_tree_tree_1 PARAMS ((tree, tree));
 int hook_int_rtx_0 PARAMS ((rtx));
+int hook_int_void_0 (void);
 
 bool default_can_output_mi_thunk_no_vcall
   PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
============================================================
Index: gcc/langhooks-def.h
--- gcc/langhooks-def.h	7 Apr 2003 06:03:09 -0000	1.47
+++ gcc/langhooks-def.h	6 Jun 2003 20:31:58 -0000
@@ -92,8 +92,9 @@ void write_global_declarations PARAMS ((
 #define LANG_HOOKS_FINISH		lhd_do_nothing
 #define LANG_HOOKS_PARSE_FILE		lhd_do_nothing_i
 #define LANG_HOOKS_CLEAR_BINDING_STACK	lhd_clear_binding_stack
-#define LANG_HOOKS_INIT_OPTIONS		lhd_do_nothing
+#define LANG_HOOKS_INIT_OPTIONS		hook_int_void_0
 #define LANG_HOOKS_DECODE_OPTION	lhd_decode_option
+#define LANG_HOOKS_HANDLE_OPTION	NULL
 #define LANG_HOOKS_POST_OPTIONS		lhd_post_options
 #define LANG_HOOKS_GET_ALIAS_SET	lhd_get_alias_set
 #define LANG_HOOKS_EXPAND_CONSTANT	lhd_return_tree
@@ -243,6 +244,7 @@ int lhd_tree_dump_type_quals			PARAMS ((
   LANG_HOOKS_TREE_SIZE, \
   LANG_HOOKS_INIT_OPTIONS, \
   LANG_HOOKS_DECODE_OPTION, \
+  LANG_HOOKS_HANDLE_OPTION, \
   LANG_HOOKS_POST_OPTIONS, \
   LANG_HOOKS_INIT, \
   LANG_HOOKS_FINISH, \
============================================================
Index: gcc/langhooks.h
--- gcc/langhooks.h	7 Apr 2003 06:03:10 -0000	1.55
+++ gcc/langhooks.h	6 Jun 2003 20:31:58 -0000
@@ -199,8 +199,9 @@ struct lang_hooks
   size_t (*tree_size) PARAMS ((enum tree_code));
 
   /* The first callback made to the front end, for simple
-     initialization needed before any calls to decode_option.  */
-  void (*init_options) PARAMS ((void));
+     initialization needed before any calls to handle_option.  Return
+     the language mask to filter the switch array with.  */
+  int (*init_options) PARAMS ((void));
 
   /* Function called with an option vector as argument, to decode a
      single option (typically starting with -f or -W or +).  It should
@@ -209,8 +210,19 @@ struct lang_hooks
      option.  If this function returns a negative number, then its
      absolute value is the number of command-line arguments used, but,
      in addition, no language-independent option processing should be
-     done for this option.  */
+     done for this option.  Obsoleted by handle_option.  */
   int (*decode_option) PARAMS ((int, char **));
+
+  /* Handle the switch CODE, which has real type enum opt_code from
+     options.h.  If the switch takes an argument, it is passed in ARG
+     which points to permanent storage.  The handler is resonsible for
+     checking whether ARG is NULL, which indicates that no argument
+     was in fact supplied.  For -f and -W switches, VALUE is 1 or 0
+     for the positive and negative forms respectively.
+
+     Return 1 if the switch is valid, 0 if invalid, and -1 if it's
+     valid and should not be treated as language-independent too.  */
+  int (*handle_option) (size_t code, const char *arg, int value);
 
   /* Called when all command line options have been parsed to allow
      further processing and initialization
============================================================
Index: gcc/opts.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/opts.c	6 Jun 2003 20:31:58 -0000
@@ -0,0 +1,209 @@
+/* Command line option handling.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Neil Booth.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "langhooks.h"
+#include "opts.h"
+#include "options.h"
+
+static enum opt_code find_opt (const char *, int);
+
+/* Perform a binary search to find which option the command-line INPUT
+   matches.  Returns its index in the option array, and N_OPTS on
+   failure.
+
+   Complications arise since some options can be suffixed with an
+   argument, and multiple complete matches can occur, e.g. -pedantic
+   and -pedantic-errors.  Also, some options are only accepted by some
+   languages.  If a switch matches for a different language and
+   doesn't match any alternatives for the true front end, the index of
+   the matched switch is returned anyway.  The caller should check for
+   this case.  */
+static enum opt_code
+find_opt (const char *input, int lang_mask)
+{
+  size_t md, mn, mx;
+  size_t opt_len;
+  enum opt_code result = N_OPTS;
+  int comp;
+
+  mn = 0;
+  mx = N_OPTS;
+
+  while (mx > mn)
+    {
+      md = (mn + mx) / 2;
+
+      opt_len = cl_options[md].opt_len;
+      comp = strncmp (input, cl_options[md].opt_text, opt_len);
+
+      if (comp < 0)
+	mx = md;
+      else if (comp > 0)
+	mn = md + 1;
+      else
+	{
+	  /* The switch matches.  It it an exact match?  */
+	  if (input[opt_len] == '\0')
+	    return md;
+	  else
+	    {
+	      mn = md + 1;
+
+	      /* If the switch takes no arguments this is not a proper
+		 match, so we continue the search (e.g. input="stdc++"
+		 match was "stdc").  */
+	      if (!(cl_options[md].flags & CL_JOINED))
+		continue;
+
+	      /* Is this switch valid for this front end?  */
+	      if (!(cl_options[md].flags & lang_mask))
+		{
+		  /* If subsequently we don't find a better match,
+		     return this and let the caller report it as a bad
+		     match.  */
+		  result = (enum opt_code) md;
+		  continue;
+		}
+
+	      /* Two scenarios remain: we have the switch's argument,
+		 or we match a longer option.  This can happen with
+		 -iwithprefix and -withprefixbefore.  The longest
+		 possible option match succeeds.
+
+		 Scan forwards, and return an exact match.  Otherwise
+		 return the longest valid option-accepting match (mx).
+		 This loops at most twice with current options.  */
+	      mx = md;
+	      for (md = md + 1; md < N_OPTS; md++)
+		{
+		  opt_len = cl_options[md].opt_len;
+		  if (strncmp (input, cl_options[md].opt_text, opt_len))
+		    break;
+		  if (input[opt_len] == '\0')
+		    return md;
+		  if (cl_options[md].flags & lang_mask
+		      && cl_options[md].flags & CL_JOINED)
+		    mx = md;
+		}
+
+	      return mx;
+	    }
+	}
+    }
+
+  return result;
+}
+
+/* Handle the switch beginning at ARGV, with ARGC remaining.  */
+int
+handle_option (int argc, char **argv, int lang_mask)
+{
+  size_t opt_index;
+  const char *opt, *arg = 0;
+  char *dup = 0;
+  bool on = true;
+  int result = 0, temp;
+  const struct cl_option *option;
+
+  /* If the front end isn't yet converted, use the old hook.  */
+  if (!lang_hooks.handle_option)
+    return (*lang_hooks.decode_option) (argc, argv);
+
+  opt = argv[0];
+
+  /* Interpret "-" or a non-switch as a file name.  */
+  if (opt[0] != '-' || opt[1] == '\0')
+    {
+      opt_index = N_OPTS;
+      arg = opt;
+      result = 1;
+    }
+  else
+    {
+      /* Drop the "no-" from negative switches.  */
+      if ((opt[1] == 'W' || opt[1] == 'f')
+	  && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+	{
+	  size_t len = strlen (opt) - 3;
+
+	  dup = xmalloc (len + 1);
+	  dup[0] = '-';
+	  dup[1] = opt[1];
+	  memcpy (dup + 2, opt + 5, len - 2 + 1);
+	  opt = dup;
+	  on = false;
+	}
+
+      /* Skip over '-'.  */
+      opt_index = find_opt (opt + 1, lang_mask);
+      if (opt_index == N_OPTS)
+	goto done;
+
+      option = &cl_options[opt_index];
+
+      /* Reject negative form of switches that don't take negatives.  */
+      if (!on && (option->flags & CL_REJECT_NEGATIVE))
+	goto done;
+
+      /* We've recognised this switch.  */
+      result = 1;
+
+      /* Sort out any argument the switch takes.  */
+      if (option->flags & (CL_JOINED | CL_SEPARATE))
+	{
+	  if (option->flags & CL_JOINED)
+	    {
+	      /* Have arg point to the original switch.  This is because
+		 some code, such as disable_builtin_function, expects its
+		 argument to be persistent until the program exits.  */
+	      arg = argv[0] + cl_options[opt_index].opt_len + 1;
+	      if (!on)
+		arg += strlen ("no-");
+	    }
+
+	  /* If we don't have an argument, and CL_SEPARATE, try the next
+	     argument in the vector.  */
+	  if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
+	    {
+	      arg = argv[1];
+	      result = 2;
+	    }
+
+	  /* Canonicalize missing arguments as NULL for the handler.  */
+	  if (*arg == '\0')
+	    arg = NULL;
+	}
+    }
+
+  temp = (*lang_hooks.handle_option) (opt_index, arg, on);
+  if (temp <= 0)
+    result = temp;
+
+ done:
+  if (dup)
+    free (dup);
+  return result;
+}
============================================================
Index: gcc/opts.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/opts.h	6 Jun 2003 20:31:58 -0000
@@ -0,0 +1,34 @@
+/* Command line option handling.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#ifndef GCC_OPTS_H
+#define GCC_OPTS_H
+
+extern int handle_option (int argc, char **argv, int lang_mask);
+
+#define CL_C			(1 << 0) /* Only C.  */
+#define CL_OBJC			(1 << 1) /* Only ObjC.  */
+#define CL_CXX			(1 << 2) /* Only C++.  */
+#define CL_OBJCXX		(1 << 3) /* Only ObjC++.  */
+#define CL_JOINED		(1 << 4) /* If takes joined argument.  */
+#define CL_SEPARATE		(1 << 5) /* If takes a separate argument.  */
+#define CL_REJECT_NEGATIVE	(1 << 6) /* Reject no- form.  */
+
+#endif
============================================================
Index: gcc/opts.sh
--- gcc/opts.sh	2 Jun 2003 05:48:29 -0000	1.4
+++ gcc/opts.sh	6 Jun 2003 20:31:58 -0000
@@ -65,9 +65,12 @@ cat "$@" | ${AWK} '
 	print "  const char *opt_text;"			>> h_file
 	print "  unsigned char opt_len;"		>> h_file
 	print "  unsigned char flags;"			>> h_file
-	print "};\n"					>> h_file
+	print "};\n\n"					>> h_file
+	print "extern const struct cl_option cl_options[];\n" >> h_file
 	print "enum opt_code\n{"			>> h_file
-	print "static const struct cl_option cl_options[] =\n{" >> c_file
+	print "#include \"options.h\""			>> c_file
+	print "#include \"opts.h\"\n"			>> c_file
+	print "const struct cl_option cl_options[] =\n{" >> c_file
     }
 
     {
============================================================
Index: gcc/toplev.c
--- gcc/toplev.c	6 Jun 2003 09:24:26 -0000	1.766
+++ gcc/toplev.c	6 Jun 2003 20:32:00 -0000
@@ -76,6 +76,7 @@ Software Foundation, 59 Temple Place - S
 #include "cfgloop.h"
 #include "hosthooks.h"
 #include "cgraph.h"
+#include "opts.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -1457,7 +1458,7 @@ documented_lang_options[] =
 
 #define DEFINE_LANG_NAME(NAME) { NULL, NAME },
 
-#include "options.h"
+#include "options_.h"
 
 };
 
@@ -5134,7 +5135,7 @@ general_init (char *argv0)
 static void
 parse_options_and_default_flags (int argc, char **argv)
 {
-  int i;
+  int i, lang_mask;
 
   /* Save in case md file wants to emit args as a comment.  */
   save_argc = argc;
@@ -5150,7 +5151,7 @@ parse_options_and_default_flags (int arg
   init_ggc_heuristics();
 
   /* Perform language-specific options initialization.  */
-  (*lang_hooks.init_options) ();
+  lang_mask = (*lang_hooks.init_options) ();
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
@@ -5287,7 +5288,7 @@ parse_options_and_default_flags (int arg
       int indep_processed;
 
       /* Give the language a chance to decode the option for itself.  */
-      lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i);
+      lang_processed = handle_option (argc - i, argv + i, lang_mask);
 
       if (lang_processed >= 0)
 	/* Now see if the option also has a language independent meaning.
============================================================
Index: gcc/ada/misc.c
--- gcc/ada/misc.c	7 Apr 2003 06:03:12 -0000	1.48
+++ gcc/ada/misc.c	6 Jun 2003 20:32:00 -0000
@@ -81,7 +81,7 @@ extern char **save_argv;
 
 static size_t gnat_tree_size		PARAMS ((enum tree_code));
 static bool gnat_init			PARAMS ((void));
-static void gnat_init_options		PARAMS ((void));
+static int gnat_init_options		PARAMS ((void));
 static int gnat_decode_option		PARAMS ((int, char **));
 static HOST_WIDE_INT gnat_get_alias_set	PARAMS ((tree));
 static void gnat_print_decl		PARAMS ((FILE *, tree, int));
@@ -300,13 +300,15 @@ gnat_decode_option (argc, argv)
 
 /* Initialize for option processing.  */
 
-static void
+static int
 gnat_init_options ()
 {
   /* Initialize gnat_argv with save_argv size */
   gnat_argv = (char **) xmalloc ((save_argc + 1) * sizeof (gnat_argv[0])); 
   gnat_argv[0] = save_argv[0];     /* name of the command */ 
   gnat_argc = 1;
+
+  return 0;
 }
 
 /* Here is the function to handle the compiler error processing in GCC.  */
============================================================
Index: gcc/cp/cp-lang.c
--- gcc/cp/cp-lang.c	7 Apr 2003 06:03:14 -0000	1.49
+++ gcc/cp/cp-lang.c	6 Jun 2003 20:32:00 -0000
@@ -49,8 +49,8 @@ static bool cp_var_mod_type_p (tree);
 #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS cxx_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
 #undef LANG_HOOKS_POST_OPTIONS
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_GET_ALIAS_SET
============================================================
Index: gcc/cp/cp-tree.h
--- gcc/cp/cp-tree.h	4 Jun 2003 01:06:08 -0000	1.848
+++ gcc/cp/cp-tree.h	6 Jun 2003 20:32:01 -0000
@@ -3898,7 +3898,7 @@ extern void yyhook				(int);
 extern int cp_type_qual_from_rid                (tree);
 extern bool cxx_init				(void);
 extern void cxx_finish (void);
-extern void cxx_init_options (void);
+extern int cxx_init_options (void);
 
 /* in method.c */
 extern void init_method	(void);
============================================================
Index: gcc/cp/lex.c
--- gcc/cp/lex.c	10 May 2003 11:29:51 -0000	1.304
+++ gcc/cp/lex.c	6 Jun 2003 20:32:02 -0000
@@ -150,11 +150,9 @@ int interface_unknown;		/* whether or no
 
 
 /* Initialization before switch parsing.  */
-void
+int
 cxx_init_options ()
 {
-  c_common_init_options (clk_cplusplus);
-
   /* Default exceptions on.  */
   flag_exceptions = 1;
   /* By default wrap lines at 80 characters.  Is getenv ("COLUMNS")
@@ -163,6 +161,8 @@ cxx_init_options ()
   /* By default, emit location information once for every
      diagnostic message.  */
   diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+
+  return c_common_init_options (clk_cplusplus);
 }
 
 void
============================================================
Index: gcc/f/com.c
--- gcc/f/com.c	1 Jun 2003 07:21:02 -0000	1.198
+++ gcc/f/com.c	6 Jun 2003 20:32:05 -0000
@@ -14149,7 +14149,7 @@ insert_block (tree block)
 static bool ffe_init PARAMS ((void));
 static void ffe_finish PARAMS ((void));
 static bool ffe_post_options PARAMS ((const char **));
-static void ffe_init_options PARAMS ((void));
+static int ffe_init_options PARAMS ((void));
 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
 
 struct language_function GTY(())
@@ -14289,7 +14289,7 @@ ffe_finish ()
   fclose (finput);
 }
 
-static void
+static int
 ffe_init_options ()
 {
   /* Set default options for Fortran.  */
@@ -14299,6 +14299,8 @@ ffe_init_options ()
   flag_merge_constants = 2;
   flag_errno_math = 0;
   flag_complex_divide_method = 1;
+
+  return 0;
 }
 
 static bool
============================================================
Index: gcc/java/lang.c
--- gcc/java/lang.c	31 May 2003 13:23:30 -0000	1.124
+++ gcc/java/lang.c	6 Jun 2003 20:32:06 -0000
@@ -55,7 +55,7 @@ struct string_option
 
 static bool java_init (void);
 static void java_finish (void);
-static void java_init_options (void);
+static int java_init_options (void);
 static bool java_post_options (const char **);
 
 static int java_decode_option (int, char **);
@@ -731,7 +731,7 @@ void lang_init_source (int level)
   inhibit_error_function_printing = (level == 1);
 }
 
-static void
+static int
 java_init_options (void)
 {
   flag_bounds_check = 1;
@@ -743,6 +743,8 @@ java_init_options (void)
 
   /* In Java arithmetic overflow always wraps around.  */
   flag_wrapv = 1;
+
+  return 0;
 }
 
 static bool
============================================================
Index: gcc/objc/objc-lang.c
--- gcc/objc/objc-lang.c	26 Feb 2003 11:09:33 -0000	1.29
+++ gcc/objc/objc-lang.c	6 Jun 2003 20:32:06 -0000
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks.h"
 #include "langhooks-def.h"
 
-static void objc_init_options                   PARAMS ((void));
+static int objc_init_options                   PARAMS ((void));
 
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU Objective-C"
@@ -41,8 +41,8 @@ static void objc_init_options           
 #define LANG_HOOKS_FINISH c_common_finish
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS objc_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
 #undef LANG_HOOKS_POST_OPTIONS
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_GET_ALIAS_SET
@@ -164,9 +164,9 @@ const char * const tree_code_name[] = {
 };
 #undef DEFTREECODE
 
-static void 
+static int 
 objc_init_options ()
 {
   flag_objc = 1;
-  c_common_init_options (clk_c);
+  return c_common_init_options (clk_c);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]