summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/dbxout.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/dbxout.c')
-rw-r--r--contrib/gcc/dbxout.c673
1 files changed, 436 insertions, 237 deletions
diff --git a/contrib/gcc/dbxout.c b/contrib/gcc/dbxout.c
index e322614..5e6f2a9 100644
--- a/contrib/gcc/dbxout.c
+++ b/contrib/gcc/dbxout.c
@@ -1,5 +1,5 @@
/* Output dbx-format symbol table information from GNU compiler.
- Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -67,11 +67,9 @@ Boston, MA 02111-1307, USA. */
For more on data type definitions, see `dbxout_type'. */
-/* Include these first, because they may define MIN and MAX. */
-#include <stdio.h>
-#include <errno.h>
-
#include "config.h"
+#include "system.h"
+
#include "tree.h"
#include "rtl.h"
#include "flags.h"
@@ -80,10 +78,8 @@ Boston, MA 02111-1307, USA. */
#include "reload.h"
#include "defaults.h"
#include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions. */
-
-#ifndef errno
-extern int errno;
-#endif
+#include "dbxout.h"
+#include "toplev.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
@@ -127,9 +123,27 @@ extern int errno;
#endif
/* Nonzero means if the type has methods, only output debugging
- information if methods are actually written to the asm file. */
+ 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
+#endif
+
+char *getpwd ();
-static int flag_minimal_debug = 1;
+/* 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;
/* Nonzero if we have actually used any of the GDB extensions
to the debugging format. The idea is that we use them for the
@@ -143,29 +157,24 @@ static int have_used_extensions = 0;
static int source_label_number = 1;
-char *getpwd ();
-
-/* 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)
-
#ifdef DEBUG_SYMS_TEXT
#define FORCE_TEXT text_section ();
#else
#define FORCE_TEXT
#endif
-#if defined (USG) || defined (NO_STAB_H)
-#include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
+/* If there is a system stabs.h, use it. Otherwise, use our own. */
+
+#ifndef HAVE_STABS_H
+#include "gstab.h"
#else
-#include <stab.h> /* On BSD, use the system's stab.h. */
+#include <stab.h>
/* This is a GNU extension we need to reference in this file. */
#ifndef N_CATCH
#define N_CATCH 0x54
#endif
-#endif /* not USG */
+#endif
#ifdef __GNU_STAB__
#define STAB_CODE_TYPE enum __stab_debug_code
@@ -205,15 +214,28 @@ static char *cwd;
enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
-/* Vector recording the status of describing C data types.
+/* 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.
- The vector element says whether we have yet output
- the definition of the type. TYPE_XREF says we have
- output it as a cross-reference only. */
+ That is its index in this vector. */
-enum typestatus *typevec;
+struct typeinfo *typevec;
/* Number of elements of space allocated in `typevec'. */
@@ -225,6 +247,29 @@ static int typevec_len;
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 */
+
/* In dbx output, we must assign symbol-blocks id numbers
in the order in which their beginnings are encountered.
We output debugging info that refers to the beginning and
@@ -275,121 +320,53 @@ static int current_sym_nchars;
void dbxout_types ();
void dbxout_args ();
void dbxout_symbol ();
-static void dbxout_type_name ();
-static void dbxout_type ();
-static void dbxout_typedefs ();
-static void dbxout_symbol_name ();
-static void dbxout_symbol_location ();
-static void dbxout_prepare_symbol ();
-static void dbxout_finish_symbol ();
-static void dbxout_continue ();
-static void print_int_cst_octal ();
-static void print_octal ();
+
+#if defined(ASM_OUTPUT_SECTION_NAME)
+static void dbxout_function_end PROTO((void));
+#endif
+static void dbxout_typedefs PROTO((tree));
+static void dbxout_type_index PROTO((tree));
+#if DBX_CONTIN_LENGTH > 0
+static void dbxout_continue PROTO((void));
+#endif
+static void dbxout_type_fields PROTO((tree));
+static void dbxout_type_method_1 PROTO((tree, char *));
+static void dbxout_type_methods PROTO((tree));
+static void dbxout_range_type PROTO((tree));
+static void dbxout_type PROTO((tree, int, int));
+static void print_int_cst_octal PROTO((tree));
+static void print_octal PROTO((unsigned HOST_WIDE_INT, int));
+static void dbxout_type_name PROTO((tree));
+static void dbxout_symbol_location PROTO((tree, tree, char *, rtx));
+static void dbxout_symbol_name PROTO((tree, char *, int));
+static void dbxout_prepare_symbol PROTO((tree));
+static void dbxout_finish_symbol PROTO((tree));
+static void dbxout_block PROTO((tree, int, tree));
+static void dbxout_really_begin_function PROTO((tree));
-#if 0 /* Not clear we will actually need this. */
-
-/* Return the absolutized filename for the given relative
- filename. Note that if that filename is already absolute, it may
- still be returned in a modified form because this routine also
- eliminates redundant slashes and single dots and eliminates double
- dots to get a shortest possible filename from the given input
- filename. The absolutization of relative filenames is made by
- assuming that the given filename is to be taken as relative to
- the first argument (cwd) or to the current directory if cwd is
- NULL. */
-
-static char *
-abspath (rel_filename)
- char *rel_filename;
+#if defined(ASM_OUTPUT_SECTION_NAME)
+static void
+dbxout_function_end ()
{
- /* Setup the current working directory as needed. */
- char *abs_buffer
- = (char *) alloca (strlen (cwd) + strlen (rel_filename) + 1);
- char *endp = abs_buffer;
- char *outp, *inp;
- char *value;
-
- /* Copy the filename (possibly preceded by the current working
- directory name) into the absolutization buffer. */
-
- {
- char *src_p;
-
- if (rel_filename[0] != '/')
- {
- src_p = cwd;
- while (*endp++ = *src_p++)
- continue;
- *(endp-1) = '/'; /* overwrite null */
- }
- src_p = rel_filename;
- while (*endp++ = *src_p++)
- continue;
- if (endp[-1] == '/')
- *endp = '\0';
-
- /* Now make a copy of abs_buffer into abs_buffer, shortening the
- filename (by taking out slashes and dots) as we go. */
-
- outp = inp = abs_buffer;
- *outp++ = *inp++; /* copy first slash */
- for (;;)
- {
- if (!inp[0])
- break;
- else if (inp[0] == '/' && outp[-1] == '/')
- {
- inp++;
- continue;
- }
- else if (inp[0] == '.' && outp[-1] == '/')
- {
- if (!inp[1])
- break;
- else if (inp[1] == '/')
- {
- inp += 2;
- continue;
- }
- else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
- {
- inp += (inp[2] == '/') ? 3 : 2;
- outp -= 2;
- while (outp >= abs_buffer && *outp != '/')
- outp--;
- if (outp < abs_buffer)
- {
- /* Catch cases like /.. where we try to backup to a
- point above the absolute root of the logical file
- system. */
-
- fprintf (stderr, "%s: invalid file name: %s\n",
- pname, rel_filename);
- exit (1);
- }
- *++outp = '\0';
- continue;
- }
- }
- *outp++ = *inp++;
- }
-
- /* On exit, make sure that there is a trailing null, and make sure that
- the last character of the returned string is *not* a slash. */
-
- *outp = '\0';
- if (outp[-1] == '/')
- *--outp = '\0';
-
- /* Make a copy (in the heap) of the stuff left in the absolutization
- buffer and return a pointer to the copy. */
-
- value = (char *) oballoc (strlen (abs_buffer) + 1);
- strcpy (value, abs_buffer);
- return value;
+ static int scope_labelno = 0;
+ char lscope_label_name[100];
+ /* Convert Ltext into the appropriate format for local labels in case
+ 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);
+ scope_labelno++;
+
+ /* By convention, GCC will mark the end of a function with an N_FUN
+ symbol and an empty string. */
+ fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN);
+ assemble_name (asmfile, lscope_label_name);
+ fputc ('-', asmfile);
+ assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
+ fprintf (asmfile, "\n");
}
-#endif /* 0 */
-
+#endif /* ! NO_DBX_FUNCTION_END */
+
/* At the beginning of compilation, start writing the symbol table.
Initialize `typevec' and output the standard data types of C. */
@@ -404,7 +381,7 @@ dbxout_init (asm_file, input_file_name, syms)
asmfile = asm_file;
typevec_len = 100;
- typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);
+ typevec = (struct typeinfo *) xmalloc (typevec_len * sizeof typevec[0]);
bzero ((char *) typevec, typevec_len * sizeof typevec[0]);
/* Convert Ltext into the appropriate format for local labels in case
@@ -464,6 +441,14 @@ dbxout_init (asm_file, input_file_name, syms)
next_type_number = 1;
next_block_number = 2;
+#ifdef DBX_USE_BINCL
+ current_file = (struct dbx_file *) xmalloc (sizeof *current_file);
+ current_file->next = NULL;
+ current_file->file_number = 0;
+ current_file->next_type_number = 1;
+ next_file_number = 1;
+#endif
+
/* Make sure that types `int' and `char' have numbers 1 and 2.
Definitions of other integer types will refer to those numbers.
(Actually it should no longer matter what their numbers are.
@@ -499,12 +484,47 @@ dbxout_typedefs (syms)
tree type = TREE_TYPE (syms);
if (TYPE_NAME (type)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+ && TYPE_SIZE (type) != NULL_TREE
&& ! TREE_ASM_WRITTEN (TYPE_NAME (type)))
dbxout_symbol (TYPE_NAME (type), 0);
}
}
}
+/* Change to reading from a new source file. Generate a N_BINCL stab. */
+
+void
+dbxout_start_new_source_file (filename)
+ char *filename;
+{
+#ifdef DBX_USE_BINCL
+ struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n);
+
+ n->next = current_file;
+ n->file_number = next_file_number++;
+ n->next_type_number = 1;
+ current_file = n;
+ fprintf (asmfile, "%s ", ASM_STABS_OP);
+ output_quoted_string (asmfile, filename);
+ fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
+#endif
+}
+
+/* Revert to reading a previous source file. Generate a N_EINCL stab. */
+
+void
+dbxout_resume_previous_source_file ()
+{
+#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;
+#endif
+}
+
/* Output debugging info to FILE to switch to sourcefile FILENAME. */
void
@@ -556,7 +576,7 @@ dbxout_source_line (file, filename, lineno)
/* 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. */
+ to do nothing. */
void
dbxout_finish (file, filename)
@@ -568,6 +588,23 @@ dbxout_finish (file, filename)
#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */
}
+/* Output the index of a type. */
+
+static void
+dbxout_type_index (type)
+ tree type;
+{
+#ifndef DBX_USE_BINCL
+ fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
+ CHARS (3);
+#else
+ struct typeinfo *t = &typevec[TYPE_SYMTAB_ADDRESS (type)];
+ fprintf (asmfile, "(%d,%d)", t->file_number, t->type_number);
+ CHARS (7);
+#endif
+}
+
+#if DBX_CONTIN_LENGTH > 0
/* Continue a symbol-description that gets too big.
End one symbol table entry with a double-backslash
and start a new one, eventually producing something like
@@ -586,6 +623,7 @@ dbxout_continue ()
fprintf (asmfile, "%s \"", ASM_STABS_OP);
current_sym_nchars = 0;
}
+#endif /* DBX_CONTIN_LENGTH > 0 */
/* Subroutine of `dbxout_type'. Output the type fields of TYPE.
This must be a separate function because anonymous unions require
@@ -609,12 +647,16 @@ dbxout_type_fields (type)
|| TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST))
continue;
/* Omit here the nameless fields that are used to skip bits. */
+ else if (DECL_IGNORED_P (tem))
+ continue;
else if (TREE_CODE (tem) != CONST_DECL)
{
/* Continue the line if necessary,
but not before the first field. */
if (tem != TYPE_FIELDS (type))
- CONTIN;
+ {
+ CONTIN;
+ }
if (use_gnu_debug_info_extensions
&& flag_minimal_debug
@@ -628,8 +670,10 @@ dbxout_type_fields (type)
dbxout_type (DECL_FCONTEXT (tem), 0, 0);
fprintf (asmfile, ":");
dbxout_type (TREE_TYPE (tem), 0, 0);
- fprintf (asmfile, ",%d;",
+ fputc (',', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+ fputc (';', asmfile);
continue;
}
@@ -678,9 +722,13 @@ dbxout_type_fields (type)
}
else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
{
- fprintf (asmfile, ",%d,%d;",
- TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)),
+ fputc (',', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+ fputc (',', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (DECL_SIZE (tem)));
+ fputc (';', asmfile);
}
CHARS (23);
}
@@ -725,8 +773,9 @@ dbxout_type_method_1 (decl, debug_name)
- (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
if (DECL_VINDEX (decl))
{
- fprintf (asmfile, "%d;",
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (DECL_VINDEX (decl)));
+ fputc (';', asmfile);
dbxout_type (DECL_CONTEXT (decl), 0, 0);
fprintf (asmfile, ";");
CHARS (8);
@@ -765,13 +814,7 @@ dbxout_type_methods (type)
{
static int warned;
if (!warned)
- {
warned = 1;
-#ifdef HAVE_TEMPLATES
- if (warn_template_debugging)
- warning ("dbx info for template class methods not yet supported");
-#endif
- }
return;
}
}
@@ -781,7 +824,7 @@ dbxout_type_methods (type)
sprintf(formatted_type_identifier_length, "%d", type_identifier_length);
- if (TREE_CODE (methods) == FUNCTION_DECL)
+ if (TREE_CODE (methods) != TREE_VEC)
fndecl = methods;
else if (TREE_VEC_ELT (methods, 0) != NULL_TREE)
fndecl = TREE_VEC_ELT (methods, 0);
@@ -805,7 +848,7 @@ dbxout_type_methods (type)
/* This is the "mangled" name of the method.
It encodes the argument types. */
char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
- int destructor = 0;
+ int show_arg_types = 0;
CONTIN;
@@ -816,10 +859,23 @@ dbxout_type_methods (type)
if (flag_minimal_debug)
{
+ 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. */
- if (!strncmp (IDENTIFIER_POINTER (name), debug_name,
- IDENTIFIER_LENGTH (name)))
+ else if (!strncmp (IDENTIFIER_POINTER (name), debug_name,
+ IDENTIFIER_LENGTH (name)))
{
debug_name += IDENTIFIER_LENGTH (name);
if (debug_name[0] == '_' && debug_name[1] == '_')
@@ -829,7 +885,7 @@ dbxout_type_methods (type)
/* Get past const and volatile qualifiers. */
while (*method_name == 'C' || *method_name == 'V')
method_name++;
- /* Skip digits for length of type_encoding. */
+ /* Skip digits for length of type_encoding. */
while (*method_name == *length_ptr && *length_ptr)
length_ptr++, method_name++;
if (! strncmp (method_name,
@@ -846,7 +902,7 @@ dbxout_type_methods (type)
char *length_ptr = formatted_type_identifier_length;
while (*ctor_name == 'C' || *ctor_name == 'V')
ctor_name++;
- /* Skip digits for length of type_encoding. */
+ /* 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,
@@ -855,7 +911,7 @@ dbxout_type_methods (type)
}
/* The other alternative is a destructor. */
else
- destructor = 1;
+ show_arg_types = 1;
/* Output the operation name just once, for the first method
that we output. */
@@ -867,7 +923,7 @@ dbxout_type_methods (type)
}
}
- dbxout_type (TREE_TYPE (fndecl), 0, destructor);
+ dbxout_type (TREE_TYPE (fndecl), 0, show_arg_types);
dbxout_type_method_1 (fndecl, debug_name);
}
@@ -881,7 +937,7 @@ dbxout_type_methods (type)
/* Emit a "range" type specification, which has the form:
"r<index type>;<lower bound>;<upper bound>;".
- TYPE is an INTEGER_TYPE. */
+ TYPE is an INTEGER_TYPE. */
static void
dbxout_range_type (type)
@@ -894,18 +950,39 @@ dbxout_range_type (type)
dbxout_type (type, 0, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */
else
{
- /* This used to say `r1' and we used to take care
- to make sure that `int' was type number 1. */
- fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (integer_type_node));
+ /* Traditionally, we made sure 'int' was type 1, and builtin types
+ were defined to be sub-ranges of int. Unfortunately, this
+ does not allow us to distinguish true sub-ranges from integer
+ types. So, instead we define integer (non-sub-range) types as
+ sub-ranges of themselves. This matters for Chill. If this isn't
+ a subrange type, then we want to define it in terms of itself.
+ However, in C, this may be an anonymous integer type, and we don't
+ want to emit debug info referring to it. Just calling
+ dbxout_type_index won't work anyways, because the type hasn't been
+ defined yet. We make this work for both cases by checked to see
+ whether this is a defined type, referring to it if it is, and using
+ 'int' otherwise. */
+ if (TYPE_SYMTAB_ADDRESS (type) != 0)
+ dbxout_type_index (type);
+ else
+ dbxout_type_index (integer_type_node);
}
if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
- fprintf (asmfile, ";%d",
- TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)));
+ {
+ fputc (';', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)));
+ }
else
fprintf (asmfile, ";0");
- if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
- fprintf (asmfile, ";%d;",
- TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
+ if (TYPE_MAX_VALUE (type)
+ && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
+ {
+ fputc (';', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
+ fputc (';', asmfile);
+ }
else
fprintf (asmfile, ";-1;");
}
@@ -939,7 +1016,18 @@ dbxout_type (type, full, show_arg_types)
type = integer_type_node;
else
{
- type = TYPE_MAIN_VARIANT (type);
+ /* 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)))
@@ -955,18 +1043,24 @@ dbxout_type (type, full, show_arg_types)
if (next_type_number == typevec_len)
{
- typevec =
- (enum typestatus *) xrealloc (typevec,
- typevec_len * 2 * sizeof typevec[0]);
+ typevec
+ = (struct typeinfo *) xrealloc (typevec,
+ typevec_len * 2 * sizeof typevec[0]);
bzero ((char *) (typevec + typevec_len),
typevec_len * sizeof typevec[0]);
typevec_len *= 2;
}
+
+#ifdef DBX_USE_BINCL
+ typevec[TYPE_SYMTAB_ADDRESS (type)].file_number
+ = current_file->file_number;
+ typevec[TYPE_SYMTAB_ADDRESS (type)].type_number
+ = current_file->next_type_number++;
+#endif
}
/* Output the number of this type, to refer to it. */
- fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
- CHARS (3);
+ dbxout_type_index (type);
#ifdef DBX_TYPE_DEFINED
if (DBX_TYPE_DEFINED (type))
@@ -976,7 +1070,7 @@ dbxout_type (type, full, show_arg_types)
/* If this type's definition has been output or is now being output,
that is all. */
- switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
+ switch (typevec[TYPE_SYMTAB_ADDRESS (type)].status)
{
case TYPE_UNSEEN:
break;
@@ -1014,7 +1108,7 @@ dbxout_type (type, full, show_arg_types)
/* No way in DBX fmt to describe a variable size. */
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
- typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+ typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
return;
}
#endif
@@ -1027,7 +1121,14 @@ dbxout_type (type, full, show_arg_types)
/* Mark it as defined, so that if it is self-referent
we will not get into an infinite recursion of definitions. */
- typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
+ 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);
+ return;
+ }
switch (TREE_CODE (type))
{
@@ -1038,25 +1139,33 @@ dbxout_type (type, full, show_arg_types)
without saying what it is. The debugger will make it
a void type when the reference is seen, and nothing will
ever override that default. */
- fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
- CHARS (3);
+ dbxout_type_index (type);
break;
case INTEGER_TYPE:
if (type == char_type_node && ! TREE_UNSIGNED (type))
- /* Output the type `char' as a subrange of itself!
- I don't understand this definition, just copied it
- from the output of pcc.
- This used to use `r2' explicitly and we used to
- take care to make sure that `char' was type number 2. */
- fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type));
+ {
+ /* Output the type `char' as a subrange of itself!
+ I don't understand this definition, just copied it
+ from the output of pcc.
+ This used to use `r2' explicitly and we used to
+ take care to make sure that `char' was type number 2. */
+ fprintf (asmfile, "r");
+ dbxout_type_index (type);
+ fprintf (asmfile, ";0;127;");
+ }
+ /* This used to check if the type's precision was more than
+ HOST_BITS_PER_WIDE_INT. That is wrong since gdb uses a
+ long (it has no concept of HOST_BITS_PER_WIDE_INT). */
else if (use_gnu_debug_info_extensions
&& (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
- || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT))
+ || TYPE_PRECISION (type) >= HOST_BITS_PER_LONG))
{
/* This used to say `r1' and we used to take care
to make sure that `int' was type number 1. */
- fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node));
+ fprintf (asmfile, "r");
+ dbxout_type_index (integer_type_node);
+ fprintf (asmfile, ";");
print_int_cst_octal (TYPE_MIN_VALUE (type));
fprintf (asmfile, ";");
print_int_cst_octal (TYPE_MAX_VALUE (type));
@@ -1064,33 +1173,47 @@ dbxout_type (type, full, show_arg_types)
}
else /* Output other integer types as subranges of `int'. */
dbxout_range_type (type);
- CHARS (25);
+ 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%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node),
- int_size_in_bytes (type));
- CHARS (16);
+ fprintf (asmfile, "r");
+ dbxout_type_index (integer_type_node);
+ fputc (';', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type));
+ fputs (";0;", asmfile);
+ CHARS (13);
break;
case CHAR_TYPE:
if (use_gnu_debug_info_extensions)
- fprintf (asmfile, "@s%d;-20;",
- BITS_PER_UNIT * int_size_in_bytes (type));
+ {
+ fputs ("@s", asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ BITS_PER_UNIT * int_size_in_bytes (type));
+ fputs (";-20;", asmfile);
+ }
else
- /* Output the type `char' as a subrange of itself.
- That is what pcc seems to do. */
- fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node),
- TREE_UNSIGNED (type) ? 255 : 127);
+ {
+ /* Output the type `char' as a subrange of itself.
+ That is what pcc seems to do. */
+ fprintf (asmfile, "r");
+ dbxout_type_index (char_type_node);
+ fprintf (asmfile, ";0;%d;", TREE_UNSIGNED (type) ? 255 : 127);
+ }
CHARS (9);
break;
case BOOLEAN_TYPE:
if (use_gnu_debug_info_extensions)
- fprintf (asmfile, "@s%d;-16;",
- BITS_PER_UNIT * int_size_in_bytes (type));
+ {
+ fputs ("@s", asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ BITS_PER_UNIT * int_size_in_bytes (type));
+ fputs (";-16;", asmfile);
+ }
else /* Define as enumeral type (False, True) */
fprintf (asmfile, "eFalse:0,True:1,;");
CHARS (17);
@@ -1107,16 +1230,20 @@ dbxout_type (type, full, show_arg_types)
if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
{
- fprintf (asmfile, "r%d;%d;0;",
- TYPE_SYMTAB_ADDRESS (type),
+ fprintf (asmfile, "r");
+ dbxout_type_index (type);
+ fputc (';', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
int_size_in_bytes (TREE_TYPE (type)));
- CHARS (15); /* The number is probably incorrect here. */
+ fputs (";0;", asmfile);
+ CHARS (12); /* The number is probably incorrect here. */
}
else
{
/* Output a complex integer type as a structure,
pending some other way to do it. */
- fprintf (asmfile, "s%d", int_size_in_bytes (type));
+ fputc ('s', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type));
fprintf (asmfile, "real:");
CHARS (10);
@@ -1138,10 +1265,12 @@ dbxout_type (type, full, show_arg_types)
if (use_gnu_debug_info_extensions)
{
have_used_extensions = 1;
- fprintf (asmfile, "@s%d;",
+ fputs ("@s", asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
BITS_PER_UNIT * int_size_in_bytes (type));
+ fputc (';', asmfile);
/* Check if a bitstring type, which in Chill is
- different from a [power]set. */
+ different from a [power]set. */
if (TYPE_STRING_FLAG (type))
fprintf (asmfile, "@S;");
}
@@ -1151,12 +1280,26 @@ dbxout_type (type, full, show_arg_types)
break;
case ARRAY_TYPE:
+ /* Make arrays of packed bits look like bitstrings for chill. */
+ if (TYPE_PACKED (type) && 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));
+ fputc (';', asmfile);
+ fprintf (asmfile, "@S;");
+ putc ('S', asmfile);
+ CHARS (1);
+ dbxout_type (TYPE_DOMAIN (type), 0, 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.
ar1;0;N;M for a C array of type M and size N+1. */
/* Check if a character string type, which in Chill is
- different from an array of characters. */
+ different from an array of characters. */
if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions)
{
have_used_extensions = 1;
@@ -1164,14 +1307,17 @@ dbxout_type (type, full, show_arg_types)
}
tem = TYPE_DOMAIN (type);
if (tem == NULL)
- fprintf (asmfile, "ar%d;0;-1;",
- TYPE_SYMTAB_ADDRESS (integer_type_node));
+ {
+ fprintf (asmfile, "ar");
+ dbxout_type_index (integer_type_node);
+ fprintf (asmfile, ";0;-1;");
+ }
else
{
fprintf (asmfile, "a");
dbxout_range_type (tem);
}
- CHARS (17);
+ CHARS (14);
dbxout_type (TREE_TYPE (type), 0, 0);
break;
@@ -1181,7 +1327,9 @@ dbxout_type (type, full, show_arg_types)
{
int i, n_baseclasses = 0;
- if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0)
+ if (TYPE_BINFO (type) != 0
+ && TREE_CODE (TYPE_BINFO (type)) == TREE_VEC
+ && TYPE_BINFO_BASETYPES (type) != 0)
n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
/* Output a structure type. We must use the same test here as we
@@ -1215,12 +1363,13 @@ dbxout_type (type, full, show_arg_types)
else
fprintf (asmfile, "$$%d", anonymous_type_number++);
fprintf (asmfile, ":");
- typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+ typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
break;
}
/* Identify record or union, and print its size. */
- fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
+ fputc (((TREE_CODE (type) == RECORD_TYPE) ? 's' : 'u'), asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
int_size_in_bytes (type));
if (use_gnu_debug_info_extensions)
@@ -1244,8 +1393,9 @@ dbxout_type (type, full, show_arg_types)
putc (TREE_VIA_PUBLIC (child) ? '2'
: '0',
asmfile);
- fprintf (asmfile, "%d,",
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
+ fputc (',', asmfile);
CHARS (15);
dbxout_type (BINFO_TYPE (child), 0, 0);
putc (';', asmfile);
@@ -1257,9 +1407,13 @@ dbxout_type (type, full, show_arg_types)
dbxout_type_name (BINFO_TYPE (child));
putc (':', asmfile);
dbxout_type (BINFO_TYPE (child), full, 0);
- fprintf (asmfile, ",%d,%d;",
- TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT,
+ fputc (',', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
+ fputc (',', asmfile);
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT);
+ fputc (';', asmfile);
CHARS (20);
}
}
@@ -1312,7 +1466,7 @@ dbxout_type (type, full, show_arg_types)
fprintf (asmfile, "xe");
CHARS (3);
dbxout_type_name (type);
- typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+ typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
fprintf (asmfile, ":");
return;
}
@@ -1328,18 +1482,20 @@ dbxout_type (type, full, show_arg_types)
{
fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
- fprintf (asmfile, "%lu",
- (unsigned long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_UNSIGNED,
+ TREE_INT_CST_LOW (TREE_VALUE (tem)));
else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
&& TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
- fprintf (asmfile, "%ld",
- (long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (TREE_VALUE (tem)));
else
print_int_cst_octal (TREE_VALUE (tem));
fprintf (asmfile, ",");
CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
if (TREE_CHAIN (tem) != 0)
- CONTIN;
+ {
+ CONTIN;
+ }
}
putc (';', asmfile);
CHARS (1);
@@ -1363,6 +1519,7 @@ dbxout_type (type, full, 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);
@@ -1467,7 +1624,7 @@ print_int_cst_octal (c)
<< (HOST_BITS_PER_WIDE_INT / 3 * 3))
- 1);
- fprintf (asmfile, "%o%01o", beg, middle);
+ fprintf (asmfile, "%o%01o", (int)beg, (int)middle);
print_octal (end, HOST_BITS_PER_WIDE_INT / 3);
}
}
@@ -1480,7 +1637,7 @@ print_octal (value, digits)
int i;
for (i = digits - 1; i >= 0; i--)
- fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7));
+ fprintf (asmfile, "%01o", (int)((value >> (3 * i)) & 7));
}
/* Output the name of type TYPE, with no punctuation.
@@ -1593,7 +1750,7 @@ dbxout_symbol (decl, local)
/* If this typedef name was defined by outputting the type,
don't duplicate it. */
- if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
+ if (typevec[TYPE_SYMTAB_ADDRESS (type)].status == TYPE_DEFINED
&& TYPE_NAME (TREE_TYPE (decl)) == decl)
return;
#endif
@@ -1625,10 +1782,7 @@ 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. */
- && (!strcmp (lang_identify (), "cplusplus")
- /* The following line maybe unnecessary;
- in 2.6, try removing it. */
- || DECL_SOURCE_LINE (decl) == 0))
+ && DECL_ARTIFICIAL (decl))
{
tree name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
@@ -1653,7 +1807,10 @@ dbxout_symbol (decl, local)
if ((TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
- && TYPE_NAME (type) == decl)
+ && TYPE_NAME (type) == decl
+ /* Distinguish the implicit typedefs of C++
+ from explicit ones that might be found in C. */
+ && DECL_ARTIFICIAL (decl))
{
if (use_gnu_debug_info_extensions && have_used_extensions)
{
@@ -1760,8 +1917,10 @@ dbxout_symbol (decl, local)
#ifdef DBX_OUTPUT_CONSTANT_SYMBOL
DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);
#else
- fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n",
- ASM_STABS_OP, name, ival, N_LSYM);
+ fprintf (asmfile, "%s \"%s:c=i", ASM_STABS_OP, name);
+
+ fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, ival);
+ fprintf (asmfile, "\",0x%x,0,0,0\n", N_LSYM);
#endif
return;
}
@@ -1781,6 +1940,10 @@ dbxout_symbol (decl, local)
#endif
dbxout_symbol_location (decl, type, 0, DECL_RTL (decl));
+ break;
+
+ default:
+ break;
}
}
@@ -1801,7 +1964,7 @@ 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 it's rtl
+ 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)
@@ -1887,7 +2050,12 @@ dbxout_symbol_location (decl, type, suffix, home)
else if (GET_CODE (home) == MEM
&& (GET_CODE (XEXP (home, 0)) == MEM
|| (GET_CODE (XEXP (home, 0)) == REG
- && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM)))
+ && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
+ && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
+#endif
+ )))
/* If the value is indirect by memory or by a register
that isn't the frame pointer
then it means the object is variable-sized and address through
@@ -2129,7 +2297,21 @@ dbxout_parms (parms)
DBX_MEMPARM_STABS_LETTER);
}
- dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
+ /* It is quite tempting to use:
+
+ dbxout_type (TREE_TYPE (parms), 0, 0);
+
+ as the next statement, rather than using DECL_ARG_TYPE(), so
+ that gcc reports the actual type of the parameter, rather
+ than the promoted type. This certainly makes GDB's life
+ easier, at least for some ports. The change is a bad idea
+ however, since GDB expects to be able access the type without
+ performing any conversions. So for example, if we were
+ 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);
current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr);
dbxout_finish_symbol (parms);
}
@@ -2259,6 +2441,15 @@ dbxout_parms (parms)
current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
current_sym_addr = 0;
+ /* Make a big endian correction if the mode of the type of the
+ parameter is not the same as the mode of the rtl. */
+ if (BYTES_BIG_ENDIAN
+ && TYPE_MODE (TREE_TYPE (parms)) != GET_MODE (DECL_RTL (parms))
+ && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))) < UNITS_PER_WORD)
+ {
+ current_sym_value += UNITS_PER_WORD - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms)));
+ }
+
FORCE_TEXT;
if (DECL_NAME (parms))
{
@@ -2514,5 +2705,13 @@ dbxout_function (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 */
+#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
OpenPOWER on IntegriCloud