OSDN Git Service

2005-06-03 Richard Guenther <rguenth@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 7c8723c..b26d767 100644 (file)
@@ -374,40 +374,6 @@ static const param_info lang_independent_params[] = {
   { NULL, 0, 0, 0, NULL }
 };
 
-#ifdef TARGET_SWITCHES
-/* Here is a table, controlled by the tm.h file, listing each -m switch
-   and which bits in `target_switches' it should set or clear.
-   If VALUE is positive, it is bits to set.
-   If VALUE is negative, -VALUE is bits to clear.
-   (The sign bit is not used so there is no confusion.)  */
-
-static const struct
-{
-  const char *const name;
-  const int value;
-  const char *const description;
-}
-target_switches[] = TARGET_SWITCHES;
-#endif
-
-/* This table is similar, but allows the switch to have a value.  */
-
-#ifdef TARGET_OPTIONS
-static const struct
-{
-  const char *const prefix;
-  const char **const variable;
-  const char *const description;
-  const char *const value;
-}
-target_options[] = TARGET_OPTIONS;
-#endif
-
-/* Nonzero means warn about function definitions that default the return type
-   or that use a null return and have a return-type other than void.  */
-
-int warn_return_type;
-
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
@@ -781,9 +747,11 @@ wrapup_global_declarations (tree *vec, int len)
              bool needed = 1;
              node = cgraph_varpool_node (decl);
 
-             if (flag_unit_at_a_time && node->finalized)
+             if (node->finalized)
+               needed = 0;
+             else if (node->alias)
                needed = 0;
-             else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
+             else if (!cgraph_global_info_ready
                       && (TREE_USED (decl)
                           || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
                /* needed */;
@@ -849,7 +817,7 @@ check_global_declarations (tree *vec, int len)
          if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
            pedwarn ("%J%qF used but never defined", decl, decl);
          else
-           warning ("%J%qF declared %<static%> but never defined",
+           warning (0, "%J%qF declared %<static%> but never defined",
                     decl, decl);
          /* This symbol is effectively an "extern" declaration now.  */
          TREE_PUBLIC (decl) = 1;
@@ -875,7 +843,7 @@ check_global_declarations (tree *vec, int len)
          && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
          /* Otherwise, ask the language.  */
          && lang_hooks.decls.warn_unused_global (decl))
-       warning ("%J%qD defined but not used", decl, decl);
+       warning (0, "%J%qD defined but not used", decl, decl);
 
       /* Avoid confusing the debug information machinery when there are
         errors.  */
@@ -898,7 +866,7 @@ warn_deprecated_use (tree node)
   if (DECL_P (node))
     {
       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));
-      warning ("%qs is deprecated (declared at %s:%d)",
+      warning (0, "%qs is deprecated (declared at %s:%d)",
               IDENTIFIER_POINTER (DECL_NAME (node)),
               xloc.file, xloc.line);
     }
@@ -921,18 +889,18 @@ warn_deprecated_use (tree node)
          expanded_location xloc
            = expand_location (DECL_SOURCE_LOCATION (decl));
          if (what)
-           warning ("%qs is deprecated (declared at %s:%d)", what,
+           warning (0, "%qs is deprecated (declared at %s:%d)", what,
                       xloc.file, xloc.line);
          else
-           warning ("type is deprecated (declared at %s:%d)",
+           warning (0, "type is deprecated (declared at %s:%d)",
                     xloc.file, xloc.line);
        }
       else
        {
          if (what)
-           warning ("%qs is deprecated", what);
+           warning (0, "%qs is deprecated", what);
          else
-           warning ("type is deprecated");
+           warning (0, "type is deprecated");
        }
     }
 }
@@ -1060,92 +1028,6 @@ compile_file (void)
   targetm.asm_out.file_end ();
 }
 
-/* Display help for target options.  */
-void
-display_target_options (void)
-{
-  int undoc;
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
-  int i;
-#endif
-  unsigned int cli;
-  static bool displayed = false;
-
-  /* Avoid double printing for --help --target-help.  */
-  if (displayed)
-    return;
-
-  displayed = true;
-
-  for (cli = 0; cli < cl_options_count; cli++)
-    if ((cl_options[cli].flags & (CL_TARGET | CL_UNDOCUMENTED)) == CL_TARGET)
-      break;
-
-  if (cli < cl_options_count
-#ifdef TARGET_SWITCHES
-      || ARRAY_SIZE (target_switches) > 1
-#endif
-#ifdef TARGET_OPTIONS
-      || ARRAY_SIZE (target_options) > 1
-#endif
-      )
-    {
-      int doc = cli < cl_options_count;
-
-      undoc = 0;
-
-      printf (_("\nTarget specific options:\n"));
-
-#ifdef TARGET_SWITCHES
-      for (i = ARRAY_SIZE (target_switches); i--;)
-       {
-         const char *option      = target_switches[i].name;
-         const char *description = target_switches[i].description;
-
-         if (option == NULL || *option == 0)
-           continue;
-         else if (description == NULL)
-           {
-             undoc = 1;
-
-             if (extra_warnings)
-               printf (_("  -m%-23s [undocumented]\n"), option);
-           }
-         else if (*description != 0)
-           doc += printf ("  -m%-23s %s\n", option, _(description));
-       }
-#endif
-
-#ifdef TARGET_OPTIONS
-      for (i = ARRAY_SIZE (target_options); i--;)
-       {
-         const char *option      = target_options[i].prefix;
-         const char *description = target_options[i].description;
-
-         if (option == NULL || *option == 0)
-           continue;
-         else if (description == NULL)
-           {
-             undoc = 1;
-
-             if (extra_warnings)
-               printf (_("  -m%-23s [undocumented]\n"), option);
-           }
-         else if (*description != 0)
-           doc += printf ("  -m%-23s %s\n", option, _(description));
-       }
-#endif
-      print_filtered_help (CL_TARGET);
-      if (undoc)
-       {
-         if (doc)
-           printf (_("\nThere are undocumented target specific options as well.\n"));
-         else
-           printf (_("  They exist, but they are not documented.\n"));
-       }
-    }
-}
-
 /* Parse a -d... command line switch.  */
 
 void
@@ -1185,7 +1067,7 @@ decode_d_option (const char *arg)
       case 'a':
       default:
        if (!enable_rtl_dump_file (c))
-         warning ("unrecognized gcc debugging option: %c", c);
+         warning (0, "unrecognized gcc debugging option: %c", c);
        break;
       }
 }
@@ -1196,64 +1078,6 @@ const char *const debug_type_names[] =
   "none", "stabs", "coff", "dwarf-2", "xcoff", "vms"
 };
 
-/* Decode -m switches.  */
-/* Decode the switch -mNAME.  */
-
-void
-set_target_switch (const char *name)
-{
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
-  size_t j;
-#endif
-  int valid_target_option = 0;
-
-#ifdef TARGET_SWITCHES
-  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;
-       if (name[0] != 0)
-         {
-           if (target_switches[j].value < 0)
-             target_flags_explicit |= -target_switches[j].value;
-           else
-             target_flags_explicit |= target_switches[j].value;
-         }
-       valid_target_option = 1;
-      }
-#endif
-
-#ifdef TARGET_OPTIONS
-  if (!valid_target_option)
-    for (j = 0; j < ARRAY_SIZE (target_options); j++)
-      {
-       int len = strlen (target_options[j].prefix);
-       if (target_options[j].value)
-         {
-           if (!strcmp (target_options[j].prefix, name))
-             {
-               *target_options[j].variable = target_options[j].value;
-               valid_target_option = 1;
-             }
-         }
-       else
-         {
-           if (!strncmp (target_options[j].prefix, name, len))
-             {
-               *target_options[j].variable = name + len;
-               valid_target_option = 1;
-             }
-         }
-      }
-#endif
-
-  if (name[0] != 0 && !valid_target_option)
-    error ("invalid option %qs", name);
-}
-
 /* Print version information to FILE.
    Each line begins with INDENT (for the case where FILE is the
    assembler output file).  */
@@ -1358,35 +1182,10 @@ print_switch_values (FILE *file, int pos, int max,
 
   for (j = 0; j < cl_options_count; j++)
     if ((cl_options[j].flags & CL_REPORT)
-       && option_enabled (&cl_options[j]) > 0)
+       && option_enabled (j) > 0)
       pos = print_single_switch (file, pos, max, indent, sep, term,
                                 "", cl_options[j].opt_text);
 
-  /* Print target specific options.  */
-
-#ifdef TARGET_SWITCHES
-  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);
-      }
-#endif
-
-#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);
 }
 
@@ -1437,6 +1236,21 @@ init_asm_output (const char *name)
     }
 }
 
+/* Return true if the state of option OPTION should be stored in PCH files
+   and checked by default_pch_valid_p.  Store the option's current state
+   in STATE if so.  */
+
+static inline bool
+option_affects_pch_p (int option, struct cl_option_state *state)
+{
+  if ((cl_options[option].flags & CL_TARGET) == 0)
+    return false;
+  if (cl_options[option].flag_var == &target_flags)
+    if (targetm.check_pch_target_flags)
+      return false;
+  return get_option_state (option, state);
+}
+
 /* Default version of get_pch_validity.
    By default, every flag difference is fatal; that will be mostly right for
    most targets, but completely right for very few.  */
@@ -1444,51 +1258,58 @@ init_asm_output (const char *name)
 void *
 default_get_pch_validity (size_t *len)
 {
-#ifdef TARGET_OPTIONS
+  struct cl_option_state state;
   size_t i;
-#endif
   char *result, *r;
 
-  *len = sizeof (target_flags) + 2;
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
-    {
-      *len += 1;
-      if (*target_options[i].variable)
-       *len += strlen (*target_options[i].variable);
-    }
-#endif
+  *len = 2;
+  if (targetm.check_pch_target_flags)
+    *len += sizeof (target_flags);
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      *len += state.size;
 
   result = r = xmalloc (*len);
   r[0] = flag_pic;
   r[1] = flag_pie;
   r += 2;
-  memcpy (r, &target_flags, sizeof (target_flags));
-  r += sizeof (target_flags);
-
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
+  if (targetm.check_pch_target_flags)
     {
-      const char *str = *target_options[i].variable;
-      size_t l;
-      if (! str)
-       str = "";
-      l = strlen (str) + 1;
-      memcpy (r, str, l);
-      r += l;
+      memcpy (r, &target_flags, sizeof (target_flags));
+      r += sizeof (target_flags);
     }
-#endif
+
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       memcpy (r, state.data, state.size);
+       r += state.size;
+      }
 
   return result;
 }
 
+/* Return a message which says that a PCH file was created with a different
+   setting of OPTION.  */
+
+static const char *
+pch_option_mismatch (const char *option)
+{
+  char *r;
+
+  asprintf (&r, _("created and used with differing settings of '%s'"), option);
+  if (r == NULL)
+    return _("out of memory");
+  return r;
+}
+
 /* Default version of pch_valid_p.  */
 
 const char *
 default_pch_valid_p (const void *data_p, size_t len)
 {
+  struct cl_option_state state;
   const char *data = (const char *)data_p;
-  const char *flag_that_differs = NULL;
   size_t i;
 
   /* -fpic and -fpie also usually make a PCH invalid.  */
@@ -1499,68 +1320,29 @@ default_pch_valid_p (const void *data_p, size_t len)
   data += 2;
 
   /* Check target_flags.  */
-  if (memcmp (data, &target_flags, sizeof (target_flags)) != 0)
+  if (targetm.check_pch_target_flags)
     {
       int tf;
+      const char *r;
 
       memcpy (&tf, data, sizeof (target_flags));
-#ifdef TARGET_SWITCHES
-      for (i = 0; i < ARRAY_SIZE (target_switches); i++)
-       {
-         int bits;
-
-         bits = target_switches[i].value;
-         if (bits < 0)
-           bits = -bits;
-         if ((target_flags & bits) != (tf & bits))
-           {
-             flag_that_differs = target_switches[i].name;
-             goto make_message;
-           }
-       }
-#endif
-      for (i = 0; i < cl_options_count; i++)
-       if (cl_options[i].flag_var == &target_flags
-           && (cl_options[i].var_value & (target_flags ^ tf)) != 0)
-         {
-           flag_that_differs = cl_options[i].opt_text + 2;
-           goto make_message;
-         }
-      gcc_unreachable ();
+      data += sizeof (target_flags);
+      len -= sizeof (target_flags);
+      r = targetm.check_pch_target_flags (tf);
+      if (r != NULL)
+       return r;
     }
-  data += sizeof (target_flags);
-  len -= sizeof (target_flags);
 
-  /* Check string options.  */
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
-    {
-      const char *str = *target_options[i].variable;
-      size_t l;
-      if (! str)
-       str = "";
-      l = strlen (str) + 1;
-      if (len < l || memcmp (data, str, l) != 0)
-       {
-         flag_that_differs = target_options[i].prefix;
-         goto make_message;
-       }
-      data += l;
-      len -= l;
-    }
-#endif
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       if (memcmp (data, state.data, state.size) != 0)
+         return pch_option_mismatch (cl_options[i].opt_text);
+       data += state.size;
+       len -= state.size;
+      }
 
   return NULL;
-
- make_message:
-  {
-    char *r;
-    asprintf (&r, _("created and used with differing settings of '-m%s'"),
-                 flag_that_differs);
-    if (r == NULL)
-      return _("out of memory");
-    return r;
-  }
 }
 
 /* Default tree printer.   Handles declarations only.  */
@@ -1573,7 +1355,7 @@ default_tree_printer (pretty_printer * pp, text_info *text)
     {
     case 'D':
       t = va_arg (*text->args_ptr, tree);
-      if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+      if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
        t = DECL_DEBUG_EXPR (t);
       break;
 
@@ -1616,6 +1398,9 @@ general_init (const char *argv0)
 
   hex_init ();
 
+  /* Unlock the stdio streams.  */
+  unlock_std_streams ();
+
   gcc_init_libintl ();
 
   /* Initialize the diagnostics reporting machinery, so option parsing
@@ -1766,11 +1551,11 @@ process_options (void)
   /* Warn about options that are not supported on this machine.  */
 #ifndef INSN_SCHEDULING
   if (flag_schedule_insns || flag_schedule_insns_after_reload)
-    warning ("instruction scheduling not supported on this target machine");
+    warning (0, "instruction scheduling not supported on this target machine");
 #endif
 #ifndef DELAY_SLOTS
   if (flag_delayed_branch)
-    warning ("this target machine does not have delayed branches");
+    warning (0, "this target machine does not have delayed branches");
 #endif
 
   user_label_prefix = USER_LABEL_PREFIX;
@@ -1784,7 +1569,7 @@ process_options (void)
          user_label_prefix = flag_leading_underscore ? "_" : "";
        }
       else
-       warning ("-f%sleading-underscore not supported on this target machine",
+       warning (0, "-f%sleading-underscore not supported on this target machine",
                 flag_leading_underscore ? "" : "no-");
     }
 
@@ -1870,10 +1655,10 @@ process_options (void)
       if (flag_var_tracking == 1)
         {
          if (debug_info_level < DINFO_LEVEL_NORMAL)
-           warning ("variable tracking requested, but useless unless "
+           warning (0, "variable tracking requested, but useless unless "
                     "producing debug info");
          else
-           warning ("variable tracking requested, but not supported "
+           warning (0, "variable tracking requested, but not supported "
                     "by this debug format");
        }
       flag_var_tracking = 0;
@@ -1900,44 +1685,44 @@ process_options (void)
     {
       if (flag_function_sections)
        {
-         warning ("-ffunction-sections not supported for this target");
+         warning (0, "-ffunction-sections not supported for this target");
          flag_function_sections = 0;
        }
       if (flag_data_sections)
        {
-         warning ("-fdata-sections not supported for this target");
+         warning (0, "-fdata-sections not supported for this target");
          flag_data_sections = 0;
        }
     }
 
   if (flag_function_sections && profile_flag)
     {
-      warning ("-ffunction-sections disabled; it makes profiling impossible");
+      warning (0, "-ffunction-sections disabled; it makes profiling impossible");
       flag_function_sections = 0;
     }
 
 #ifndef HAVE_prefetch
   if (flag_prefetch_loop_arrays)
     {
-      warning ("-fprefetch-loop-arrays not supported for this target");
+      warning (0, "-fprefetch-loop-arrays not supported for this target");
       flag_prefetch_loop_arrays = 0;
     }
   if (flag_speculative_prefetching)
     {
       if (flag_speculative_prefetching_set)
-       warning ("-fspeculative-prefetching not supported for this target");
+       warning (0, "-fspeculative-prefetching not supported for this target");
       flag_speculative_prefetching = 0;
     }
 #else
   if (flag_prefetch_loop_arrays && !HAVE_prefetch)
     {
-      warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)");
+      warning (0, "-fprefetch-loop-arrays not supported for this target (try -march switches)");
       flag_prefetch_loop_arrays = 0;
     }
   if (flag_speculative_prefetching && !HAVE_prefetch)
     {
       if (flag_speculative_prefetching_set)
-       warning ("-fspeculative-prefetching not supported for this target (try -march switches)");
+       warning (0, "-fspeculative-prefetching not supported for this target (try -march switches)");
       flag_speculative_prefetching = 0;
     }
 #endif
@@ -1946,13 +1731,13 @@ process_options (void)
      make much sense anyway, so don't allow it.  */
   if (flag_prefetch_loop_arrays && optimize_size)
     {
-      warning ("-fprefetch-loop-arrays is not supported with -Os");
+      warning (0, "-fprefetch-loop-arrays is not supported with -Os");
       flag_prefetch_loop_arrays = 0;
     }
 
 #ifndef OBJECT_FORMAT_ELF
   if (flag_function_sections && write_symbols != NO_DEBUG)
-    warning ("-ffunction-sections may affect debugging on some targets");
+    warning (0, "-ffunction-sections may affect debugging on some targets");
 #endif
 
   /* The presence of IEEE signaling NaNs, implies all math can trap.  */