OSDN Git Service

* pa.md (dbra pattern): Use output_dbra.
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 77bb95f..a08230d 100644 (file)
@@ -1,5 +1,5 @@
 /* Output sdb-format symbol table information from GNU compiler.
-   Copyright (C) 1988-1990 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -34,7 +34,7 @@ AT&T C compiler.  From the example below I would conclude the following:
 4. All structure .defs are emitted before the typedefs that refer to them.
 
 5. All top level static and external variable definitions are moved to the
-   end of file with all top level statics occuring first before externs.
+   end of file with all top level statics occurring first before externs.
 
 6. All undefined references are at the end of the file.
 */
@@ -51,9 +51,9 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "insn-config.h"
 #include "reload.h"
 
-/* Mips systems use the SDB functions to dump out it's symbols, but
+/* Mips systems use the SDB functions to dump out symbols, but
    do not supply usable syms.h include files.  */
-#if defined(USG) && !defined(MIPS)
+#if defined(USG) && !defined(MIPS) && !defined (hpux)
 #include <syms.h>
 /* Use T_INT if we don't have T_VOID.  */
 #ifndef T_VOID
@@ -104,7 +104,7 @@ static void sdbout_typedefs ();
 static void sdbout_syms ();
 static void sdbout_one_type ();
 static void sdbout_queue_anonymous_type ();
-static void sdbout_dequeue_anonymous_type ();
+static void sdbout_dequeue_anonymous_types ();
 static int plain_type_1 ();
 \f
 /* Define the default sizes for various types.  */
@@ -344,8 +344,10 @@ gen_fake_label ()
 /* Produce the number that describes a pointer, function or array type.
    PREV is the number describing the target, value or element type.
    DT_type describes how to transform that type.  */
-#define PUSH_DERIVED_LEVEL(DT_type,PREV) \
-  ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))
+#define PUSH_DERIVED_LEVEL(DT_type,PREV)               \
+  ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT)                \
+   | ((int)DT_type << (int)N_BTSHFT)                   \
+   | ((PREV) & (int)N_BTMASK))
 
 /* Number of elements used in sdb_dims.  */
 static int sdb_n_dims = 0;
@@ -387,6 +389,17 @@ plain_type (type)
   return val;
 }
 
+static int
+template_name_p (name)
+     tree name;
+{
+  register char *ptr = IDENTIFIER_POINTER (name);
+  while (*ptr && *ptr != '<')
+    ptr++;
+
+  return *ptr != '\0';
+}
+
 static void
 sdbout_record_type_name (type)
      tree type;
@@ -405,15 +418,21 @@ sdbout_record_type_name (type)
        {
          t = TYPE_NAME (type);
        }
-#if 0  /* Don't use typedef names.  */
-      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+#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 = DECL_NAME (TYPE_NAME (type));
+         /* The DECL_NAME for templates includes "<>", which breaks
+            most assemblers.  Use its assembler name instead, which
+            has been mangled into being safe.  */
+         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 != 0)
+      if (t != NULL_TREE)
        name = IDENTIFIER_POINTER (t);
     }
 
@@ -445,12 +464,42 @@ plain_type_1 (type)
     case INTEGER_TYPE:
       {
        int size = int_size_in_bytes (type) * BITS_PER_UNIT;
+
+       /* Carefully distinguish all the standard types of C,
+          without messing up if the language is not C.
+          Note that we check only for the names that contain spaces;
+          other names might occur by coincidence in other languages.  */
+       if (TYPE_NAME (type) != 0
+           && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+           && DECL_NAME (TYPE_NAME (type)) != 0
+           && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
+         {
+           char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+           if (!strcmp (name, "unsigned char"))
+             return T_UCHAR;
+           if (!strcmp (name, "signed char"))
+             return T_CHAR;
+           if (!strcmp (name, "unsigned int"))
+             return T_UINT;
+           if (!strcmp (name, "short int"))
+             return T_SHORT;
+           if (!strcmp (name, "short unsigned int"))
+             return T_USHORT;
+           if (!strcmp (name, "long int"))
+             return T_LONG;
+           if (!strcmp (name, "long unsigned int"))
+             return T_ULONG;
+         }
+
        if (size == CHAR_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
        if (size == SHORT_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
        if (size == INT_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
+       if (size == LONG_TYPE_SIZE)
+         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
        return 0;
       }
 
@@ -478,6 +527,7 @@ plain_type_1 (type)
 
     case RECORD_TYPE:
     case UNION_TYPE:
+    case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       {
        char *tag;
@@ -509,6 +559,7 @@ plain_type_1 (type)
          }
        return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
                : (TREE_CODE (type) == UNION_TYPE) ? T_UNION
+               : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION
                : T_ENUM);
       }
     case POINTER_TYPE:
@@ -575,7 +626,8 @@ sdbout_syms (syms)
 {
   while (syms)
     {
-      sdbout_symbol (syms, 1);
+      if (TREE_CODE (syms) != LABEL_DECL)
+       sdbout_symbol (syms, 1);
       syms = TREE_CHAIN (syms);
     }
 }
@@ -597,6 +649,12 @@ sdbout_symbol (decl, local)
 
   sdbout_one_type (type);
 
+#if 0 /* This loses when functions are marked to be ignored,
+        which happens in the C++ front end.  */
+  if (DECL_IGNORED_P (decl))
+    return;
+#endif
+
   switch (TREE_CODE (decl))
     {
     case CONST_DECL:
@@ -608,7 +666,7 @@ sdbout_symbol (decl, local)
       context = decl_function_context (decl);
       if (context == current_function_decl)
        return;
-      if (TREE_EXTERNAL (decl))
+      if (DECL_EXTERNAL (decl))
        return;
       if (GET_CODE (DECL_RTL (decl)) != MEM
          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
@@ -622,9 +680,14 @@ sdbout_symbol (decl, local)
       /* Done with tagged types.  */
       if (DECL_NAME (decl) == 0)
        return;
+      if (DECL_IGNORED_P (decl))
+       return;
 
       /* Output typedef name.  */
-      PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
+      if (template_name_p (DECL_NAME (decl)))
+       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+      else
+       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
       PUT_SDB_SCL (C_TPDEF);
       break;
 
@@ -636,7 +699,11 @@ sdbout_symbol (decl, local)
     case VAR_DECL:
       /* Don't mention a variable that is external.
         Let the file that defines it describe it.  */
-      if (TREE_EXTERNAL (decl))
+      if (DECL_EXTERNAL (decl))
+       return;
+
+      /* Ignore __FUNCTION__, etc.  */
+      if (DECL_IGNORED_P (decl))
        return;
 
       /* If there was an error in the declaration, don't dump core
@@ -645,7 +712,12 @@ sdbout_symbol (decl, local)
       if (DECL_RTL (decl) == 0)
        return;
 
-      value = eliminate_regs (DECL_RTL (decl), 0, 0);
+      DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
+#ifdef LEAF_REG_REMAP
+      if (leaf_function)
+       leaf_renumber_regs_insn (DECL_RTL (decl));
+#endif
+      value = DECL_RTL (decl);
 
       /* Don't mention a variable at all
         if it was completely optimized into nothingness.
@@ -657,11 +729,9 @@ sdbout_symbol (decl, local)
        {
          regno = REGNO (DECL_RTL (decl));
          if (regno >= FIRST_PSEUDO_REGISTER)
-           regno = reg_renumber[REGNO (DECL_RTL (decl))];
-         if (regno < 0)
            return;
        }
-      else if (GET_CODE (DECL_RTL (decl)) == SUBREG)
+      else if (GET_CODE (value) == SUBREG)
        {
          int offset = 0;
          while (GET_CODE (value) == SUBREG)
@@ -673,10 +743,11 @@ sdbout_symbol (decl, local)
            {
              regno = REGNO (value);
              if (regno >= FIRST_PSEUDO_REGISTER)
-               regno = reg_renumber[REGNO (value)];
-             if (regno >= 0)
-               regno += offset;
+               return;
+             regno += offset;
            }
+         alter_subreg (DECL_RTL (decl));
+         value = DECL_RTL (decl);
        }
 
       /* Emit any structure, union, or enum type that has not been output.
@@ -684,7 +755,8 @@ sdbout_symbol (decl, local)
         within functions.  */
       if (TREE_CODE (type) == ENUMERAL_TYPE
          || TREE_CODE (type) == RECORD_TYPE
-         || TREE_CODE (type) == UNION_TYPE)
+         || TREE_CODE (type) == UNION_TYPE
+         || TREE_CODE (type) == QUAL_UNION_TYPE)
        {
          if (TYPE_SIZE (type) != 0             /* not a forward reference */
              && KNOWN_TYPE_TAG (type) == 0)    /* not yet declared */
@@ -697,6 +769,11 @@ sdbout_symbol (decl, local)
          && DECL_INITIAL (decl))
        return;
 
+      /* C++ in 2.3 makes nameless symbols.  That will be fixed later.
+        For now, avoid crashing.  */
+      if (DECL_NAME (decl) == NULL_TREE)
+       return;
+
       /* Record the name for, starting a symtab entry.  */
       name = IDENTIFIER_POINTER (DECL_NAME (decl));
 
@@ -724,7 +801,8 @@ sdbout_symbol (decl, local)
       else if (GET_CODE (value) == MEM
               && (GET_CODE (XEXP (value, 0)) == MEM
                   || (GET_CODE (XEXP (value, 0)) == REG
-                      && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM)))
+                      && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM
+                      && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
        /* If the value is indirect by memory or by a register
           that isn't the frame pointer
           then it means the object is variable-sized and address through
@@ -761,6 +839,23 @@ sdbout_symbol (decl, local)
          PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
          PUT_SDB_SCL (C_AUTO);
        }
+      else if (GET_CODE (value) == MEM && GET_CODE (XEXP (value, 0)) == CONST)
+       {
+         /* Handle an obscure case which can arise when optimizing and
+            when there are few available registers.  (This is *always*
+            the case for i386/i486 targets).  The DECL_RTL looks like
+            (MEM (CONST ...)) even though this variable is a local `auto'
+            or a local `register' variable.  In effect, what has happened
+            is that the reload pass has seen that all assignments and
+            references for one such a local variable can be replaced by
+            equivalent assignments and references to some static storage
+            variable, thereby avoiding the need for a register.  In such
+            cases we're forced to lie to debuggers and tell them that
+            this variable was itself `static'.  */
+         PUT_SDB_DEF (name);
+         PUT_SDB_VAL (XEXP (XEXP (value, 0), 0));
+         PUT_SDB_SCL (C_STAT);
+       }
       else
        {
          /* It is something we don't know how to represent for SDB.  */
@@ -781,6 +876,9 @@ sdbout_toplevel_data (decl)
 {
   tree type = TREE_TYPE (decl);
 
+  if (DECL_IGNORED_P (decl))
+    return;
+
   if (! (TREE_CODE (decl) == VAR_DECL
         && GET_CODE (DECL_RTL (decl)) == MEM
         && DECL_INITIAL (decl)))
@@ -827,7 +925,7 @@ sdbout_dequeue_anonymous_types ()
        {
          register tree type = TREE_VALUE (link);
 
-         if (! TREE_ASM_WRITTEN (type))
+         if (type && ! TREE_ASM_WRITTEN (type))
            sdbout_one_type (type);
        }
     }
@@ -897,6 +995,7 @@ sdbout_one_type (type)
     {
     case RECORD_TYPE:
     case UNION_TYPE:
+    case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       type = TYPE_MAIN_VARIANT (type);
       /* Don't output a type twice.  */
@@ -911,7 +1010,7 @@ sdbout_one_type (type)
       TREE_ASM_WRITTEN (type) = 1;
 #if 1
       /* This is reputed to cause trouble with the following case,
-        but perhaps checking TYPE_SIZE above will fix it.
+        but perhaps checking TYPE_SIZE above will fix it.  */
 
       /* Here is a test case:
 
@@ -948,6 +1047,7 @@ sdbout_one_type (type)
        int size = int_size_in_bytes (type);
        int member_scl;
        tree tem;
+       int i, n_baseclasses = 0;
 
        /* Record the type tag, but not in its permanent place just yet.  */
        sdbout_record_type_name (type);
@@ -957,6 +1057,7 @@ sdbout_one_type (type)
        switch (TREE_CODE (type))
          {
          case UNION_TYPE:
+         case QUAL_UNION_TYPE:
            PUT_SDB_SCL (C_UNTAG);
            PUT_SDB_TYPE (T_UNION);
            member_scl = C_MOU;
@@ -978,6 +1079,33 @@ sdbout_one_type (type)
        PUT_SDB_SIZE (size);
        PUT_SDB_ENDEF;
 
+       /* Print out the base class information with fields
+          named after the types they hold.  */
+       if (TYPE_BINFO (type)
+           && TYPE_BINFO_BASETYPES (type))
+         n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
+       for (i = 0; i < n_baseclasses; i++)
+         {
+           tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
+           tree child_type = BINFO_TYPE (child);
+           tree child_type_name;
+           if (TYPE_NAME (child_type) == 0)
+             continue;
+           if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
+             child_type_name = TYPE_NAME (child_type);
+           else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
+             child_type_name = DECL_NAME (TYPE_NAME (child_type));
+           else
+             continue;
+
+           CONTIN;
+           PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
+           PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child)));
+           PUT_SDB_SCL (member_scl);
+           sdbout_type (BINFO_TYPE (child));
+           PUT_SDB_ENDEF;
+         }
+
        /* output the individual fields */
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
@@ -1062,8 +1190,8 @@ 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, 0);
-       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, 0);
+         eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
+       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
 
        if (PARM_PASSED_IN_MEMORY (parms))
          {