OSDN Git Service

($(OBJC_O)): Also depend on $(GCC_PASSES).
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 583dda0..046ec32 100644 (file)
@@ -1,5 +1,5 @@
 /* Output sdb-format symbol table information from GNU compiler.
-   Copyright (C) 1988, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /*  mike@tredysvr.Tredydev.Unisys.COM says:
 I modified the struct.c example and have a nm of a .o resulting from the
@@ -47,21 +48,24 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "rtl.h"
 #include <stdio.h>
 #include "regs.h"
+#include "defaults.h"
 #include "flags.h"
 #include "insn-config.h"
 #include "reload.h"
 
-/* Mips systems use the SDB functions to dump out symbols, but
-   do not supply usable syms.h include files.  */
-#if defined(USG) && !defined(MIPS) && !defined (hpux)
+/* Mips systems use the SDB functions to dump out symbols, but do not
+   supply usable syms.h include files.  Which syms.h file to use is a
+   target parameter so don't use the native one if we're cross compiling.  */
+
+#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(CROSS_COMPILE)
 #include <syms.h>
 /* Use T_INT if we don't have T_VOID.  */
 #ifndef T_VOID
 #define T_VOID T_INT
 #endif
-#else /* not USG, or MIPS */
+#else
 #include "gsyms.h"
-#endif /* not USG, or MIPS */
+#endif
 
 /* #include <storclass.h>  used to be this instead of syms.h.  */
 
@@ -100,12 +104,20 @@ void sdbout_init ();
 void sdbout_symbol ();
 void sdbout_types();
 
-static void sdbout_typedefs ();
-static void sdbout_syms ();
-static void sdbout_one_type ();
-static void sdbout_queue_anonymous_type ();
-static void sdbout_dequeue_anonymous_types ();
-static int plain_type_1 ();
+static char *gen_fake_label            PROTO((void));
+static int plain_type                  PROTO((tree));
+static int template_name_p             PROTO((tree));
+static void sdbout_record_type_name    PROTO((tree));
+static int plain_type_1                        PROTO((tree, int));
+static void sdbout_block               PROTO((tree));
+static void sdbout_syms                        PROTO((tree));
+static void sdbout_queue_anonymous_type        PROTO((tree));
+static void sdbout_dequeue_anonymous_types PROTO((void));
+static void sdbout_type                        PROTO((tree));
+static void sbdout_field_types         PROTO((tree));
+static void sdbout_one_type            PROTO((tree));
+static void sdbout_parms               PROTO((tree));
+static void sdbout_reg_parms           PROTO((tree));
 \f
 /* Define the default sizes for various types.  */
 
@@ -276,6 +288,38 @@ do { fprintf (asm_out_file, "\t.def\t");           \
 /* Ensure we don't output a negative line number.  */
 #define MAKE_LINE_SAFE(line)  \
   if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1
+
+/* Perform linker optimization of merging header file definitions together
+   for targets with MIPS_DEBUGGING_INFO defined.  This won't work without a
+   post 960826 version of GAS.  Nothing breaks with earlier versions of GAS,
+   the optimization just won't be done.  The native assembler already has the
+   necessary support.  */
+
+#ifdef MIPS_DEBUGGING_INFO
+
+#ifndef PUT_SDB_SRC_FILE
+#define PUT_SDB_SRC_FILE(FILENAME) \
+output_file_directive (asm_out_file, (FILENAME))
+#endif
+
+/* ECOFF linkers have an optimization that does the same kind of thing as
+   N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the
+   executable.  To achieve this, GCC must output a .file for each file
+   name change.  */
+
+/* This is a stack of input files.  */
+
+struct sdb_file
+{
+  struct sdb_file *next;
+  char *name;
+};
+
+/* This is the top of the stack.  */
+
+static struct sdb_file *current_file;
+
+#endif /* MIPS_DEBUGGING_INFO */
 \f
 /* Set up for SDB output at the start of compilation.  */
 
@@ -285,6 +329,12 @@ sdbout_init (asm_file, input_file_name, syms)
      char *input_file_name;
      tree syms;
 {
+#ifdef MIPS_DEBUGGING_INFO
+  current_file = (struct sdb_file *) xmalloc (sizeof *current_file);
+  current_file->next = NULL;
+  current_file->name = input_file_name;
+#endif
+
 #ifdef RMS_QUICK_HACK_1
   tree t;
   for (t = syms; t; t = TREE_CHAIN (t))
@@ -292,13 +342,6 @@ sdbout_init (asm_file, input_file_name, syms)
        && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
       sdbout_symbol (t, 0);
 #endif  
-
-#if 0 /* Nothing need be output for the predefined types.  */
-  /* Get all permanent types that have typedef names,
-     and output them all, except for those already output.  */
-
-  sdbout_typedefs (syms);
-#endif
 }
 
 #if 0
@@ -369,7 +412,7 @@ static int
 plain_type (type)
      tree type;
 {
-  int val = plain_type_1 (type);
+  int val = plain_type_1 (type, 0);
 
   /* If we have already saved up some array dimensions, print them now.  */
   if (sdb_n_dims > 0)
@@ -422,12 +465,8 @@ sdbout_record_type_name (type)
       tree t = 0;
       /* Find the IDENTIFIER_NODE for the type name.  */
       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
-       {
-         t = TYPE_NAME (type);
-       }
-#if 1  /* As a temporary hack, use typedef names for C++ only.  */
-      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
-              && TYPE_LANG_SPECIFIC (type))
+       t = TYPE_NAME (type);
+      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
        {
          t = DECL_NAME (TYPE_NAME (type));
          /* The DECL_NAME for templates includes "<>", which breaks
@@ -436,7 +475,6 @@ sdbout_record_type_name (type)
          if (t && template_name_p (t))
            t = DECL_ASSEMBLER_NAME (TYPE_NAME (type));
        }
-#endif
 
       /* Now get the name as a string, or invent one.  */
       if (t != NULL_TREE)
@@ -454,15 +492,25 @@ sdbout_record_type_name (type)
 #endif
 }
 
+/* Return the .type value for type TYPE.
+
+   LEVEL indicates how many levels deep we have recursed into the type.
+   The SDB debug format can only represent 6 derived levels of types.
+   After that, we must output inaccurate debug info.  We deliberately
+   stop before the 7th level, so that ADA recursive types will not give an
+   infinite loop.  */
+
 static int
-plain_type_1 (type)
+plain_type_1 (type, level)
      tree type;
+     int level;
 {
   if (type == 0)
     type = void_type_node;
-  if (type == error_mark_node)
+  else if (type == error_mark_node)
     type = integer_type_node;
-  type = TYPE_MAIN_VARIANT (type);
+  else
+    type = TYPE_MAIN_VARIANT (type);
 
   switch (TREE_CODE (type))
     {
@@ -507,27 +555,37 @@ plain_type_1 (type)
          return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
        if (size == LONG_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+       if (size == LONG_LONG_TYPE_SIZE)        /* better than nothing */
+         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
        return 0;
       }
 
     case REAL_TYPE:
       {
-       int size = int_size_in_bytes (type) * BITS_PER_UNIT;
-       if (size == FLOAT_TYPE_SIZE)
+       int precision = TYPE_PRECISION (type);
+       if (precision == FLOAT_TYPE_SIZE)
          return T_FLOAT;
-       if (size == DOUBLE_TYPE_SIZE)
+       if (precision == DOUBLE_TYPE_SIZE)
          return T_DOUBLE;
+#ifdef EXTENDED_SDB_BASIC_TYPES
+       if (precision == LONG_DOUBLE_TYPE_SIZE)
+         return T_LNGDBL;
+#endif
        return 0;
       }
 
     case ARRAY_TYPE:
       {
        int m;
-       m = plain_type_1 (TREE_TYPE (type));
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        if (sdb_n_dims < SDB_MAX_DIM)
          sdb_dims[sdb_n_dims++]
            = (TYPE_DOMAIN (type)
-              ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1
+              ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
+                 - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1)
               : 0);
        return PUSH_DERIVED_LEVEL (DT_ARY, m);
       }
@@ -553,8 +611,8 @@ plain_type_1 (type)
               only if the .def has already been finished.
               At least on 386, the Unix assembler
               cannot handle forward references to tags.  */
-           /* But the 88100, it requires them, sigh... */
-           /* And the MIPS requires unknown refs as well... */
+           /* But the 88100, it requires them, sigh...  */
+           /* And the MIPS requires unknown refs as well...  */
            tag = KNOWN_TYPE_TAG (type);
            PUT_SDB_TAG (tag);
            /* These 3 lines used to follow the close brace.
@@ -572,13 +630,21 @@ plain_type_1 (type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       int m = plain_type_1 (TREE_TYPE (type));
+       int m;
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        return PUSH_DERIVED_LEVEL (DT_PTR, m);
       }
     case FUNCTION_TYPE:
     case METHOD_TYPE:
       {
-       int m = plain_type_1 (TREE_TYPE (type));
+       int m;
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        return PUSH_DERIVED_LEVEL (DT_FCN, m);
       }
     default:
@@ -672,7 +738,10 @@ sdbout_symbol (decl, local)
       context = decl_function_context (decl);
       if (context == current_function_decl)
        return;
-      if (DECL_EXTERNAL (decl))
+      /* Check DECL_INITIAL to distinguish declarations from definitions.
+        Don't output debug info here for declarations; they will have
+        a DECL_INITIAL value of 0.  */
+      if (! DECL_INITIAL (decl))
        return;
       if (GET_CODE (DECL_RTL (decl)) != MEM
          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
@@ -718,7 +787,7 @@ sdbout_symbol (decl, local)
       if (DECL_RTL (decl) == 0)
        return;
 
-      DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
+      DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX, 0);
 #ifdef LEAF_REG_REMAP
       if (leaf_function)
        leaf_renumber_regs_insn (DECL_RTL (decl));
@@ -787,7 +856,7 @@ sdbout_symbol (decl, local)
        return;
 
       /* Record the name for, starting a symtab entry.  */
-      name = IDENTIFIER_POINTER (DECL_NAME (decl));
+      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
       if (GET_CODE (value) == MEM
          && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
@@ -917,7 +986,7 @@ sdbout_toplevel_data (decl)
 \f
 #ifdef SDB_ALLOW_FORWARD_REFERENCES
 
-/* Machinery to record and output anonymous types. */
+/* Machinery to record and output anonymous types.  */
 
 static tree anonymous_types;
 
@@ -1005,7 +1074,11 @@ static void
 sdbout_one_type (type)
      tree type;
 {
-  text_section ();
+  if (current_function_decl != NULL_TREE
+      && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
+    ; /* Don't change section amid function.  */
+  else
+    text_section ();
 
   switch (TREE_CODE (type))
     {
@@ -1155,10 +1228,7 @@ sdbout_one_type (type)
                char *name;
 
                CONTIN;
-               if (DECL_LANG_SPECIFIC (tem))
-                 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));
-               else
-                 name = IDENTIFIER_POINTER (DECL_NAME (tem));
+               name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));
                PUT_SDB_DEF (name);
                if (DECL_BIT_FIELD_TYPE (tem))
                  {
@@ -1216,9 +1286,9 @@ sdbout_parms (parms)
 
        /* Perform any necessary register eliminations on the parameter's rtl,
           so that the debugging output will be accurate.  */
-       DECL_INCOMING_RTL (parms) =
-         eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
-       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
+       DECL_INCOMING_RTL (parms)
+         = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX, 0);
+       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX, 0);
 
        if (PARM_PASSED_IN_MEMORY (parms))
          {
@@ -1249,12 +1319,12 @@ sdbout_parms (parms)
                   the parm with the variable's declared type, and adjust
                   the address if the least significant bytes (which we are
                   using) are not the first ones.  */
-#if BYTES_BIG_ENDIAN
-               if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
+               if (BYTES_BIG_ENDIAN
+                   && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
                  current_sym_value +=
                    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
-#endif
+
                if (GET_CODE (DECL_RTL (parms)) == MEM
                    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
@@ -1295,7 +1365,7 @@ sdbout_parms (parms)
            PUT_SDB_DEF (name);
            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl)));
            PUT_SDB_SCL (C_REGPARM);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
        else if (GET_CODE (DECL_RTL (parms)) == MEM
@@ -1318,7 +1388,7 @@ sdbout_parms (parms)
            PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value,
                                                  XEXP (DECL_RTL (parms), 0)));
            PUT_SDB_SCL (C_ARG);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
       }
@@ -1356,7 +1426,7 @@ sdbout_reg_parms (parms)
            PUT_SDB_DEF (name);
            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
            PUT_SDB_SCL (C_REG);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
        /* Report parms that live in memory but not where they were passed.  */
@@ -1371,11 +1441,11 @@ sdbout_reg_parms (parms)
            /* A parm declared char is really passed as an int,
               so it occupies the least significant bytes.
               On a big-endian machine those are not the low-numbered ones.  */
-#if BYTES_BIG_ENDIAN
-           if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
+           if (BYTES_BIG_ENDIAN
+               && offset != -1
+               && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
              offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
-#endif
            if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
 #endif
              {
@@ -1524,4 +1594,35 @@ sdbout_label (insn)
   PUT_SDB_ENDEF;
 }
 
+/* Change to reading from a new source file.  */
+
+void
+sdbout_start_new_source_file (filename)
+     char *filename;
+{
+#ifdef MIPS_DEBUGGING_INFO
+  struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n);
+
+  n->next = current_file;
+  n->name = filename;
+  current_file = n;
+  PUT_SDB_SRC_FILE (filename);
+#endif
+}
+
+/* Revert to reading a previous source file.  */
+
+void
+sdbout_resume_previous_source_file ()
+{
+#ifdef MIPS_DEBUGGING_INFO
+  struct sdb_file *next;
+
+  next = current_file->next;
+  free (current_file);
+  current_file = next;
+  PUT_SDB_SRC_FILE (current_file->name);
+#endif
+}
+
 #endif /* SDB_DEBUGGING_INFO */