/* Output dbx-format symbol table information from GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GCC.
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
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* Output dbx-format symbol table data.
static void dbxout_class_name_qualifiers (tree);
static int dbxout_symbol_location (tree, tree, const char *, rtx);
static void dbxout_symbol_name (tree, const char *, int);
-static void dbxout_block (tree, int, tree);
static void dbxout_global_decl (tree);
static void dbxout_type_decl (tree, int);
static void dbxout_handle_pch (unsigned);
dbxout_end_source_file,
dbxout_begin_block,
dbxout_end_block,
- debug_true_tree, /* ignore_block */
+ debug_true_const_tree, /* ignore_block */
dbxout_source_line, /* source_line */
dbxout_begin_prologue, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
dbxout_end_source_file,
xcoffout_begin_block,
xcoffout_end_block,
- debug_true_tree, /* ignore_block */
+ debug_true_const_tree, /* ignore_block */
xcoffout_source_line,
xcoffout_begin_prologue, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
char ltext_label_name[100];
bool used_ltext_label_name = false;
tree syms = lang_hooks.decls.getdecls ();
+ const char *mapped_name;
typevec_len = 100;
typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
cwd = "/";
else if (!IS_DIR_SEPARATOR (cwd[strlen (cwd) - 1]))
cwd = concat (cwd, "/", NULL);
+ cwd = remap_debug_filename (cwd);
}
#ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY
DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asm_out_file, cwd);
#endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */
}
+ mapped_name = remap_debug_filename (input_file_name);
#ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME
- DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, input_file_name);
+ DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, mapped_name);
#else
- dbxout_begin_simple_stabs_desc (input_file_name, N_SO, get_lang_number ());
+ dbxout_begin_simple_stabs_desc (mapped_name, N_SO, get_lang_number ());
dbxout_stab_value_label (ltext_label_name);
used_ltext_label_name = true;
#endif
n->prev = NULL;
current_file->prev = n;
n->bincl_status = BINCL_PENDING;
- n->pending_bincl_name = filename;
+ n->pending_bincl_name = remap_debug_filename (filename);
pending_bincls = 1;
current_file = n;
#endif
}
#if defined (DBX_DEBUGGING_INFO)
+
+static void dbxout_block (tree, int, tree);
+
/* Output debugging info to FILE to switch to sourcefile FILENAME. */
static void
if (current_function_decl == NULL_TREE)
switch_to_section (text_section);
- dbxout_begin_simple_stabs (filename, N_SOL);
+ dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
dbxout_stab_value_internal_label ("Ltext", &source_label_number);
lastfile = filename;
}
break;
case REAL_TYPE:
+ case FIXED_POINT_TYPE:
/* This used to say `r1' and we used to take care
to make sure that `int' was type number 1. */
stabstr_C ('r');
another type's definition; instead, output an xref
and let the definition come when the name is defined. */
stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
- if (TYPE_NAME (type) != 0)
+ if (TYPE_NAME (type) != 0
+ /* The C frontend creates for anonymous variable length
+ records/unions TYPE_NAME with DECL_NAME NULL. */
+ && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL
+ || DECL_NAME (TYPE_NAME (type))))
dbxout_type_name (type);
else
{
switch (TREE_CODE (expr))
{
case VAR_DECL:
+ /* We can't handle emulated tls variables, because the address is an
+ offset to the return value of __emutls_get_address, and there is no
+ way to express that in stabs. Also, there are name mangling issues
+ here. We end up with references to undefined symbols if we don't
+ disable debug info for these variables. */
+ if (!targetm.have_tls && DECL_THREAD_LOCAL_P (expr))
+ return NULL;
+ /* FALLTHRU */
+
case PARM_DECL:
if (DECL_HAS_VALUE_EXPR_P (expr))
return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
}
}
+/* Helper function for output_used_types. Queue one entry from the
+ used types hash to be output. */
+
+static int
+output_used_types_helper (void **slot, void *data)
+{
+ tree type = *slot;
+ VEC(tree, heap) **types_p = data;
+
+ if ((TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE)
+ && TYPE_STUB_DECL (type)
+ && DECL_P (TYPE_STUB_DECL (type))
+ && ! DECL_IGNORED_P (TYPE_STUB_DECL (type)))
+ VEC_quick_push (tree, *types_p, TYPE_STUB_DECL (type));
+ else if (TYPE_NAME (type)
+ && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+ VEC_quick_push (tree, *types_p, TYPE_NAME (type));
+
+ return 1;
+}
+
+/* This is a qsort callback which sorts types and declarations into a
+ predictable order (types, then declarations, sorted by UID
+ within). */
+
+static int
+output_types_sort (const void *pa, const void *pb)
+{
+ const tree lhs = *((const tree *)pa);
+ const tree rhs = *((const tree *)pb);
+
+ if (TYPE_P (lhs))
+ {
+ if (TYPE_P (rhs))
+ return TYPE_UID (lhs) - TYPE_UID (rhs);
+ else
+ return 1;
+ }
+ else
+ {
+ if (TYPE_P (rhs))
+ return -1;
+ else
+ return DECL_UID (lhs) - DECL_UID (rhs);
+ }
+}
+
+
+/* Force all types used by this function to be output in debug
+ information. */
+
+static void
+output_used_types (void)
+{
+ if (cfun && cfun->used_types_hash)
+ {
+ VEC(tree, heap) *types;
+ int i;
+ tree type;
+
+ types = VEC_alloc (tree, heap, htab_elements (cfun->used_types_hash));
+ htab_traverse (cfun->used_types_hash, output_used_types_helper, &types);
+
+ /* Sort by UID to prevent dependence on hash table ordering. */
+ qsort (VEC_address (tree, types), VEC_length (tree, types),
+ sizeof (tree), output_types_sort);
+
+ for (i = 0; VEC_iterate (tree, types, i, type); i++)
+ debug_queue_symbol (type);
+
+ VEC_free (tree, heap, types);
+ }
+}
+
/* Output a .stabs for the symbol defined by DECL,
which must be a ..._DECL node in the normal namespace.
It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
|| GET_CODE (XEXP (decl_rtl, 0)) != SYMBOL_REF)
break;
+ if (flag_debug_only_used_symbols)
+ output_used_types ();
+
dbxout_begin_complex_stabs ();
stabstr_I (DECL_ASSEMBLER_NAME (decl));
stabstr_S (TREE_PUBLIC (decl) ? ":F" : ":f");
}
}
\f
+#if defined (DBX_DEBUGGING_INFO)
+
/* Subroutine of dbxout_block. Emit an N_LBRAC stab referencing LABEL.
BEGIN_LABEL is the name of the beginning of the function, which may
be required. */
Usually this follows the function's code,
but on some systems, it comes before. */
-#if defined (DBX_DEBUGGING_INFO)
static void
dbxout_begin_function (tree decl)
{