OSDN Git Service

Rework specs to subtarget specs and EXTRA_SPECS
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index a05ebd5..e614152 100644 (file)
@@ -62,6 +62,7 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "bytecode.h"
 #include "bc-emit.h"
+#include "except.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
@@ -92,6 +93,36 @@ vms_fopen (fname, type)
 #define DEFAULT_GDB_EXTENSIONS 1
 #endif
 
+/* If more than one debugging type is supported, you must define
+   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. 
+
+   This is one long line cause VAXC can't handle a \-newline.  */
+#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
+#ifndef PREFERRED_DEBUGGING_TYPE
+You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
+#endif /* no PREFERRED_DEBUGGING_TYPE */
+#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
+        so the following code needn't care.  */
+#ifdef DBX_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#endif
+#ifdef SDB_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+#endif
+#ifdef XCOFF_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
+#endif
+#endif /* More than one debugger format enabled.  */
+
+/* If still not defined, must have been because no debugging formats
+   are supported.  */
+#ifndef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
+#endif
+
 extern int rtx_equal_function_value_matters;
 
 #if ! (defined (VMS) || defined (OS2))
@@ -271,12 +302,6 @@ struct rtx_def *(*lang_expand_expr) ();
 
 void (*incomplete_decl_finalize_hook) () = 0;
 
-/* Pointer to function for interim exception handling implementation.
-   This interface will change, and it is only here until a better interface
-   replaces it.  */
-
-void (*interim_eh_hook)        PROTO((tree));
-
 /* Highest label number used at the end of reload.  */
 
 int max_label_num_after_reload;
@@ -492,8 +517,13 @@ int flag_short_temps;
 
 int flag_pic;
 
+/* Nonzero means generate extra code for exception handling and enable
+   exception handling.  */
+
+int flag_exceptions = 1;
+
 /* Nonzero means don't place uninitialized global data in common storage
-   by default. */
+   by default.  */
 
 int flag_no_common;
 
@@ -593,6 +623,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"schedule-insns2", &flag_schedule_insns_after_reload, 1},
   {"pic", &flag_pic, 1},
   {"PIC", &flag_pic, 2},
+  {"exceptions", &flag_exceptions, 1},
   {"fast-math", &flag_fast_math, 1},
   {"common", &flag_no_common, 0},
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
@@ -997,15 +1028,6 @@ decl_name (decl, kind)
 {
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
-
-/* This is the default interim_eh_hook function.  */
-
-void
-interim_eh (finalization)
-     tree finalization;
-{
-  /* Don't do anything by default.  */
-}
 \f
 static int need_error_newline;
 
@@ -2416,6 +2438,12 @@ compile_file (name)
          }
       }
 
+    /* Now that all possible functions have been output, we can dump
+       the exception table.  */
+
+    if (exception_table_p ())
+      output_exception_table ();
+
     for (i = 0; i < len; i++)
       {
        decl = vec[i];
@@ -2492,6 +2520,7 @@ compile_file (name)
           and definitions which have not yet been forced out.  */
 
        if (write_symbols == DWARF_DEBUG
+           && (TREE_CODE (decl) != VAR_DECL || DECL_RTL (decl) != 0)
            && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
          TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
 #endif
@@ -2723,6 +2752,16 @@ rest_of_type_compilation (type, toplev)
   if (write_symbols == SDB_DEBUG)
     TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
 #endif
+#ifdef DWARF_DEBUGGING_INFO
+  /* If this is a file-scope or function-scope type, or a class-scope type
+     for which the containing class has already been completed, write it
+     out now to avoid ordering headaches with member functions.  */
+  if (write_symbols == DWARF_DEBUG
+      && (TYPE_CONTEXT (type) == NULL_TREE
+         || TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) != 't'
+         || TREE_ASM_WRITTEN (TYPE_CONTEXT (type))))
+    TIMEVAR (symout_time, dwarfout_file_scope_decl (TYPE_STUB_DECL (type), 0));
+#endif
 }
 
 /* This is called from finish_function (within yyparse)
@@ -2894,6 +2933,9 @@ rest_of_compilation (decl)
     FINALIZE_PIC;
 #endif
 
+  /* Add an unwinder for exception handling, if needed.  */
+  emit_unwinder ();
+
   insns = get_insns ();
 
   /* Copy any shared structure that should not be shared.  */
@@ -2909,6 +2951,9 @@ rest_of_compilation (decl)
      for all references to such slots.  */
 /*   fixup_stack_slots (); */
 
+  /* Find all the EH handlers.  */
+  find_exception_handler_labels ();
+
   /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
      are initialized and to compute whether control can drop off the end
      of the function.  */
@@ -3430,7 +3475,6 @@ main (argc, argv, envp)
 
   decl_printable_name = decl_name;
   lang_expand_expr = (struct rtx_def *(*)()) do_abort;
-  interim_eh_hook = interim_eh;
 
   /* Initialize whether `char' is signed.  */
   flag_signed_char = DEFAULT_SIGNED_CHAR;
@@ -3782,6 +3826,47 @@ main (argc, argv, envp)
              char *q;
              unsigned len;
              unsigned level;
+             /* A lot of code assumes write_symbols == NO_DEBUG if the
+                debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
+                of what debugging type has been selected).  This records the
+                selected type.  It is an error to specify more than one
+                debugging type.  */
+             static enum debug_info_type selected_debug_type = NO_DEBUG;
+             /* Non-zero if debugging format has been explicitly set.
+                -g and -ggdb don't explicitly set the debugging format so
+                -gdwarf -g3 is equivalent to -gdwarf3.  */
+             static int type_explicitly_set_p = 0;
+             /* Table of supported debugging formats.  */
+             static struct {
+               char *arg;
+               /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
+                  constant expression, we use NO_DEBUG in its place.  */
+               enum debug_info_type debug_type;
+               int use_extensions_p;
+             } *da, debug_args[] = {
+               { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS },
+               { "ggdb", NO_DEBUG, 1 },
+#ifdef DBX_DEBUGGING_INFO
+               { "gstabs", DBX_DEBUG, 0 },
+               { "gstabs+", DBX_DEBUG, 1 },
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+               { "gdwarf", DWARF_DEBUG, 0 },
+               { "gdwarf+", DWARF_DEBUG, 1 },
+#endif
+#ifdef XCOFF_DEBUGGING_INFO
+               { "gxcoff", XCOFF_DEBUG, 0 },
+               { "gxcoff+", XCOFF_DEBUG, 1 },
+#endif
+#ifdef SDB_DEBUGGING_INFO
+               { "gcoff", SDB_DEBUG, 0 },
+#endif
+               { 0, 0, 0 }
+             };
+             /* Indexed by enum debug_info_type.  */
+             static char *debug_type_names[] = {
+               "none", "stabs", "coff", "dwarf", "xcoff"
+             };
 
              while (*p && (*p < '0' || *p > '9'))
                p++;
@@ -3797,114 +3882,54 @@ main (argc, argv, envp)
                {
                  warning ("invalid debug level specification in option: `-%s'",
                           str);
+                 /* ??? This error message is incorrect in the case of
+                    -g4 -g.  */
                  warning ("no debugging information will be generated");
                  level = 0;
                }
 
-             /* If more than one debugging type is supported,
-                you must define PREFERRED_DEBUGGING_TYPE
-                to choose a format in a system-dependent way.  */
-             /* This is one long line cause VAXC can't handle a \-newline.  */
-#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
-#ifdef PREFERRED_DEBUGGING_TYPE
-             if (!strncmp (str, "ggdb", len))
-               write_symbols = PREFERRED_DEBUGGING_TYPE;
-#else /* no PREFERRED_DEBUGGING_TYPE */
-You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
-#endif /* no PREFERRED_DEBUGGING_TYPE */
-#endif /* More than one debugger format enabled.  */
-#ifdef DBX_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = DBX_DEBUG;
-             else if (!strncmp (str, "gstabs", len))
-               write_symbols = DBX_DEBUG;
-             else if (!strncmp (str, "gstabs+", len))
-               write_symbols = DBX_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gstabs+, 
-                always disable for -gstabs.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DBX_DEBUG && !strncmp (str, "gstabs+", len)
-                      && len >= 7)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DBX_DEBUG
-                      && !strncmp (str, "gstabs", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
-#endif /* DBX_DEBUGGING_INFO */
-#ifdef DWARF_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = DWARF_DEBUG;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = DWARF_DEBUG;
-             else if (!strncmp (str, "gdwarf", len))
-               write_symbols = DWARF_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gdwarf+, 
-                always disable for -gdwarf.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == DWARF_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DWARF_DEBUG && !strcmp (str, "gdwarf+"))
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DWARF_DEBUG
-                      && !strncmp (str, "gdwarf", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
-#endif
-#ifdef SDB_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = SDB_DEBUG;
-             else if (!strncmp (str, "gdb", len))
-               write_symbols = SDB_DEBUG;
-             else if (!strncmp (str, "gcoff", len))
-               write_symbols = SDB_DEBUG;
-#endif /* SDB_DEBUGGING_INFO */
-#ifdef XCOFF_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = XCOFF_DEBUG;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = XCOFF_DEBUG;
-             else if (!strncmp (str, "gxcoff", len))
-               write_symbols = XCOFF_DEBUG;
-             else if (!strncmp (str, "gxcoff+", len))
-               write_symbols = XCOFF_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gxcoff+,
-                always disable for -gxcoff.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == XCOFF_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == XCOFF_DEBUG && !strcmp (str, "gxcoff+"))
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == XCOFF_DEBUG
-                      && !strncmp (str, "gxcoff", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
-#endif       
-             if (write_symbols == NO_DEBUG)
+             /* Look up STR in the table.  */
+             for (da = debug_args; da->arg; da++)
+               {
+                 if (! strncmp (str, da->arg, len))
+                   {
+                     enum debug_info_type type = da->debug_type;
+                     /* ??? A few targets use STR and LEN in the
+                        definition of PREFERRED_DEBUGGING_TYPE!  */
+                     if (type == NO_DEBUG)
+                       type = PREFERRED_DEBUGGING_TYPE;
+
+                     /* 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 (level == 0)
-               write_symbols = NO_DEBUG;
-             else
-               debug_info_level = (enum debug_info_level) level;
            }
          else if (!strcmp (str, "o"))
            {
@@ -3935,7 +3960,7 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
     {
 #ifndef TARGET_SUPPORTS_BYTECODE
       /* Just die with a fatal error if not supported */
-      fatal ("-fbytecode not supporter for this target");
+      fatal ("-fbytecode not supported for this target");
 #else
       bc_initialize ();
 #endif
@@ -4010,7 +4035,7 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 
   compile_file (filename);
 
-#if !defined(OS2) && !defined(VMS) && !defined(_WIN32)
+#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN32__))
   if (flag_print_mem)
     {
       char *lim = (char *) sbrk (0);
@@ -4025,7 +4050,7 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
       system ("ps v");
 #endif /* not USG */
     }
-#endif /* not OS2 and not VMS and not _WIN32 */
+#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN32) */
 
   if (errorcount)
     exit (FATAL_EXIT_CODE);
@@ -4112,7 +4137,8 @@ print_version (file, indent)
 }
 
 /* Print an option value and return the adjusted position in the line.
-   ??? We don't handle error returns from fprintf (disk full).  */
+   ??? We don't handle error returns from fprintf (disk full); presumably
+   other code will catch a disk full though.  */
 
 int
 print_single_switch (file, pos, max, indent, sep, term, type, name)
@@ -4120,17 +4146,23 @@ print_single_switch (file, pos, max, indent, sep, term, type, name)
      int pos, max;
      char *indent, *sep, *term, *type, *name;
 {
+  /* The ultrix fprintf returns 0 on success, so compute the result we want
+     here since we need it for the following test.  */
+  int len = strlen (sep) + strlen (type) + strlen (name);
+
   if (pos != 0
-      && pos + strlen (sep) + strlen (type) + strlen (name) > max)
+      && pos + len > max)
     {
       fprintf (file, "%s", term);
       pos = 0;
     }
   if (pos == 0)
     {
-      pos = fprintf (file, "%s", indent);
+      fprintf (file, "%s", indent);
+      pos = strlen (indent);
     }
-  pos += fprintf (file, "%s%s%s", sep, type, name);
+  fprintf (file, "%s%s%s", sep, type, name);
+  pos += len;
   return pos;
 }