X-Git-Url: https://gcc.gnu.org/git/?a=blobdiff_plain;f=gcc%2Fdbxout.c;h=f680465404be220eab170fbaa5f08334345bb87c;hb=3c0e8d08d4d0b9d8aaad90eb1df86b454d29b9d1;hp=4d0276a1d11f761d1c5ccdd991a977c228958965;hpb=3a7587e44e18f503e4781a813ac1ab16d5fd0fa3;p=gcc.git diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 4d0276a1d11f..f680465404be 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -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; } -/* 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) } } -/* 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); + } } } @@ -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);