X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdbxout.c;h=468ee0969d386c01aacab024776c1be26e75c823;hb=38ac91bf63ac10b9412e9d352cdf5b68e346a318;hp=c3838dfe9566855fdec954b6a234d6d3c3e47a9b;hpb=a1d829f8614a65a4e6e810d7266a11393fa7a14f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dbxout.c b/gcc/dbxout.c index c3838dfe956..468ee0969d3 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1,23 +1,23 @@ /* Output dbx-format symbol table information from GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the 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, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ /* Output dbx-format symbol table data. @@ -70,6 +70,8 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "tree.h" #include "rtl.h" @@ -77,12 +79,15 @@ Boston, MA 02111-1307, USA. */ #include "regs.h" #include "insn-config.h" #include "reload.h" -#include "defaults.h" #include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions. */ #include "dbxout.h" #include "toplev.h" #include "tm_p.h" #include "ggc.h" +#include "debug.h" +#include "function.h" +#include "target.h" +#include "langhooks.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" @@ -125,26 +130,77 @@ Boston, MA 02111-1307, USA. */ #define FILE_NAME_JOINER "/" #endif -/* Nonzero means if the type has methods, only output debugging - information if methods are actually written to the asm file. This - optimization only works if the debugger can detect the special C++ - marker. */ +/* GDB needs to know that the stabs were generated by GCC. We emit an + N_OPT stab at the beginning of the source file to indicate this. + The string is historical, and different on a very few targets. */ +#ifndef STABS_GCC_MARKER +#define STABS_GCC_MARKER "gcc2_compiled." +#endif -#define MINIMAL_DEBUG 1 +enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED}; -#ifdef NO_DOLLAR_IN_LABEL -#ifdef NO_DOT_IN_LABEL -#undef MINIMAL_DEBUG -#define MINIMAL_DEBUG 0 -#endif -#endif +/* Structure recording information about a C data type. + The status element says whether we have yet output + the definition of the type. TYPE_XREF says we have + output it as a cross-reference only. + The file_number and type_number elements are used if DBX_USE_BINCL + is defined. */ + +struct typeinfo GTY(()) +{ + enum typestatus status; + int file_number; + int type_number; +}; + +/* Vector recording information about C data types. + When we first notice a data type (a tree node), + we assign it a number using next_type_number. + That is its index in this vector. */ + +static GTY ((length ("typevec_len"))) struct typeinfo *typevec; + +/* Number of elements of space allocated in `typevec'. */ + +static GTY(()) int typevec_len; + +/* In dbx output, each type gets a unique number. + This is the number for the next type output. + The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */ + +static GTY(()) int next_type_number; + +/* When using N_BINCL in dbx output, each type number is actually a + pair of the file number and the type number within the file. + This is a stack of input files. */ + +struct dbx_file GTY(()) +{ + struct dbx_file *next; + int file_number; + int next_type_number; +}; + +/* This is the top of the stack. */ + +static GTY(()) struct dbx_file *current_file; + +/* This is the next file number to use. */ + +static GTY(()) int next_file_number; /* Typical USG systems don't have stab.h, and they also have no use for DBX-format debugging info. */ #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) -static int flag_minimal_debug = MINIMAL_DEBUG; +/* Last source file name mentioned in a NOTE insn. */ + +static const char *lastfile; + +/* Current working directory. */ + +static const char *cwd; /* Nonzero if we have actually used any of the GDB extensions to the debugging format. The idea is that we use them for the @@ -156,34 +212,19 @@ static int have_used_extensions = 0; /* Number for the next N_SOL filename stabs label. The number 0 is reserved for the N_SO filename stabs label. */ +#if defined (DBX_DEBUGGING_INFO) && !defined (DBX_OUTPUT_SOURCE_FILENAME) static int source_label_number = 1; +#endif #ifdef DEBUG_SYMS_TEXT -#define FORCE_TEXT text_section (); +#define FORCE_TEXT function_section (current_function_decl); #else #define FORCE_TEXT #endif -/* If there is a system stab.h, use it. Otherwise, use our own. */ -/* ??? This is supposed to describe the target's stab format, so using - the host HAVE_STAB_H appears to be wrong. For now, we use our own file - when cross compiling. */ -#if defined (USG) || !defined (HAVE_STAB_H) || defined (CROSS_COMPILE) -#include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ -#else -#include +#include "gstab.h" -/* This is a GNU extension we need to reference in this file. */ -#ifndef N_CATCH -#define N_CATCH 0x54 -#endif -#endif - -#ifdef __GNU_STAB__ #define STAB_CODE_TYPE enum __stab_debug_code -#else -#define STAB_CODE_TYPE int -#endif /* 1 if PARM is passed to this function in memory. */ @@ -207,72 +248,6 @@ static int source_label_number = 1; static FILE *asmfile; -/* Last source file name mentioned in a NOTE insn. */ - -static const char *lastfile; - -/* Current working directory. */ - -static const char *cwd; - -enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED}; - -/* Structure recording information about a C data type. - The status element says whether we have yet output - the definition of the type. TYPE_XREF says we have - output it as a cross-reference only. - The file_number and type_number elements are used if DBX_USE_BINCL - is defined. */ - -struct typeinfo -{ - enum typestatus status; -#ifdef DBX_USE_BINCL - int file_number; - int type_number; -#endif -}; - -/* Vector recording information about C data types. - When we first notice a data type (a tree node), - we assign it a number using next_type_number. - That is its index in this vector. */ - -struct typeinfo *typevec; - -/* Number of elements of space allocated in `typevec'. */ - -static int typevec_len; - -/* In dbx output, each type gets a unique number. - This is the number for the next type output. - The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */ - -static int next_type_number; - -#ifdef DBX_USE_BINCL - -/* When using N_BINCL in dbx output, each type number is actually a - pair of the file number and the type number within the file. - This is a stack of input files. */ - -struct dbx_file -{ - struct dbx_file *next; - int file_number; - int next_type_number; -}; - -/* This is the top of the stack. */ - -static struct dbx_file *current_file; - -/* This is the next file number to use. */ - -static int next_file_number; - -#endif /* DBX_USE_BINCL */ - /* These variables are for dbxout_symbol to communicate to dbxout_finish_symbol. current_sym_code is the symbol-type-code, a symbol N_... define in stab.h. @@ -310,30 +285,101 @@ static int current_sym_nchars; #define CONTIN do { } while (0) #endif -#if defined(ASM_OUTPUT_SECTION_NAME) -static void dbxout_function_end PARAMS ((void)); -#endif +static void dbxout_init PARAMS ((const char *)); +static void dbxout_finish PARAMS ((const char *)); +static void dbxout_start_source_file PARAMS ((unsigned, const char *)); +static void dbxout_end_source_file PARAMS ((unsigned)); static void dbxout_typedefs PARAMS ((tree)); +static void dbxout_fptype_value PARAMS ((tree)); static void dbxout_type_index PARAMS ((tree)); #if DBX_CONTIN_LENGTH > 0 static void dbxout_continue PARAMS ((void)); #endif +static void dbxout_args PARAMS ((tree)); static void dbxout_type_fields PARAMS ((tree)); static void dbxout_type_method_1 PARAMS ((tree, const char *)); static void dbxout_type_methods PARAMS ((tree)); static void dbxout_range_type PARAMS ((tree)); -static void dbxout_type PARAMS ((tree, int, int)); +static void dbxout_type PARAMS ((tree, int)); static void print_int_cst_octal PARAMS ((tree)); static void print_octal PARAMS ((unsigned HOST_WIDE_INT, int)); +static void print_wide_int PARAMS ((HOST_WIDE_INT)); static void dbxout_type_name PARAMS ((tree)); +static void dbxout_class_name_qualifiers PARAMS ((tree)); static int dbxout_symbol_location PARAMS ((tree, tree, const char *, rtx)); static void dbxout_symbol_name PARAMS ((tree, const char *, int)); static void dbxout_prepare_symbol PARAMS ((tree)); static void dbxout_finish_symbol PARAMS ((tree)); static void dbxout_block PARAMS ((tree, int, tree)); -static void dbxout_really_begin_function PARAMS ((tree)); +static void dbxout_global_decl PARAMS ((tree)); -#if defined(ASM_OUTPUT_SECTION_NAME) +/* The debug hooks structure. */ +#if defined (DBX_DEBUGGING_INFO) + +static void dbxout_source_line PARAMS ((unsigned int, const char *)); +static void dbxout_source_file PARAMS ((FILE *, const char *)); +static void dbxout_function_end PARAMS ((void)); +static void dbxout_begin_function PARAMS ((tree)); +static void dbxout_begin_block PARAMS ((unsigned, unsigned)); +static void dbxout_end_block PARAMS ((unsigned, unsigned)); +static void dbxout_function_decl PARAMS ((tree)); + +const struct gcc_debug_hooks dbx_debug_hooks = +{ + dbxout_init, + dbxout_finish, + debug_nothing_int_charstar, + debug_nothing_int_charstar, + dbxout_start_source_file, + dbxout_end_source_file, + dbxout_begin_block, + dbxout_end_block, + debug_true_tree, /* ignore_block */ + dbxout_source_line, /* source_line */ + dbxout_source_line, /* begin_prologue: just output line info */ + debug_nothing_int_charstar, /* end_prologue */ + debug_nothing_int_charstar, /* end_epilogue */ +#ifdef DBX_FUNCTION_FIRST + dbxout_begin_function, +#else + debug_nothing_tree, /* begin_function */ +#endif + debug_nothing_int, /* end_function */ + dbxout_function_decl, + dbxout_global_decl, /* global_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx /* label */ +}; +#endif /* DBX_DEBUGGING_INFO */ + +#if defined (XCOFF_DEBUGGING_INFO) +const struct gcc_debug_hooks xcoff_debug_hooks = +{ + dbxout_init, + dbxout_finish, + debug_nothing_int_charstar, + debug_nothing_int_charstar, + dbxout_start_source_file, + dbxout_end_source_file, + xcoffout_begin_block, + xcoffout_end_block, + debug_true_tree, /* ignore_block */ + xcoffout_source_line, + xcoffout_begin_prologue, /* begin_prologue */ + debug_nothing_int_charstar, /* end_prologue */ + xcoffout_end_epilogue, + debug_nothing_tree, /* begin_function */ + xcoffout_end_function, + debug_nothing_tree, /* function_decl */ + dbxout_global_decl, /* global_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx /* label */ +}; +#endif /* XCOFF_DEBUGGING_INFO */ + +#if defined (DBX_DEBUGGING_INFO) static void dbxout_function_end () { @@ -343,34 +389,37 @@ dbxout_function_end () the system doesn't insert underscores in front of user generated labels. */ ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno); - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno); + (*targetm.asm_out.internal_label) (asmfile, "Lscope", scope_labelno); scope_labelno++; /* By convention, GCC will mark the end of a function with an N_FUN symbol and an empty string. */ +#ifdef DBX_OUTPUT_NFUN + DBX_OUTPUT_NFUN (asmfile, lscope_label_name, current_function_decl); +#else fprintf (asmfile, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN); assemble_name (asmfile, lscope_label_name); - fputc ('-', asmfile); + putc ('-', asmfile); assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); fprintf (asmfile, "\n"); +#endif } -#endif /* ! NO_DBX_FUNCTION_END */ +#endif /* DBX_DEBUGGING_INFO */ /* At the beginning of compilation, start writing the symbol table. Initialize `typevec' and output the standard data types of C. */ -void -dbxout_init (asm_file, input_file_name, syms) - FILE *asm_file; +static void +dbxout_init (input_file_name) const char *input_file_name; - tree syms; { char ltext_label_name[100]; + tree syms = (*lang_hooks.decls.getdecls) (); - asmfile = asm_file; + asmfile = asm_out_file; typevec_len = 100; - typevec = (struct typeinfo *) xcalloc (typevec_len, sizeof typevec[0]); + typevec = (struct typeinfo *) ggc_calloc (typevec_len, sizeof typevec[0]); /* Convert Ltext into the appropriate format for local labels in case the system doesn't insert underscores in front of user generated @@ -384,11 +433,7 @@ dbxout_init (asm_file, input_file_name, syms) #endif { if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/')) - { - char *wdslash = xmalloc (strlen (cwd) + sizeof (FILE_NAME_JOINER)); - sprintf (wdslash, "%s%s", cwd, FILE_NAME_JOINER); - cwd = wdslash; - } + cwd = concat (cwd, FILE_NAME_JOINER, NULL); if (cwd) { #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY @@ -396,7 +441,9 @@ dbxout_init (asm_file, input_file_name, syms) #else /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ fprintf (asmfile, "%s", ASM_STABS_OP); output_quoted_string (asmfile, cwd); - fprintf (asmfile, ",%d,0,0,%s\n", N_SO, <ext_label_name[1]); + fprintf (asmfile, ",%d,0,0,", N_SO); + assemble_name (asmfile, ltext_label_name); + fputc ('\n', asmfile); #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ } } @@ -411,17 +458,19 @@ dbxout_init (asm_file, input_file_name, syms) /* Used to put `Ltext:' before the reference, but that loses on sun 4. */ fprintf (asmfile, "%s", ASM_STABS_OP); output_quoted_string (asmfile, input_file_name); - fprintf (asmfile, ",%d,0,0,%s\n", - N_SO, <ext_label_name[1]); + fprintf (asmfile, ",%d,0,0,", N_SO); + assemble_name (asmfile, ltext_label_name); + fputc ('\n', asmfile); text_section (); - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0); + (*targetm.asm_out.internal_label) (asmfile, "Ltext", 0); #endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ - /* Possibly output something to inform GDB that this compilation was by - GCC. It's easier for GDB to parse it when after the N_SO's. This - is used in Solaris 2. */ -#ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE - ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile); +#ifdef DBX_OUTPUT_GCC_MARKER + DBX_OUTPUT_GCC_MARKER (asmfile); +#else + /* Emit an N_OPT stab to indicate that this file was compiled by GCC. */ + fprintf (asmfile, "%s\"%s\",%d,0,0,0\n", + ASM_STABS_OP, STABS_GCC_MARKER, N_OPT); #endif lastfile = input_file_name; @@ -429,7 +478,7 @@ dbxout_init (asm_file, input_file_name, syms) next_type_number = 1; #ifdef DBX_USE_BINCL - current_file = (struct dbx_file *) xmalloc (sizeof *current_file); + current_file = (struct dbx_file *) ggc_alloc (sizeof *current_file); current_file->next = NULL; current_file->file_number = 0; current_file->next_type_number = 1; @@ -480,12 +529,13 @@ dbxout_typedefs (syms) /* Change to reading from a new source file. Generate a N_BINCL stab. */ -void -dbxout_start_new_source_file (filename) +static void +dbxout_start_source_file (line, filename) + unsigned int line ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED; { #ifdef DBX_USE_BINCL - struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n); + struct dbx_file *n = (struct dbx_file *) ggc_alloc (sizeof *n); n->next = current_file; n->file_number = next_file_number++; @@ -499,82 +549,194 @@ dbxout_start_new_source_file (filename) /* Revert to reading a previous source file. Generate a N_EINCL stab. */ -void -dbxout_resume_previous_source_file () +static void +dbxout_end_source_file (line) + unsigned int line ATTRIBUTE_UNUSED; { #ifdef DBX_USE_BINCL - struct dbx_file *next; - fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL); - next = current_file->next; - free (current_file); - current_file = next; + current_file = current_file->next; #endif } +#if defined (DBX_DEBUGGING_INFO) /* Output debugging info to FILE to switch to sourcefile FILENAME. */ -void +static void dbxout_source_file (file, filename) FILE *file; const char *filename; { - char ltext_label_name[100]; - if (filename && (lastfile == 0 || strcmp (filename, lastfile))) { #ifdef DBX_OUTPUT_SOURCE_FILENAME DBX_OUTPUT_SOURCE_FILENAME (file, filename); #else + char ltext_label_name[100]; + ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", source_label_number); fprintf (file, "%s", ASM_STABS_OP); output_quoted_string (file, filename); - fprintf (file, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); + fprintf (asmfile, ",%d,0,0,", N_SOL); + assemble_name (asmfile, ltext_label_name); + fputc ('\n', asmfile); if (current_function_decl != NULL_TREE && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) ; /* Don't change section amid function. */ else text_section (); - ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", source_label_number); + (*targetm.asm_out.internal_label) (file, "Ltext", source_label_number); source_label_number++; #endif lastfile = filename; } } -/* Output a line number symbol entry into output stream FILE, - for source file FILENAME and line number LINENO. */ +/* Output a line number symbol entry for source file FILENAME and line + number LINENO. */ -void -dbxout_source_line (file, filename, lineno) - FILE *file; +static void +dbxout_source_line (lineno, filename) + unsigned int lineno; const char *filename; - int lineno; { - dbxout_source_file (file, filename); + dbxout_source_file (asmfile, filename); #ifdef ASM_OUTPUT_SOURCE_LINE - ASM_OUTPUT_SOURCE_LINE (file, lineno); + ASM_OUTPUT_SOURCE_LINE (asmfile, lineno); #else - fprintf (file, "%s%d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno); + fprintf (asmfile, "%s%d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno); +#endif +} + +/* Describe the beginning of an internal block within a function. */ + +static void +dbxout_begin_block (line, n) + unsigned int line ATTRIBUTE_UNUSED; + unsigned int n; +{ + (*targetm.asm_out.internal_label) (asmfile, "LBB", n); +} + +/* Describe the end line-number of an internal block within a function. */ + +static void +dbxout_end_block (line, n) + unsigned int line ATTRIBUTE_UNUSED; + unsigned int n; +{ + (*targetm.asm_out.internal_label) (asmfile, "LBE", n); +} + +/* Output dbx data for a function definition. + This includes a definition of the function name itself (a symbol), + definitions of the parameters (locating them in the parameter list) + and then output the block that makes up the function's body + (including all the auto variables of the function). */ + +static void +dbxout_function_decl (decl) + tree decl; +{ +#ifndef DBX_FUNCTION_FIRST + dbxout_begin_function (decl); +#endif + dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); +#ifdef DBX_OUTPUT_FUNCTION_END + DBX_OUTPUT_FUNCTION_END (asmfile, decl); +#endif + if (use_gnu_debug_info_extensions +#if defined(NO_DBX_FUNCTION_END) + && ! NO_DBX_FUNCTION_END #endif + && targetm.have_named_sections) + dbxout_function_end (); +} + +#endif /* DBX_DEBUGGING_INFO */ + +/* Debug information for a global DECL. Called from toplev.c after + compilation proper has finished. */ +static void +dbxout_global_decl (decl) + tree decl; +{ + if (TREE_CODE (decl) == VAR_DECL + && ! DECL_EXTERNAL (decl) + && DECL_RTL_SET_P (decl)) /* Not necessary? */ + dbxout_symbol (decl, 0); } /* At the end of compilation, finish writing the symbol table. Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is to do nothing. */ -void -dbxout_finish (file, filename) - FILE *file ATTRIBUTE_UNUSED; +static void +dbxout_finish (filename) const char *filename ATTRIBUTE_UNUSED; { #ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END - DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename); + DBX_OUTPUT_MAIN_SOURCE_FILE_END (asmfile, filename); #endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */ } +/* Output floating point type values used by the 'R' stab letter. + These numbers come from include/aout/stab_gnu.h in binutils/gdb. + + There are only 3 real/complex types defined, and we need 7/6. + We use NF_SINGLE as a generic float type, and NF_COMPLEX as a generic + complex type. Since we have the type size anyways, we don't really need + to distinguish between different FP types, we only need to distinguish + between float and complex. This works fine with gdb. + + We only use this for complex types, to avoid breaking backwards + compatibility for real types. complex types aren't in ISO C90, so it is + OK if old debuggers don't understand the debug info we emit for them. */ + +/* ??? These are supposed to be IEEE types, but we don't check for that. + We could perhaps add additional numbers for non-IEEE types if we need + them. */ + +static void +dbxout_fptype_value (type) + tree type; +{ + char value = '0'; + enum machine_mode mode = TYPE_MODE (type); + + if (TREE_CODE (type) == REAL_TYPE) + { + if (mode == SFmode) + value = '1'; + else if (mode == DFmode) + value = '2'; + else if (mode == TFmode || mode == XFmode) + value = '6'; + else + /* Use NF_SINGLE as a generic real type for other sizes. */ + value = '1'; + } + else if (TREE_CODE (type) == COMPLEX_TYPE) + { + if (mode == SCmode) + value = '3'; + else if (mode == DCmode) + value = '4'; + else if (mode == TCmode || mode == XCmode) + value = '5'; + else + /* Use NF_COMPLEX as a generic complex type for other sizes. */ + value = '3'; + } + else + abort (); + + putc (value, asmfile); + CHARS (1); +} + /* Output the index of a type. */ static void @@ -587,7 +749,7 @@ dbxout_type_index (type) #else struct typeinfo *t = &typevec[TYPE_SYMTAB_ADDRESS (type)]; fprintf (asmfile, "(%d,%d)", t->file_number, t->type_number); - CHARS (7); + CHARS (9); #endif } @@ -645,25 +807,6 @@ dbxout_type_fields (type) if (tem != TYPE_FIELDS (type)) CONTIN; - if (use_gnu_debug_info_extensions - && flag_minimal_debug - && TREE_CODE (tem) == FIELD_DECL - && DECL_VIRTUAL_P (tem) - && DECL_ASSEMBLER_NAME (tem)) - { - have_used_extensions = 1; - CHARS (3 + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (tem))); - fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile); - dbxout_type (DECL_FCONTEXT (tem), 0, 0); - fprintf (asmfile, ":"); - dbxout_type (TREE_TYPE (tem), 0, 0); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - int_bit_position (tem)); - fputc (';', asmfile); - continue; - } - if (DECL_NAME (tem)) { fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); @@ -672,7 +815,7 @@ dbxout_type_fields (type) else { fprintf (asmfile, ":"); - CHARS (2); + CHARS (1); } if (use_gnu_debug_info_extensions @@ -689,32 +832,33 @@ dbxout_type_fields (type) dbxout_type ((TREE_CODE (tem) == FIELD_DECL && DECL_BIT_FIELD_TYPE (tem)) - ? DECL_BIT_FIELD_TYPE (tem) : TREE_TYPE (tem), 0, 0); + ? DECL_BIT_FIELD_TYPE (tem) : TREE_TYPE (tem), 0); if (TREE_CODE (tem) == VAR_DECL) { if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) { - const char *name = - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); + tree name = DECL_ASSEMBLER_NAME (tem); + have_used_extensions = 1; - fprintf (asmfile, ":%s;", name); - CHARS (strlen (name)); + fprintf (asmfile, ":%s;", IDENTIFIER_POINTER (name)); + CHARS (IDENTIFIER_LENGTH (name) + 2); } else - /* If TEM is non-static, GDB won't understand it. */ - fprintf (asmfile, ",0,0;"); + { + /* If TEM is non-static, GDB won't understand it. */ + fprintf (asmfile, ",0,0;"); + CHARS (5); + } } else { - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - int_bit_position (tem)); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - tree_low_cst (DECL_SIZE (tem), 1)); - fputc (';', asmfile); - CHARS (23); + putc (',', asmfile); + print_wide_int (int_bit_position (tem)); + putc (',', asmfile); + print_wide_int (tree_low_cst (DECL_SIZE (tem), 1)); + putc (';', asmfile); + CHARS (3); } } } @@ -760,12 +904,12 @@ dbxout_type_method_1 (decl, debug_name) if (DECL_VINDEX (decl) && host_integerp (DECL_VINDEX (decl), 0)) { - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - tree_low_cst (DECL_VINDEX (decl), 0)); - fputc (';', asmfile); - dbxout_type (DECL_CONTEXT (decl), 0, 0); + print_wide_int (tree_low_cst (DECL_VINDEX (decl), 0)); + putc (';', asmfile); + CHARS (1); + dbxout_type (DECL_CONTEXT (decl), 0); fprintf (asmfile, ";"); - CHARS (8); + CHARS (1); } } @@ -774,15 +918,15 @@ dbxout_type_method_1 (decl, debug_name) static void dbxout_type_methods (type) - register tree type; + tree type; { /* C++: put out the method names and their parameter lists */ tree methods = TYPE_METHODS (type); tree type_encoding; - register tree fndecl; - register tree last; + tree fndecl; + tree last; char formatted_type_identifier_length[16]; - register int type_identifier_length; + int type_identifier_length; if (methods == NULL_TREE) return; @@ -809,7 +953,7 @@ dbxout_type_methods (type) type_identifier_length = IDENTIFIER_LENGTH (type_encoding); - sprintf(formatted_type_identifier_length, "%d", type_identifier_length); + sprintf (formatted_type_identifier_length, "%d", type_identifier_length); if (TREE_CODE (methods) != TREE_VEC) fndecl = methods; @@ -820,7 +964,6 @@ dbxout_type_methods (type) while (fndecl) { - tree name = DECL_NAME (fndecl); int need_prefix = 1; /* Group together all the methods for the same operation. @@ -834,91 +977,42 @@ dbxout_type_methods (type) { /* This is the "mangled" name of the method. It encodes the argument types. */ - const char *debug_name = - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); - int show_arg_types = 0; + const char *debug_name; + + /* Skip methods that aren't FUNCTION_DECLs. (In C++, these + include TEMPLATE_DECLs.) The debugger doesn't know what + to do with such entities anyhow. */ + if (TREE_CODE (fndecl) != FUNCTION_DECL) + continue; + + debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); CONTIN; last = fndecl; - if (DECL_IGNORED_P (fndecl)) + /* Also ignore abstract methods; those are only interesting to + the DWARF backends. */ + if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT (fndecl)) continue; - if (flag_minimal_debug) + /* Redundantly output the plain name, since that's what gdb + expects. */ + if (need_prefix) { - char marker; - - /* We can't optimize a method which uses an anonymous - class, because the debugger will not be able to - associate the arbitrary class name with the actual - class. */ -#ifndef NO_DOLLAR_IN_LABEL - marker = '$'; -#else - marker = '.'; -#endif - if (strchr (debug_name, marker)) - show_arg_types = 1; - /* Detect ordinary methods because their mangled names - start with the operation name. */ - else if (!strncmp (IDENTIFIER_POINTER (name), debug_name, - IDENTIFIER_LENGTH (name))) - { - debug_name += IDENTIFIER_LENGTH (name); - if (debug_name[0] == '_' && debug_name[1] == '_') - { - const char *method_name = debug_name + 2; - const char *length_ptr = - formatted_type_identifier_length; - /* Get past const and volatile qualifiers. */ - while (*method_name == 'C' || *method_name == 'V') - method_name++; - /* Skip digits for length of type_encoding. */ - while (*method_name == *length_ptr && *length_ptr) - length_ptr++, method_name++; - if (! strncmp (method_name, - IDENTIFIER_POINTER (type_encoding), - type_identifier_length)) - method_name += type_identifier_length; - debug_name = method_name; - } - } - /* Detect constructors by their style of name mangling. */ - else if (debug_name[0] == '_' && debug_name[1] == '_') - { - const char *ctor_name = debug_name + 2; - const char *length_ptr = formatted_type_identifier_length; - while (*ctor_name == 'C' || *ctor_name == 'V') - ctor_name++; - /* Skip digits for length of type_encoding. */ - while (*ctor_name == *length_ptr && *length_ptr) - length_ptr++, ctor_name++; - if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name, - type_identifier_length)) - debug_name = ctor_name + type_identifier_length; - } - /* The other alternative is a destructor. */ - else - show_arg_types = 1; - - /* Output the operation name just once, for the first method - that we output. */ - if (need_prefix) - { - fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); - CHARS (IDENTIFIER_LENGTH (name) + 2); - need_prefix = 0; - } + tree name = DECL_NAME (fndecl); + fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); + CHARS (IDENTIFIER_LENGTH (name) + 2); + need_prefix = 0; } - dbxout_type (TREE_TYPE (fndecl), 0, show_arg_types); + dbxout_type (TREE_TYPE (fndecl), 0); dbxout_type_method_1 (fndecl, debug_name); } if (!need_prefix) { - putc (';', asmfile); + putc (';', asmfile); CHARS (1); } } @@ -934,9 +1028,9 @@ dbxout_range_type (type) { fprintf (asmfile, "r"); if (TREE_TYPE (type)) - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); else if (TREE_CODE (type) != INTEGER_TYPE) - dbxout_type (type, 0, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */ + dbxout_type (type, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */ else { /* Traditionally, we made sure 'int' was type 1, and builtin types @@ -960,23 +1054,30 @@ dbxout_range_type (type) if (TYPE_MIN_VALUE (type) != 0 && host_integerp (TYPE_MIN_VALUE (type), 0)) { - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - tree_low_cst (TYPE_MIN_VALUE (type), 0)); + putc (';', asmfile); + CHARS (1); + print_wide_int (tree_low_cst (TYPE_MIN_VALUE (type), 0)); } else - fprintf (asmfile, ";0"); + { + fprintf (asmfile, ";0"); + CHARS (2); + } if (TYPE_MAX_VALUE (type) != 0 && host_integerp (TYPE_MAX_VALUE (type), 0)) { - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - tree_low_cst (TYPE_MAX_VALUE (type), 0)); - fputc (';', asmfile); + putc (';', asmfile); + CHARS (1); + print_wide_int (tree_low_cst (TYPE_MAX_VALUE (type), 0)); + putc (';', asmfile); + CHARS (1); } else - fprintf (asmfile, ";-1;"); + { + fprintf (asmfile, ";-1;"); + CHARS (4); + } } /* Output a reference to a type. If the type has not yet been @@ -987,22 +1088,21 @@ dbxout_range_type (type) If FULL is nonzero, and the type has been described only with a forward-reference, output the definition now. If FULL is zero in this case, just refer to the forward-reference - using the number previously allocated. - - If SHOW_ARG_TYPES is nonzero, we output a description of the argument - types for a METHOD_TYPE. */ + using the number previously allocated. */ static void -dbxout_type (type, full, show_arg_types) +dbxout_type (type, full) tree type; int full; - int show_arg_types; { - register tree tem; + tree tem; + tree main_variant; static int anonymous_type_number = 0; if (TREE_CODE (type) == VECTOR_TYPE) - type = TYPE_DEBUG_REPRESENTATION_TYPE (type); + /* The frontend feeds us a representation for the vector as a struct + containing an array. Pull out the array type. */ + type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type))); /* If there was an input error and we don't really have a type, avoid crashing and write something that is at least valid @@ -1011,24 +1111,24 @@ dbxout_type (type, full, show_arg_types) type = integer_type_node; else { - /* Try to find the "main variant" with the same name but not const - or volatile. (Since stabs does not distinguish const and volatile, - there is no need to make them separate types. But types with - different names are usefully distinguished.) */ - - for (tem = TYPE_MAIN_VARIANT (type); tem; tem = TYPE_NEXT_VARIANT (tem)) - if (!TYPE_READONLY (tem) && !TYPE_VOLATILE (tem) - && TYPE_NAME (tem) == TYPE_NAME (type)) - { - type = tem; - break; - } if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type))) full = 0; } + /* Try to find the "main variant" with the same name. */ + if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL + && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) + main_variant = TREE_TYPE (TYPE_NAME (type)); + else + main_variant = TYPE_MAIN_VARIANT (type); + + /* If we are not using extensions, stabs does not distinguish const and + volatile, so there is no need to make them separate types. */ + if (!use_gnu_debug_info_extensions) + type = main_variant; + if (TYPE_SYMTAB_ADDRESS (type) == 0) { /* Type has no dbx number assigned. Assign next available number. */ @@ -1039,8 +1139,9 @@ dbxout_type (type, full, show_arg_types) if (next_type_number == typevec_len) { typevec - = (struct typeinfo *) xrealloc (typevec, - typevec_len * 2 * sizeof typevec[0]); + = (struct typeinfo *) ggc_realloc (typevec, + (typevec_len * 2 + * sizeof typevec[0])); memset ((char *) (typevec + typevec_len), 0, typevec_len * sizeof typevec[0]); typevec_len *= 2; @@ -1076,7 +1177,7 @@ dbxout_type (type, full, show_arg_types) Sun dbx crashes if we do. */ if (! full || !COMPLETE_TYPE_P (type) /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + || ! host_integerp (TYPE_SIZE (type), 1)) return; break; case TYPE_DEFINED: @@ -1101,7 +1202,7 @@ dbxout_type (type, full, show_arg_types) && !full) || !COMPLETE_TYPE_P (type) /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + || ! host_integerp (TYPE_SIZE (type), 1)) { typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; return; @@ -1118,12 +1219,30 @@ dbxout_type (type, full, show_arg_types) typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_DEFINED; - if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) - { - dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0, 0); + /* If this type is a variant of some other, hand off. Types with + different names are usefully distinguished. We only distinguish + cv-qualified types if we're using extensions. */ + if (TYPE_READONLY (type) > TYPE_READONLY (main_variant)) + { + putc ('k', asmfile); + CHARS (1); + dbxout_type (build_type_variant (type, 0, TYPE_VOLATILE (type)), 0); return; } + else if (TYPE_VOLATILE (type) > TYPE_VOLATILE (main_variant)) + { + putc ('B', asmfile); + CHARS (1); + dbxout_type (build_type_variant (type, TYPE_READONLY (type), 0), 0); + return; + } + else if (main_variant != TYPE_MAIN_VARIANT (type)) + { + /* 'type' is a typedef; output the type it refers to. */ + dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0); + return; + } + /* else continue. */ switch (TREE_CODE (type)) { @@ -1146,24 +1265,43 @@ dbxout_type (type, full, show_arg_types) This used to use `r2' explicitly and we used to take care to make sure that `char' was type number 2. */ fprintf (asmfile, "r"); + CHARS (1); dbxout_type_index (type); fprintf (asmfile, ";0;127;"); + CHARS (7); } /* If this is a subtype of another integer type, always prefer to write it as a subtype. */ else if (TREE_TYPE (type) != 0 - && TREE_CODE (TREE_TYPE (type)) == INTEGER_CST) - dbxout_range_type (type); + && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) + { + /* If the size is non-standard, say what it is if we can use + GDB extensions. */ + + if (use_gnu_debug_info_extensions + && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) + { + have_used_extensions = 1; + fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); + CHARS (5); + } + + dbxout_range_type (type); + } else - { + { /* If the size is non-standard, say what it is if we can use GDB extensions. */ if (use_gnu_debug_info_extensions && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) - fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); + { + have_used_extensions = 1; + fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); + CHARS (5); + } /* If we can use GDB extensions and the size is wider than a long (the size used by GDB to read them) or we may have @@ -1177,82 +1315,95 @@ dbxout_type (type, full, show_arg_types) larger. This is because we print the bounds as signed decimal, and hence they can't span same size unsigned types. */ - if (use_gnu_debug_info_extensions + if (use_gnu_debug_info_extensions && TYPE_MIN_VALUE (type) != 0 && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST && TYPE_MAX_VALUE (type) != 0 && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node) - || (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node) + || ((TYPE_PRECISION (type) + == TYPE_PRECISION (integer_type_node)) && TREE_UNSIGNED (type)) || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT || (TYPE_PRECISION (type) == HOST_BITS_PER_WIDE_INT && TREE_UNSIGNED (type)))) { fprintf (asmfile, "r"); + CHARS (1); dbxout_type_index (type); fprintf (asmfile, ";"); + CHARS (1); print_int_cst_octal (TYPE_MIN_VALUE (type)); fprintf (asmfile, ";"); + CHARS (1); print_int_cst_octal (TYPE_MAX_VALUE (type)); fprintf (asmfile, ";"); + CHARS (1); } else /* Output other integer types as subranges of `int'. */ dbxout_range_type (type); - } + } - CHARS (22); break; case REAL_TYPE: /* This used to say `r1' and we used to take care to make sure that `int' was type number 1. */ fprintf (asmfile, "r"); + CHARS (1); dbxout_type_index (integer_type_node); - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type)); + putc (';', asmfile); + CHARS (1); + print_wide_int (int_size_in_bytes (type)); fputs (";0;", asmfile); - CHARS (13); + CHARS (3); break; case CHAR_TYPE: if (use_gnu_debug_info_extensions) { + have_used_extensions = 1; fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); + CHARS (2); + print_wide_int (BITS_PER_UNIT * int_size_in_bytes (type)); fputs (";-20;", asmfile); + CHARS (4); } else { /* Output the type `char' as a subrange of itself. That is what pcc seems to do. */ fprintf (asmfile, "r"); + CHARS (1); dbxout_type_index (char_type_node); fprintf (asmfile, ";0;%d;", TREE_UNSIGNED (type) ? 255 : 127); + CHARS (7); } - CHARS (9); break; case BOOLEAN_TYPE: if (use_gnu_debug_info_extensions) { + have_used_extensions = 1; fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); + CHARS (2); + print_wide_int (BITS_PER_UNIT * int_size_in_bytes (type)); fputs (";-16;", asmfile); + CHARS (4); } else /* Define as enumeral type (False, True) */ - fprintf (asmfile, "eFalse:0,True:1,;"); - CHARS (17); + { + fprintf (asmfile, "eFalse:0,True:1,;"); + CHARS (17); + } break; case FILE_TYPE: putc ('d', asmfile); CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); break; case COMPLEX_TYPE: @@ -1260,34 +1411,34 @@ dbxout_type (type, full, show_arg_types) if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) { - fprintf (asmfile, "r"); - dbxout_type_index (type); - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - 2 * int_size_in_bytes (TREE_TYPE (type))); + putc ('R', asmfile); + CHARS (1); + dbxout_fptype_value (type); + putc (';', asmfile); + CHARS (1); + print_wide_int (2 * int_size_in_bytes (TREE_TYPE (type))); fputs (";0;", asmfile); - CHARS (12); /* The number is probably incorrect here. */ + CHARS (3); } else { /* Output a complex integer type as a structure, pending some other way to do it. */ - fputc ('s', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type)); - + putc ('s', asmfile); + CHARS (1); + print_wide_int (int_size_in_bytes (type)); fprintf (asmfile, "real:"); - CHARS (10); - dbxout_type (TREE_TYPE (type), 0, 0); - fprintf (asmfile, ",%d,%d;", - 0, TYPE_PRECISION (TREE_TYPE (type))); - CHARS (8); + CHARS (5); + + dbxout_type (TREE_TYPE (type), 0); + fprintf (asmfile, ",0,%d;", TYPE_PRECISION (TREE_TYPE (type))); + CHARS (7); fprintf (asmfile, "imag:"); CHARS (5); - dbxout_type (TREE_TYPE (type), 0, 0); - fprintf (asmfile, ",%d,%d;;", - TYPE_PRECISION (TREE_TYPE (type)), + dbxout_type (TREE_TYPE (type), 0); + fprintf (asmfile, ",%d,%d;;", TYPE_PRECISION (TREE_TYPE (type)), TYPE_PRECISION (TREE_TYPE (type))); - CHARS (9); + CHARS (10); } break; @@ -1296,17 +1447,22 @@ dbxout_type (type, full, show_arg_types) { have_used_extensions = 1; fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputc (';', asmfile); + CHARS (2); + print_wide_int (BITS_PER_UNIT * int_size_in_bytes (type)); + putc (';', asmfile); + CHARS (1); + /* Check if a bitstring type, which in Chill is different from a [power]set. */ if (TYPE_STRING_FLAG (type)) - fprintf (asmfile, "@S;"); + { + fprintf (asmfile, "@S;"); + CHARS (3); + } } putc ('S', asmfile); CHARS (1); - dbxout_type (TYPE_DOMAIN (type), 0, 0); + dbxout_type (TYPE_DOMAIN (type), 0); break; case ARRAY_TYPE: @@ -1315,15 +1471,14 @@ dbxout_type (type, full, show_arg_types) { have_used_extensions = 1; fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputc (';', asmfile); - fprintf (asmfile, "@S;"); - putc ('S', asmfile); - CHARS (1); - dbxout_type (TYPE_DOMAIN (type), 0, 0); + CHARS (2); + print_wide_int (BITS_PER_UNIT * int_size_in_bytes (type)); + fprintf (asmfile, ";@S;S"); + CHARS (5); + dbxout_type (TYPE_DOMAIN (type), 0); break; } + /* Output "a" followed by a range type definition for the index type of the array followed by a reference to the target-type. @@ -1334,21 +1489,25 @@ dbxout_type (type, full, show_arg_types) { have_used_extensions = 1; fprintf (asmfile, "@S;"); + CHARS (3); } tem = TYPE_DOMAIN (type); if (tem == NULL) { fprintf (asmfile, "ar"); + CHARS (2); dbxout_type_index (integer_type_node); fprintf (asmfile, ";0;-1;"); + CHARS (6); } else { fprintf (asmfile, "a"); + CHARS (1); dbxout_range_type (tem); } - CHARS (14); - dbxout_type (TREE_TYPE (type), 0, 0); + + dbxout_type (TREE_TYPE (type), 0); break; case RECORD_TYPE: @@ -1370,7 +1529,7 @@ dbxout_type (type, full, show_arg_types) && !full) || !COMPLETE_TYPE_P (type) /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + || ! host_integerp (TYPE_SIZE (type), 1)) { /* If the type is just a cross reference, output one and mark the type as partially described. @@ -1380,7 +1539,7 @@ dbxout_type (type, full, show_arg_types) another type's definition; instead, output an xref and let the definition come when the name is defined. */ fputs ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu", asmfile); - CHARS (3); + CHARS (2); #if 0 /* This assertion is legitimately false in C++. */ /* We shouldn't be outputting a reference to a type before its definition unless the type has a tag name. @@ -1391,16 +1550,21 @@ dbxout_type (type, full, show_arg_types) if (TYPE_NAME (type) != 0) dbxout_type_name (type); else - fprintf (asmfile, "$$%d", anonymous_type_number++); + { + fprintf (asmfile, "$$%d", anonymous_type_number++); + CHARS (5); + } + fprintf (asmfile, ":"); + CHARS (1); typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; break; } /* Identify record or union, and print its size. */ - fputc (((TREE_CODE (type) == RECORD_TYPE) ? 's' : 'u'), asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - int_size_in_bytes (type)); + putc (((TREE_CODE (type) == RECORD_TYPE) ? 's' : 'u'), asmfile); + CHARS (1); + print_wide_int (int_size_in_bytes (type)); if (use_gnu_debug_info_extensions) { @@ -1420,13 +1584,21 @@ dbxout_type (type, full, show_arg_types) have_used_extensions = 1; putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile); putc (TREE_VIA_PUBLIC (child) ? '2' : '0', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - (tree_low_cst (BINFO_OFFSET (child), 0) - * BITS_PER_UNIT)); - fputc (',', asmfile); - CHARS (15); - dbxout_type (BINFO_TYPE (child), 0, 0); + CHARS (2); + if (TREE_VIA_VIRTUAL (child) && strcmp (lang_hooks.name, "GNU C++") == 0) + /* For a virtual base, print the (negative) offset within + the vtable where we must look to find the necessary + adjustment. */ + print_wide_int (tree_low_cst (BINFO_VPTR_FIELD (child), 0) + * BITS_PER_UNIT); + else + print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0) + * BITS_PER_UNIT); + putc (',', asmfile); + CHARS (1); + dbxout_type (BINFO_TYPE (child), 0); putc (';', asmfile); + CHARS (1); } else { @@ -1434,24 +1606,25 @@ dbxout_type (type, full, show_arg_types) which have the same names at the types they hold. */ dbxout_type_name (BINFO_TYPE (child)); putc (':', asmfile); - dbxout_type (BINFO_TYPE (child), full, 0); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - tree_low_cst (BINFO_OFFSET (child), 0) - * BITS_PER_UNIT); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - (tree_low_cst (DECL_SIZE (TYPE_NAME - (BINFO_TYPE (child))), 0) - * BITS_PER_UNIT)); - fputc (';', asmfile); - CHARS (20); + CHARS (1); + dbxout_type (BINFO_TYPE (child), full); + putc (',', asmfile); + CHARS (1); + print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0) + * BITS_PER_UNIT); + putc (',', asmfile); + CHARS (1); + print_wide_int (tree_low_cst (DECL_SIZE + (TYPE_NAME + (BINFO_TYPE (child))), + 0) + * BITS_PER_UNIT); + putc (';', asmfile); + CHARS (1); } } } - CHARS (11); - /* Write out the field declarations. */ dbxout_type_fields (type); if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) @@ -1461,6 +1634,7 @@ dbxout_type (type, full, show_arg_types) } putc (';', asmfile); + CHARS (1); if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE /* Avoid the ~ if we don't really need it--it confuses dbx. */ @@ -1470,6 +1644,7 @@ dbxout_type (type, full, show_arg_types) /* Tell GDB+ that it may keep reading. */ putc ('~', asmfile); + CHARS (1); /* We need to write out info about what field this class uses as its "main" vtable pointer field, because if this @@ -1478,10 +1653,12 @@ dbxout_type (type, full, show_arg_types) if (TYPE_VFIELD (type)) { putc ('%', asmfile); - dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0); + CHARS (1); + dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0); } + putc (';', asmfile); - CHARS (3); + CHARS (1); } break; @@ -1496,10 +1673,11 @@ dbxout_type (type, full, show_arg_types) || !COMPLETE_TYPE_P (type)) { fprintf (asmfile, "xe"); - CHARS (3); + CHARS (2); dbxout_type_name (type); typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; - fprintf (asmfile, ":"); + putc (':', asmfile); + CHARS (1); return; } #ifdef DBX_OUTPUT_ENUM @@ -1507,28 +1685,31 @@ dbxout_type (type, full, show_arg_types) #else if (use_gnu_debug_info_extensions && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) - fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); + { + fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); + CHARS (5); + } + putc ('e', asmfile); CHARS (1); for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) { fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem))); + CHARS (IDENTIFIER_LENGTH (TREE_PURPOSE (tem)) + 1); if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0) - fprintf (asmfile, HOST_WIDE_INT_PRINT_UNSIGNED, - TREE_INT_CST_LOW (TREE_VALUE (tem))); + print_wide_int (TREE_INT_CST_LOW (TREE_VALUE (tem))); else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1 && (HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0) - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (TREE_VALUE (tem))); + print_wide_int (TREE_INT_CST_LOW (TREE_VALUE (tem))); else print_int_cst_octal (TREE_VALUE (tem)); - fprintf (asmfile, ","); - CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem))); + + putc (',', asmfile); + CHARS (1); if (TREE_CHAIN (tem) != 0) - { - CONTIN; - } + CONTIN; } + putc (';', asmfile); CHARS (1); #endif @@ -1537,7 +1718,7 @@ dbxout_type (type, full, show_arg_types) case POINTER_TYPE: putc ('*', asmfile); CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); break; case METHOD_TYPE: @@ -1546,34 +1727,19 @@ dbxout_type (type, full, show_arg_types) have_used_extensions = 1; putc ('#', asmfile); CHARS (1); - if (flag_minimal_debug && !show_arg_types) - { - /* Normally, just output the return type. - The argument types are encoded in the method name. */ - putc ('#', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - putc (';', asmfile); - CHARS (1); - } - else - { - /* When outputting destructors, we need to write - the argument types out longhand. */ - dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0); - putc (',', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - dbxout_args (TYPE_ARG_TYPES (type)); - putc (';', asmfile); - CHARS (1); - } + + /* Write the argument types out longhand. */ + dbxout_type (TYPE_METHOD_BASETYPE (type), 0); + putc (',', asmfile); + CHARS (1); + dbxout_type (TREE_TYPE (type), 0); + dbxout_args (TYPE_ARG_TYPES (type)); + putc (';', asmfile); + CHARS (1); } else - { - /* Treat it as a function type. */ - dbxout_type (TREE_TYPE (type), 0, 0); - } + /* Treat it as a function type. */ + dbxout_type (TREE_TYPE (type), 0); break; case OFFSET_TYPE: @@ -1582,17 +1748,14 @@ dbxout_type (type, full, show_arg_types) have_used_extensions = 1; putc ('@', asmfile); CHARS (1); - dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0); + dbxout_type (TYPE_OFFSET_BASETYPE (type), 0); putc (',', asmfile); CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); } else - { - /* Should print as an int, because it is really - just an offset. */ - dbxout_type (integer_type_node, 0, 0); - } + /* Should print as an int, because it is really just an offset. */ + dbxout_type (integer_type_node, 0); break; case REFERENCE_TYPE: @@ -1600,13 +1763,13 @@ dbxout_type (type, full, show_arg_types) have_used_extensions = 1; putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile); CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); break; case FUNCTION_TYPE: putc ('f', asmfile); CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); break; default: @@ -1639,6 +1802,7 @@ print_int_cst_octal (c) high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1); fprintf (asmfile, "0"); + CHARS (1); if (excess == 3) { @@ -1657,6 +1821,7 @@ print_int_cst_octal (c) - 1); fprintf (asmfile, "%o%01o", (int) beg, (int) middle); + CHARS (2); print_octal (end, HOST_BITS_PER_WIDE_INT / 3); } } @@ -1670,6 +1835,27 @@ print_octal (value, digits) for (i = digits - 1; i >= 0; i--) fprintf (asmfile, "%01o", (int) ((value >> (3 * i)) & 7)); + + CHARS (digits); +} + +/* Output C in decimal while adjusting the number of digits written. */ + +static void +print_wide_int (c) + HOST_WIDE_INT c; +{ + int digs = 0; + + fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, c); + + if (c < 0) + digs++, c = -c; + + while (c > 0) + c /= 10; digs++; + + CHARS (digs); } /* Output the name of type TYPE, with no punctuation. @@ -1678,7 +1864,7 @@ print_octal (value, digits) static void dbxout_type_name (type) - register tree type; + tree type; { tree t; if (TYPE_NAME (type) == 0) @@ -1697,6 +1883,33 @@ dbxout_type_name (type) fprintf (asmfile, "%s", IDENTIFIER_POINTER (t)); CHARS (IDENTIFIER_LENGTH (t)); } + +/* Output leading leading struct or class names needed for qualifying + type whose scope is limited to a struct or class. */ + +static void +dbxout_class_name_qualifiers (decl) + tree decl; +{ + tree context = decl_type_context (decl); + + if (context != NULL_TREE + && TREE_CODE(context) == RECORD_TYPE + && TYPE_NAME (context) != 0 + && (TREE_CODE (TYPE_NAME (context)) == IDENTIFIER_NODE + || (DECL_NAME (TYPE_NAME (context)) != 0))) + { + tree name = TYPE_NAME (context); + + if (TREE_CODE (name) == TYPE_DECL) + { + dbxout_class_name_qualifiers (name); + name = DECL_NAME (name); + } + fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); + CHARS (IDENTIFIER_LENGTH (name) + 2); + } +} /* Output a .stabs for the symbol defined by DECL, which must be a ..._DECL node in the normal namespace. @@ -1761,9 +1974,9 @@ dbxout_symbol (decl, local) current_sym_addr = XEXP (DECL_RTL (decl), 0); if (TREE_TYPE (type)) - dbxout_type (TREE_TYPE (type), 0, 0); + dbxout_type (TREE_TYPE (type), 0); else - dbxout_type (void_type_node, 0, 0); + dbxout_type (void_type_node, 0); /* For a nested function, when that function is compiled, mention the containing function name @@ -1817,7 +2030,11 @@ dbxout_symbol (decl, local) && !TREE_ASM_WRITTEN (TYPE_NAME (type)) /* Distinguish the implicit typedefs of C++ from explicit ones that might be found in C. */ - && DECL_ARTIFICIAL (decl)) + && DECL_ARTIFICIAL (decl) + /* Do not generate a tag for records of variable size, + since this type can not be properly described in the + DBX format, and it confuses some tools such as objdump. */ + && host_integerp (TYPE_SIZE (type), 1)) { tree name = TYPE_NAME (type); if (TREE_CODE (name) == TYPE_DECL) @@ -1830,13 +2047,21 @@ dbxout_symbol (decl, local) fprintf (asmfile, "%s\"%s:T", ASM_STABS_OP, IDENTIFIER_POINTER (name)); - dbxout_type (type, 1, 0); + dbxout_type (type, 1); dbxout_finish_symbol (NULL_TREE); } + /* Output .stabs (or whatever) and leading double quote. */ + fprintf (asmfile, "%s\"", ASM_STABS_OP); + + if (use_gnu_debug_info_extensions) + { + /* Output leading class/struct qualifiers. */ + dbxout_class_name_qualifiers (decl); + } + /* Output typedef name. */ - fprintf (asmfile, "%s\"%s:", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (decl))); + fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (decl))); /* Short cut way to output a tag also. */ if ((TREE_CODE (type) == RECORD_TYPE @@ -1845,7 +2070,7 @@ dbxout_symbol (decl, local) && TYPE_NAME (type) == decl /* Distinguish the implicit typedefs of C++ from explicit ones that might be found in C. */ - && DECL_ARTIFICIAL (decl)) + && DECL_ARTIFICIAL (decl)) { if (use_gnu_debug_info_extensions && have_used_extensions) { @@ -1861,13 +2086,13 @@ dbxout_symbol (decl, local) putc ('t', asmfile); current_sym_code = DBX_TYPE_DECL_STABS_CODE; - dbxout_type (type, 1, 0); + dbxout_type (type, 1); dbxout_finish_symbol (decl); did_output = 1; } - /* Don't output a tag if this is an incomplete type (TYPE_SIZE is - zero). This prevents the sun4 Sun OS 4.x dbx from crashing. */ + /* Don't output a tag if this is an incomplete type. This prevents + the sun4 Sun OS 4.x dbx from crashing. */ if (tag_needed && TYPE_NAME (type) != 0 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE @@ -1891,7 +2116,7 @@ dbxout_symbol (decl, local) fprintf (asmfile, "%s\"%s:T", ASM_STABS_OP, IDENTIFIER_POINTER (name)); - dbxout_type (type, 1, 0); + dbxout_type (type, 1); dbxout_finish_symbol (NULL_TREE); did_output = 1; } @@ -1909,7 +2134,7 @@ dbxout_symbol (decl, local) /* Some debuggers fail when given NULL names, so give this a harmless name of ` '. */ fprintf (asmfile, "%s\" :T", ASM_STABS_OP); - dbxout_type (type, 1, 0); + dbxout_type (type, 1); dbxout_finish_symbol (NULL_TREE); } @@ -1926,7 +2151,7 @@ dbxout_symbol (decl, local) case RESULT_DECL: /* Named return value, treat like a VAR_DECL. */ case VAR_DECL: - if (DECL_RTL (decl) == 0) + if (! DECL_RTL_SET_P (decl)) return 0; /* Don't mention a variable that is external. Let the file that defines it describe it. */ @@ -1970,7 +2195,7 @@ dbxout_symbol (decl, local) /* else it is something we handle like a normal variable. */ } - DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); + SET_DECL_RTL (decl, eliminate_regs (DECL_RTL (decl), 0, NULL_RTX)); #ifdef LEAF_REG_REMAP if (current_function_uses_only_leaf_regs) leaf_renumber_regs_insn (DECL_RTL (decl)); @@ -1978,7 +2203,7 @@ dbxout_symbol (decl, local) result = dbxout_symbol_location (decl, type, 0, DECL_RTL (decl)); break; - + default: break; } @@ -2002,33 +2227,28 @@ dbxout_symbol_location (decl, type, suffix, home) /* Don't mention a variable at all if it was completely optimized into nothingness. - + If the decl was from an inline function, then its rtl is not identically the rtl that was used in this particular compilation. */ - if (GET_CODE (home) == REG) - { - regno = REGNO (home); - if (regno >= FIRST_PSEUDO_REGISTER) - return 0; - } - else if (GET_CODE (home) == SUBREG) + if (GET_CODE (home) == SUBREG) { rtx value = home; - int offset = 0; + while (GET_CODE (value) == SUBREG) - { - offset += SUBREG_WORD (value); - value = SUBREG_REG (value); - } + value = SUBREG_REG (value); if (GET_CODE (value) == REG) { - regno = REGNO (value); - if (regno >= FIRST_PSEUDO_REGISTER) + if (REGNO (value) >= FIRST_PSEUDO_REGISTER) return 0; - regno += offset; } - alter_subreg (home); + home = alter_subreg (&home); + } + if (GET_CODE (home) == REG) + { + regno = REGNO (home); + if (regno >= FIRST_PSEUDO_REGISTER) + return 0; } /* The kind-of-variable letter depends on where @@ -2063,7 +2283,7 @@ dbxout_symbol_location (decl, type, suffix, home) we rely on the fact that error_mark_node initializers always end up in bss for C++ and never end up in bss for C. */ if (DECL_INITIAL (decl) == 0 - || (!strcmp (lang_identify (), "cplusplus") + || (!strcmp (lang_hooks.name, "GNU C++") && DECL_INITIAL (decl) == error_mark_node)) current_sym_code = N_LCSYM; else if (DECL_IN_TEXT_SECTION (decl)) @@ -2072,6 +2292,21 @@ dbxout_symbol_location (decl, type, suffix, home) current_sym_code = DBX_STATIC_CONST_VAR_CODE; else { + /* Some ports can transform a symbol ref into a label ref, + because the symbol ref is too far away and has to be + dumped into a constant pool. Alternatively, the symbol + in the constant pool might be referenced by a different + symbol. */ + if (GET_CODE (current_sym_addr) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (current_sym_addr)) + { + rtx tmp = get_pool_constant (current_sym_addr); + + if (GET_CODE (tmp) == SYMBOL_REF + || GET_CODE (tmp) == LABEL_REF) + current_sym_addr = tmp; + } + /* Ultrix `as' seems to need this. */ #ifdef DBX_STATIC_STAB_DATA_SECTION data_section (); @@ -2107,6 +2342,8 @@ dbxout_symbol_location (decl, type, suffix, home) { letter = 'r'; current_sym_code = N_RSYM; + if (REGNO (XEXP (home, 0)) >= FIRST_PSEUDO_REGISTER) + return 0; current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0))); } else @@ -2160,7 +2397,15 @@ dbxout_symbol_location (decl, type, suffix, home) } else if (GET_CODE (home) == CONCAT) { - tree subtype = TREE_TYPE (type); + tree subtype; + + /* If TYPE is not a COMPLEX_TYPE (it might be a RECORD_TYPE, + for example), then there is no easy way to figure out + what SUBTYPE should be. So, we give up. */ + if (TREE_CODE (type) != COMPLEX_TYPE) + return 0; + + subtype = TREE_TYPE (type); /* If the variable's storage is in two parts, output each as a separate stab with a modified name. */ @@ -2195,7 +2440,7 @@ dbxout_symbol_location (decl, type, suffix, home) #endif dbxout_symbol_name (decl, suffix, letter); - dbxout_type (type, 0, 0); + dbxout_type (type, 0); dbxout_finish_symbol (decl); #ifdef DBX_STATIC_BLOCK_END @@ -2231,7 +2476,8 @@ dbxout_symbol_name (decl, suffix, letter) fprintf (asmfile, "%s\"%s%s:", ASM_STABS_OP, name, (suffix ? suffix : "")); - if (letter) putc (letter, asmfile); + if (letter) + putc (letter, asmfile); } static void @@ -2265,7 +2511,7 @@ dbxout_finish_symbol (sym) #endif } -/* Output definitions of all the decls in a chain. Return non-zero if +/* Output definitions of all the decls in a chain. Return nonzero if anything was output */ int @@ -2306,7 +2552,7 @@ dbxout_parms (parms) 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); + SET_DECL_RTL (parms, eliminate_regs (DECL_RTL (parms), 0, NULL_RTX)); #ifdef LEAF_REG_REMAP if (current_function_uses_only_leaf_regs) { @@ -2349,8 +2595,8 @@ dbxout_parms (parms) } /* It is quite tempting to use: - - dbxout_type (TREE_TYPE (parms), 0, 0); + + dbxout_type (TREE_TYPE (parms), 0); as the next statement, rather than using DECL_ARG_TYPE(), so that gcc reports the actual type of the parameter, rather @@ -2361,8 +2607,8 @@ dbxout_parms (parms) passing a float to an unprototyped function, gcc will store a double on the stack, but if we emit a stab saying the type is a float, then gdb will only read in a single value, and this will - produce an erropneous value. */ - dbxout_type (DECL_ARG_TYPE (parms), 0, 0); + produce an erroneous value. */ + dbxout_type (DECL_ARG_TYPE (parms), 0); current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr); dbxout_finish_symbol (parms); } @@ -2413,7 +2659,7 @@ dbxout_parms (parms) regparm_letter); } - dbxout_type (parm_type, 0, 0); + dbxout_type (parm_type, 0); dbxout_finish_symbol (parms); } else if (GET_CODE (DECL_RTL (parms)) == MEM @@ -2453,7 +2699,8 @@ dbxout_parms (parms) FORCE_TEXT; if (DECL_NAME (parms)) { - current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (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)), @@ -2466,7 +2713,7 @@ dbxout_parms (parms) regparm_letter); } - dbxout_type (TREE_TYPE (parms), 0, 0); + dbxout_type (TREE_TYPE (parms), 0); dbxout_finish_symbol (parms); } else if (GET_CODE (DECL_RTL (parms)) == MEM @@ -2474,17 +2721,26 @@ dbxout_parms (parms) { /* Parm was passed via invisible reference, with the reference living on the stack. DECL_RTL looks like - (MEM (MEM (PLUS (REG ...) (CONST_INT ...)))). */ - const char *decl_name = (DECL_NAME (parms) + (MEM (MEM (PLUS (REG ...) (CONST_INT ...)))) or it + could look like (MEM (MEM (REG))). */ + const char *const decl_name = (DECL_NAME (parms) ? IDENTIFIER_POINTER (DECL_NAME (parms)) : "(anon)"); - current_sym_value - = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (parms), 0), 0), 1)); + if (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 0)) == REG) + current_sym_value = 0; + else + current_sym_value + = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (parms), 0), 0), 1)); current_sym_addr = 0; - + current_sym_code = N_PSYM; + FORCE_TEXT; fprintf (asmfile, "%s\"%s:v", ASM_STABS_OP, decl_name); - dbxout_type (TREE_TYPE (parms), 0, 0); + + current_sym_value + = DEBUGGER_ARG_OFFSET (current_sym_value, + XEXP (XEXP (DECL_RTL (parms), 0), 0)); + dbxout_type (TREE_TYPE (parms), 0); dbxout_finish_symbol (parms); } else if (GET_CODE (DECL_RTL (parms)) == MEM @@ -2515,7 +2771,7 @@ dbxout_parms (parms) && TYPE_MODE (TREE_TYPE (parms)) != GET_MODE (DECL_RTL (parms)) && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))) < UNITS_PER_WORD) { - current_sym_value += + current_sym_value += GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))) - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))); } @@ -2540,7 +2796,7 @@ dbxout_parms (parms) current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, XEXP (DECL_RTL (parms), 0)); - dbxout_type (TREE_TYPE (parms), 0, 0); + dbxout_type (TREE_TYPE (parms), 0); dbxout_finish_symbol (parms); } } @@ -2586,37 +2842,19 @@ dbxout_reg_parms (parms) /* Given a chain of ..._TYPE nodes (as come in a parameter list), output definitions of those names, in raw form */ -void +static void dbxout_args (args) tree args; { while (args) { putc (',', asmfile); - dbxout_type (TREE_VALUE (args), 0, 0); + dbxout_type (TREE_VALUE (args), 0); CHARS (1); args = TREE_CHAIN (args); } } -/* Given a chain of ..._TYPE nodes, - find those which have typedef names and output those names. - This is to ensure those types get output. */ - -void -dbxout_types (types) - register tree types; -{ - while (types) - { - if (TYPE_NAME (types) - && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL - && ! TREE_ASM_WRITTEN (TYPE_NAME (types))) - dbxout_symbol (TYPE_NAME (types), 1); - types = TREE_CHAIN (types); - } -} - /* Output everything about a symbol block (a BLOCK node that represents a scope level), including recursive output of contained blocks. @@ -2636,14 +2874,14 @@ dbxout_types (types) static void dbxout_block (block, depth, args) - register tree block; + tree block; int depth; tree args; { int blocknum = -1; #if DBX_BLOCKS_FUNCTION_RELATIVE - const char *begin_label; + const char *begin_label; if (current_function_func_begin_label != NULL_TREE) begin_label = IDENTIFIER_POINTER (current_function_func_begin_label); else @@ -2661,7 +2899,7 @@ dbxout_block (block, depth, args) did_output = 1; #else /* In dbx format, the syms of a block come before the N_LBRAC. - If nothing is output, we don't need the N_LBRAC, either. */ + If nothing is output, we don't need the N_LBRAC, either. */ did_output = 0; if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) did_output = dbxout_syms (BLOCK_VARS (block)); @@ -2703,7 +2941,7 @@ dbxout_block (block, depth, args) fprintf (asmfile, "%s%d,0,0,", ASM_STABN_OP, N_LBRAC); assemble_name (asmfile, buf); #if DBX_BLOCKS_FUNCTION_RELATIVE - fputc ('-', asmfile); + putc ('-', asmfile); assemble_name (asmfile, begin_label); #endif fprintf (asmfile, "\n"); @@ -2733,7 +2971,7 @@ dbxout_block (block, depth, args) fprintf (asmfile, "%s%d,0,0,", ASM_STABN_OP, N_RBRAC); assemble_name (asmfile, buf); #if DBX_BLOCKS_FUNCTION_RELATIVE - fputc ('-', asmfile); + putc ('-', asmfile); assemble_name (asmfile, begin_label); #endif fprintf (asmfile, "\n"); @@ -2748,8 +2986,9 @@ dbxout_block (block, depth, args) Usually this follows the function's code, but on some systems, it comes before. */ +#if defined (DBX_DEBUGGING_INFO) static void -dbxout_really_begin_function (decl) +dbxout_begin_function (decl) tree decl; { dbxout_symbol (decl, 0); @@ -2757,42 +2996,8 @@ dbxout_really_begin_function (decl) if (DECL_NAME (DECL_RESULT (decl)) != 0) dbxout_symbol (DECL_RESULT (decl), 1); } +#endif /* DBX_DEBUGGING_INFO */ -/* Called at beginning of output of function definition. */ - -void -dbxout_begin_function (decl) - tree decl ATTRIBUTE_UNUSED; -{ -#ifdef DBX_FUNCTION_FIRST - dbxout_really_begin_function (decl); -#endif -} - -/* Output dbx data for a function definition. - This includes a definition of the function name itself (a symbol), - definitions of the parameters (locating them in the parameter list) - and then output the block that makes up the function's body - (including all the auto variables of the function). */ - -void -dbxout_function (decl) - tree decl; -{ -#ifndef DBX_FUNCTION_FIRST - dbxout_really_begin_function (decl); -#endif - dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); -#ifdef DBX_OUTPUT_FUNCTION_END - DBX_OUTPUT_FUNCTION_END (asmfile, decl); -#endif -#if defined(ASM_OUTPUT_SECTION_NAME) - if (use_gnu_debug_info_extensions -#if defined(NO_DBX_FUNCTION_END) - && ! NO_DBX_FUNCTION_END -#endif - ) - dbxout_function_end (); -#endif -} #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ + +#include "gt-dbxout.h"