]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/dbxout.c
*** empty log message ***
[gcc.git] / gcc / dbxout.c
index 4d0276a1d11f761d1c5ccdd991a977c228958965..f680465404be220eab170fbaa5f08334345bb87c 100644 (file)
@@ -94,8 +94,8 @@ extern int errno;
 #define ASM_STABN_OP ".stabn"
 #endif
 
-#ifndef DBX_DECL_STABS_CODE
-#define DBX_DECL_STABS_CODE N_LSYM
+#ifndef DBX_TYPE_DECL_STABS_CODE
+#define DBX_TYPE_DECL_STABS_CODE N_LSYM
 #endif
 
 #ifndef DBX_STATIC_CONST_VAR_CODE
@@ -110,6 +110,10 @@ extern int errno;
 #define DBX_REGPARM_STABS_LETTER 'P'
 #endif
 
+#ifndef DBX_MEMPARM_STABS_LETTER
+#define DBX_MEMPARM_STABS_LETTER 'p'
+#endif
+
 /* Nonzero means if the type has methods, only output debugging
    information if methods are actually written to the asm file.  */
 
@@ -521,7 +525,7 @@ dbxout_continue ()
   current_sym_nchars = 0;
 }
 \f
-/* Subtroutine of `dbxout_type'.  Output the type fields of TYPE.
+/* Subroutine of `dbxout_type'.  Output the type fields of TYPE.
    This must be a separate function because anonymous unions require
    recursive calls.  */
 
@@ -614,7 +618,7 @@ dbxout_type_fields (type)
     }
 }
 \f
-/* Subtroutine of `dbxout_type_methods'.  Output debug info about the
+/* Subroutine of `dbxout_type_methods'.  Output debug info about the
    method described DECL.  DEBUG_NAME is an encoding of the method's
    type signature.  ??? We may be able to do without DEBUG_NAME altogether
    now.  */
@@ -781,8 +785,11 @@ dbxout_type_methods (type)
 
          dbxout_type_method_1 (fndecl, debug_name);
        }
-      putc (';', asmfile);
-      CHARS (1);
+      if (!need_prefix)
+       {
+          putc (';', asmfile);
+         CHARS (1);
+       }
     }
 }
 \f
@@ -853,7 +860,13 @@ dbxout_type (type, full, show_arg_types)
     case TYPE_UNSEEN:
       break;
     case TYPE_XREF:
-      if (! full)
+      /* If we have already had a cross reference,
+        and either that's all we want or that's the best we could do,
+        don't repeat the cross reference.
+        Sun dbx crashes if we do.  */
+      if (! full || TYPE_SIZE (type) == 0
+         /* No way in DBX fmt to describe a variable size.  */
+         || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
        return;
       break;
     case TYPE_DEFINED:
@@ -1089,6 +1102,9 @@ dbxout_type (type, full, show_arg_types)
          fprintf (asmfile, ":");
          return;
        }
+#ifdef DBX_OUTPUT_ENUM
+      DBX_OUTPUT_ENUM (asmfile, type);
+#else
       putc ('e', asmfile);
       CHARS (1);
       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
@@ -1101,6 +1117,7 @@ dbxout_type (type, full, show_arg_types)
        }
       putc (';', asmfile);
       CHARS (1);
+#endif
       break;
 
     case POINTER_TYPE:
@@ -1346,52 +1363,77 @@ dbxout_symbol (decl, local)
 
       FORCE_TEXT;
 
-      if (DECL_NAME (decl))
-       {
-         /* Output typedef name.  */
-         fprintf (asmfile, "%s \"%s:", ASM_STABS_OP,
-                  IDENTIFIER_POINTER (DECL_NAME (decl)));
-
-         /* If there is a typedecl for this type with the same name
-            as the tag, output an abbreviated form for that typedecl.  */
-         if (use_gdb_dbx_extensions && have_used_extensions
-             && (TREE_CODE (type) == RECORD_TYPE
-                 || TREE_CODE (type) == UNION_TYPE)
-             && (TYPE_NAME (type) == decl))
-           {
-             putc ('T', asmfile);
-             TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
-           }
-         putc ('t', asmfile);
-         current_sym_code = DBX_DECL_STABS_CODE;
+      {
+       int tag_needed = 1;
 
-         dbxout_type (type, 1, 0);
-         dbxout_finish_symbol (decl);
-       }
-      else if (TYPE_NAME (type) != 0 && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
-       {
-         /* Output a tag (a TYPE_DECL with no name, but the type has a name).
-            This is what represents `struct foo' with no typedef.  */
-         /* In C++, the name of a type is the corresponding typedef.
-            In C, it is an IDENTIFIER_NODE.  */
-         tree name = TYPE_NAME (type);
-         if (TREE_CODE (name) == TYPE_DECL)
-           name = DECL_NAME (name);
-
-         current_sym_code = DBX_DECL_STABS_CODE;
-         current_sym_value = 0;
-         current_sym_addr = 0;
-         current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
-
-         fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
-                  IDENTIFIER_POINTER (name));
-         dbxout_type (type, 1, 0);
-         dbxout_finish_symbol (0);
-       }
+       if (DECL_NAME (decl))
+         {
+           /* Nonzero means we must output a tag as well as a typedef.  */
+           tag_needed = 0;
+
+           /* Output typedef name.  */
+           fprintf (asmfile, "%s \"%s:", ASM_STABS_OP,
+                    IDENTIFIER_POINTER (DECL_NAME (decl)));
+
+/* #ifndef DBX_NO_EXTRA_TAGS   rms: I think this is no longer needed.  */
+           /* This section makes absolutely no sense to me. Why would a tag
+              ever be needed at this point? The result of this is that any
+              structure typedef with the tag omitted is treated as if the
+              tag was given to be the same as the typedef name. Probably
+              no harm in it, unless the programmer used the same name for
+              the tag of a *different* structure. At any rate, Alliant's
+              debugger would want the tag output before the typedef, so
+              this code still loses.  -- hyc */
+
+           /* Short cut way to output a tag also.  */
+           if ((TREE_CODE (type) == RECORD_TYPE
+                || TREE_CODE (type) == UNION_TYPE)
+               && TYPE_NAME (type) == decl)
+             {
+               if (use_gdb_dbx_extensions && have_used_extensions)
+                 {
+                   putc ('T', asmfile);
+                   TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
+                 }
+               else
+                 tag_needed = 1;
+             }
+/* #endif */
 
-      /* Prevent duplicate output of a typedef.  */
-      TREE_ASM_WRITTEN (decl) = 1;
-      break;
+           putc ('t', asmfile);
+           current_sym_code = DBX_TYPE_DECL_STABS_CODE;
+
+           dbxout_type (type, 1, 0);
+           dbxout_finish_symbol (decl);
+         }
+
+       if (tag_needed && TYPE_NAME (type) != 0
+           && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
+         {
+           /* For a TYPE_DECL with no name, but the type has a name,
+              output a tag.
+              This is what represents `struct foo' with no typedef.  */
+           /* In C++, the name of a type is the corresponding typedef.
+              In C, it is an IDENTIFIER_NODE.  */
+           tree name = TYPE_NAME (type);
+           if (TREE_CODE (name) == TYPE_DECL)
+             name = DECL_NAME (name);
+
+           current_sym_code = DBX_TYPE_DECL_STABS_CODE;
+           current_sym_value = 0;
+           current_sym_addr = 0;
+           current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
+
+           fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
+                    IDENTIFIER_POINTER (name));
+           dbxout_type (type, 1, 0);
+           dbxout_finish_symbol (0);
+         }
+
+       /* Prevent duplicate output of a typedef.  */
+       TREE_ASM_WRITTEN (decl) = 1;
+       break;
+      }
 
     case PARM_DECL:
       /* Parm decls go in their own separate chains
@@ -1505,7 +1547,7 @@ dbxout_symbol (decl, local)
            {
              current_sym_addr = XEXP (DECL_RTL (decl), 0);
 
-             letter = TREE_PERMANENT (decl) ? 'S' : 'V';
+             letter = decl_function_context (decl) ? 'V' : 'S';
 
              if (!DECL_INITIAL (decl))
                current_sym_code = N_LCSYM;
@@ -1572,7 +1614,8 @@ dbxout_symbol (decl, local)
          /* Effectively do build_pointer_type, but don't cache this type,
             since it might be temporary whereas the type it points to
             might have been saved for inlining.  */
-         type = make_node (REFERENCE_TYPE);
+         /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
+         type = make_node (POINTER_TYPE);
          TREE_TYPE (type) = TREE_TYPE (decl);
        }
       else if (GET_CODE (DECL_RTL (decl)) == MEM
@@ -1747,13 +1790,15 @@ dbxout_parms (parms)
              {
                current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
 
-               fprintf (asmfile, "%s \"%s:p", ASM_STABS_OP,
-                        IDENTIFIER_POINTER (DECL_NAME (parms)));
+               fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
+                        IDENTIFIER_POINTER (DECL_NAME (parms)),
+                        DBX_MEMPARM_STABS_LETTER);
              }
            else
              {
                current_sym_nchars = 8;
-               fprintf (asmfile, "%s \"(anon):p", ASM_STABS_OP);
+               fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
+                        DBX_MEMPARM_STABS_LETTER);
              }
 
            if (GET_CODE (DECL_RTL (parms)) == REG
@@ -1831,6 +1876,46 @@ dbxout_parms (parms)
            dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
            dbxout_finish_symbol (parms);
          }
+       else if (GET_CODE (DECL_RTL (parms)) == MEM
+                && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
+                && rtx_equal_p (XEXP (DECL_RTL (parms), 0),
+                                DECL_INCOMING_RTL (parms)))
+         {
+           /* Parm was passed via invisible reference.
+              That is, its address was passed in a register.
+              Output it as if it lived in that register.
+              The debugger will know from the type
+              that it was actually passed by invisible reference.  */
+
+           char regparm_letter;
+           /* Parm passed in registers and lives in registers or nowhere.  */
+
+           current_sym_code = DBX_REGPARM_STABS_CODE;
+           regparm_letter = DBX_REGPARM_STABS_LETTER;
+
+           /* DECL_RTL looks like (MEM (REG...).  Get the register number.  */
+           current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
+           current_sym_addr = 0;
+
+           FORCE_TEXT;
+           if (DECL_NAME (parms))
+             {
+               current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
+
+               fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
+                        IDENTIFIER_POINTER (DECL_NAME (parms)),
+                        DBX_REGPARM_STABS_LETTER);
+             }
+           else
+             {
+               current_sym_nchars = 8;
+               fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
+                        DBX_REGPARM_STABS_LETTER);
+             }
+
+           dbxout_type (TREE_TYPE (parms), 0, 0);
+           dbxout_finish_symbol (parms);
+         }
        else if (GET_CODE (DECL_RTL (parms)) == MEM
                 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
          {
@@ -1853,13 +1938,15 @@ dbxout_parms (parms)
              {
                current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
 
-               fprintf (asmfile, "%s \"%s:p", ASM_STABS_OP,
-                        IDENTIFIER_POINTER (DECL_NAME (parms)));
+               fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
+                        IDENTIFIER_POINTER (DECL_NAME (parms)),
+                        DBX_MEMPARM_STABS_LETTER);
              }
            else
              {
                current_sym_nchars = 8;
-               fprintf (asmfile, "%s \"(anon):p", ASM_STABS_OP);
+               fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
+               DBX_MEMPARM_STABS_LETTER);
              }
 
            current_sym_value
@@ -2057,9 +2144,13 @@ dbxout_block (block, depth, args)
                    }
                }
 
+#ifdef DBX_OUTPUT_LBRAC
+             DBX_OUTPUT_LBRAC (asmfile, buf);
+#else
              fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);
              assemble_name (asmfile, buf);
              fprintf (asmfile, "\n");
+#endif
            }
          else if (depth > 0)
            /* Count blocks the same way regardless of debug_info_level.  */
@@ -2082,9 +2173,13 @@ dbxout_block (block, depth, args)
            {
              char buf[20];
              ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum);
+#ifdef DBX_OUTPUT_RBRAC
+             DBX_OUTPUT_RBRAC (asmfile, buf);
+#else
              fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);
              assemble_name (asmfile, buf);
              fprintf (asmfile, "\n");
+#endif
            }
        }
       block = BLOCK_CHAIN (block);
This page took 0.038097 seconds and 5 git commands to generate.