X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdbxout.c;h=2db1f3a9fe2c89855d5919f29df4a84c88a9150f;hb=e082165d0519c45cd586747a5a567e059982829d;hp=2c147f64109654233f3a8227e357ae70661187fe;hpb=ec6cb94af9fcfa7d281b5234ad5e1c31000c10f3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 2c147f64109..2db1f3a9fe2 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 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. @@ -77,12 +77,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,18 +128,11 @@ 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. */ - -#define MINIMAL_DEBUG 1 - -#ifdef NO_DOLLAR_IN_LABEL -#ifdef NO_DOT_IN_LABEL -#undef MINIMAL_DEBUG -#define MINIMAL_DEBUG 0 -#endif +/* 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 /* Typical USG systems don't have stab.h, and they also have @@ -144,8 +140,6 @@ Boston, MA 02111-1307, USA. */ #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) -static int flag_minimal_debug = MINIMAL_DEBUG; - /* Nonzero if we have actually used any of the GDB extensions to the debugging format. The idea is that we use them for the first time only if there's a strong reason, but once we have done that, @@ -156,7 +150,9 @@ 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 (); @@ -164,26 +160,9 @@ static int source_label_number = 1; #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. */ @@ -310,30 +289,99 @@ 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_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 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)); + +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, /* end_prologue */ + debug_nothing_void, /* 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) +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, /* 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 () { @@ -350,24 +398,23 @@ dbxout_function_end () symbol and an empty string. */ 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 /* ! 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 = getdecls (); - asmfile = asm_file; + asmfile = asm_out_file; typevec_len = 100; typevec = (struct typeinfo *) xcalloc (typevec_len, sizeof typevec[0]); @@ -384,11 +431,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 +439,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 +456,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); #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; @@ -480,8 +527,9 @@ 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 @@ -499,8 +547,9 @@ 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; @@ -512,25 +561,28 @@ dbxout_resume_previous_source_file () #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. */ @@ -543,35 +595,92 @@ dbxout_source_file (file, 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; +{ + ASM_OUTPUT_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; +{ + ASM_OUTPUT_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 */ } @@ -587,7 +696,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 +754,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 +762,7 @@ dbxout_type_fields (type) else { fprintf (asmfile, ":"); - CHARS (2); + CHARS (1); } if (use_gnu_debug_info_extensions @@ -689,32 +779,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 +851,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 +865,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 +900,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 +911,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,85 +924,36 @@ 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); } @@ -934,9 +975,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 +1001,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,18 +1035,15 @@ 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) @@ -1011,24 +1056,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. */ @@ -1076,7 +1121,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 +1146,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 +1163,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,14 +1209,16 @@ 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) + && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) dbxout_range_type (type); else @@ -1163,7 +1228,11 @@ dbxout_type (type, full, show_arg_types) 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 @@ -1183,19 +1252,24 @@ dbxout_type (type, full, show_arg_types) && 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 @@ -1203,56 +1277,64 @@ dbxout_type (type, full, show_arg_types) 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: @@ -1261,33 +1343,33 @@ dbxout_type (type, full, show_arg_types) if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) { fprintf (asmfile, "r"); + CHARS (1); dbxout_type_index (type); - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - 2 * int_size_in_bytes (TREE_TYPE (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 +1378,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 +1402,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 +1420,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 +1460,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 +1470,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 +1481,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 +1515,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 +1537,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 +1565,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 +1575,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 +1584,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 +1604,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 +1616,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 +1649,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 +1658,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 +1679,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 +1694,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 +1733,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 +1752,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,15 +1766,36 @@ 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. Such names can be set up either by typedef declarations or by struct, enum and union tags. */ static void dbxout_type_name (type) - register tree type; + tree type; { tree t; if (TYPE_NAME (type) == 0) @@ -1761,9 +1878,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 +1934,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,7 +1951,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); } @@ -1861,13 +1982,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 +2012,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 +2030,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 +2047,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 +2091,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)); @@ -2006,29 +2127,24 @@ dbxout_symbol_location (decl, type, suffix, home) 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 +2179,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 +2188,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 +2238,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 +2293,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 +2336,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 +2372,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 @@ -2306,7 +2448,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) { @@ -2350,7 +2492,7 @@ 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 +2503,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 +2555,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 +2595,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 +2609,33 @@ 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 + && GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) + { + /* Parm was passed via invisible reference, with the reference + living on the stack. DECL_RTL looks like + (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)"); + 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; + + FORCE_TEXT; + fprintf (asmfile, "%s\"%s:v", ASM_STABS_OP, decl_name); + + 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 @@ -2477,22 +2646,14 @@ dbxout_parms (parms) && ! CONSTANT_P (XEXP (DECL_RTL (parms), 0))) { /* Parm was passed in registers but lives on the stack. */ - int aux_sym_value = 0; current_sym_code = N_PSYM; /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), in which case we want the value of that CONST_INT, - or (MEM (REG ...)) or (MEM (MEM ...)), + or (MEM (REG ...)), in which case we use a value of zero. */ if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG) current_sym_value = 0; - else if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) - { - /* Remember the location on the stack the parm is moved to */ - aux_sym_value - = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (parms), 0), 0), 1)); - current_sym_value = 0; - } else current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); @@ -2530,19 +2691,8 @@ 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); - if (aux_sym_value != 0) - { - /* Generate an entry for the stack location */ - - fprintf (asmfile, "%s\"%s:", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (parms))); - current_sym_value = aux_sym_value; - current_sym_code = N_LSYM; - dbxout_type (build_reference_type (TREE_TYPE (parms)), 0, 0); - dbxout_finish_symbol (parms); - } } } } @@ -2587,37 +2737,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. @@ -2637,12 +2769,11 @@ dbxout_types (types) static void dbxout_block (block, depth, args) - register tree block; + tree block; int depth; tree args; { int blocknum = -1; - int ignored; #if DBX_BLOCKS_FUNCTION_RELATIVE const char *begin_label; @@ -2657,12 +2788,16 @@ dbxout_block (block, depth, args) /* Ignore blocks never expanded or otherwise marked as real. */ if (TREE_USED (block) && TREE_ASM_WRITTEN (block)) { -#ifndef DBX_LBRAC_FIRST + int did_output; + +#ifdef DBX_LBRAC_FIRST + 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. */ - ignored = 1; + If nothing is output, we don't need the N_LBRAC, either. */ + did_output = 0; if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) - ignored = dbxout_syms (BLOCK_VARS (block)); + did_output = dbxout_syms (BLOCK_VARS (block)); if (args) dbxout_reg_parms (args); #endif @@ -2671,7 +2806,7 @@ dbxout_block (block, depth, args) the block. Use the block's tree-walk order to generate the assembler symbols LBBn and LBEn that final will define around the code in this block. */ - if (depth > 0 && !ignored) + if (depth > 0 && did_output) { char buf[20]; blocknum = BLOCK_NUMBER (block); @@ -2701,7 +2836,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"); @@ -2721,7 +2856,7 @@ dbxout_block (block, depth, args) dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); /* Refer to the marker for the end of the block. */ - if (depth > 0 && !ignored) + if (depth > 0 && did_output) { char buf[20]; ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum); @@ -2731,7 +2866,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"); @@ -2746,8 +2881,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); @@ -2755,42 +2891,6 @@ 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 */