summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
committerkan <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
commit5e00ec74d8ce58f99801200d4d3d0412c7cc1b28 (patch)
tree052f4bb635f2bea2c5e350bd60c902be100a0d1e /contrib/gcc/dwarf2out.c
parent87b8398a7d9f9bf0e28bbcd54a4fc27db2125f38 (diff)
downloadFreeBSD-src-5e00ec74d8ce58f99801200d4d3d0412c7cc1b28.zip
FreeBSD-src-5e00ec74d8ce58f99801200d4d3d0412c7cc1b28.tar.gz
Gcc 3.4.2 20040728.
Diffstat (limited to 'contrib/gcc/dwarf2out.c')
-rw-r--r--contrib/gcc/dwarf2out.c3846
1 files changed, 2126 insertions, 1720 deletions
diff --git a/contrib/gcc/dwarf2out.c b/contrib/gcc/dwarf2out.c
index bd86bc4..a2d8669 100644
--- a/contrib/gcc/dwarf2out.c
+++ b/contrib/gcc/dwarf2out.c
@@ -1,6 +1,6 @@
-/* Output Dwarf2 format symbol table information from the GNU C compiler.
- Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+/* Output Dwarf2 format symbol table information from GCC.
+ Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Contributed by Gary Funck (gary@intrepid.com).
Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -36,6 +36,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "real.h"
@@ -61,11 +63,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "target.h"
#include "langhooks.h"
-#include "hashtable.h"
#include "hashtab.h"
+#include "cgraph.h"
#ifdef DWARF2_DEBUGGING_INFO
-static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
+static void dwarf2out_source_line (unsigned int, const char *);
#endif
/* DWARF2 Abbreviation Glossary:
@@ -90,7 +92,7 @@ static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
translation unit. */
int
-dwarf2out_do_frame ()
+dwarf2out_do_frame (void)
{
return (write_symbols == DWARF2_DEBUG
|| write_symbols == VMS_AND_DWARF2_DEBUG
@@ -109,12 +111,12 @@ dwarf2out_do_frame ()
#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
#endif
-/* Default version of targetm.eh_frame_section. Note this must appear
- outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro
- guards. */
+/* Various versions of targetm.eh_frame_section. Note these must appear
+ outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro guards. */
+/* Version of targetm.eh_frame_section for systems with named sections. */
void
-default_eh_frame_section ()
+named_section_eh_frame_section (void)
{
#ifdef EH_FRAME_SECTION_NAME
#ifdef HAVE_LD_RO_RW_SECTION_MIXING
@@ -135,13 +137,29 @@ default_eh_frame_section ()
#else
named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE);
#endif
-#else
+#endif
+}
+
+/* Version of targetm.eh_frame_section for systems using collect2. */
+void
+collect2_eh_frame_section (void)
+{
tree label = get_file_function_name ('F');
data_section ();
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
(*targetm.asm_out.globalize_label) (asm_out_file, IDENTIFIER_POINTER (label));
ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
+}
+
+/* Default version of targetm.eh_frame_section. */
+void
+default_eh_frame_section (void)
+{
+#ifdef EH_FRAME_SECTION_NAME
+ named_section_eh_frame_section ();
+#else
+ collect2_eh_frame_section ();
#endif
}
@@ -161,8 +179,6 @@ static GTY(()) varray_type incomplete_types;
define type declaration DIE's. */
static GTY(()) varray_type decl_scope_table;
-#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
-
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
@@ -177,21 +193,31 @@ typedef union dw_cfi_oprnd_struct *dw_cfi_oprnd_ref;
and address fields are provided as possible operands;
their use is selected by the opcode field. */
-typedef union dw_cfi_oprnd_struct
+enum dw_cfi_oprnd_type {
+ dw_cfi_oprnd_unused,
+ dw_cfi_oprnd_reg_num,
+ dw_cfi_oprnd_offset,
+ dw_cfi_oprnd_addr,
+ dw_cfi_oprnd_loc
+};
+
+typedef union dw_cfi_oprnd_struct GTY(())
{
- unsigned long dw_cfi_reg_num;
- long int dw_cfi_offset;
- const char *dw_cfi_addr;
- struct dw_loc_descr_struct *dw_cfi_loc;
+ unsigned long GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num;
+ HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset;
+ const char * GTY ((tag ("dw_cfi_oprnd_addr"))) dw_cfi_addr;
+ struct dw_loc_descr_struct * GTY ((tag ("dw_cfi_oprnd_loc"))) dw_cfi_loc;
}
dw_cfi_oprnd;
-typedef struct dw_cfi_struct
+typedef struct dw_cfi_struct GTY(())
{
dw_cfi_ref dw_cfi_next;
enum dwarf_call_frame_info dw_cfi_opc;
- dw_cfi_oprnd dw_cfi_oprnd1;
- dw_cfi_oprnd dw_cfi_oprnd2;
+ dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)")))
+ dw_cfi_oprnd1;
+ dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)")))
+ dw_cfi_oprnd2;
}
dw_cfi_node;
@@ -200,11 +226,11 @@ dw_cfi_node;
It can now be either REG + CFA_OFFSET or *(REG + BASE_OFFSET) + CFA_OFFSET.
Instead of passing around REG and OFFSET, we pass a copy
of this structure. */
-typedef struct cfa_loc
+typedef struct cfa_loc GTY(())
{
unsigned long reg;
- long offset;
- long base_offset;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT base_offset;
int indirect; /* 1 if CFA is accessed via a dereference. */
} dw_cfa_location;
@@ -214,7 +240,7 @@ typedef struct cfa_loc
CIE obviates the need to keep track of multiple CIE's
in the DWARF generation routines below. */
-typedef struct dw_fde_struct
+typedef struct dw_fde_struct GTY(())
{
const char *dw_fde_begin;
const char *dw_fde_current_label;
@@ -248,6 +274,18 @@ dw_fde_node;
#define DWARF_OFFSET_SIZE 4
#endif
+/* According to the (draft) DWARF 3 specification, the initial length
+ should either be 4 or 12 bytes. When it's 12 bytes, the first 4
+ bytes are 0xffffffff, followed by the length stored in the next 8
+ bytes.
+
+ However, the SGI/MIPS ABI uses an initial length which is equal to
+ DWARF_OFFSET_SIZE. It is defined (elsewhere) accordingly. */
+
+#ifndef DWARF_INITIAL_LENGTH_SIZE
+#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12)
+#endif
+
#define DWARF_VERSION 2
/* Round SIZE up to the nearest BOUNDARY. */
@@ -265,67 +303,71 @@ dw_fde_node;
/* A pointer to the base of a table that contains frame description
information for each routine. */
-static dw_fde_ref fde_table;
+static GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table;
/* Number of elements currently allocated for fde_table. */
-static unsigned fde_table_allocated;
+static GTY(()) unsigned fde_table_allocated;
/* Number of elements in fde_table currently in use. */
-static unsigned fde_table_in_use;
+static GTY(()) unsigned fde_table_in_use;
/* Size (in elements) of increments by which we may expand the
fde_table. */
#define FDE_TABLE_INCREMENT 256
/* A list of call frame insns for the CIE. */
-static dw_cfi_ref cie_cfi_head;
+static GTY(()) dw_cfi_ref cie_cfi_head;
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
/* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram
attribute that accelerates the lookup of the FDE associated
with the subprogram. This variable holds the table index of the FDE
associated with the current function (body) definition. */
static unsigned current_funcdef_fde;
+#endif
-struct ht *debug_str_hash;
-
-struct indirect_string_node
+struct indirect_string_node GTY(())
{
- struct ht_identifier id;
+ const char *str;
unsigned int refcount;
unsigned int form;
char *label;
};
+static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
+
+static GTY(()) int dw2_string_counter;
+static GTY(()) unsigned long dwarf2out_cfi_label_num;
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
/* Forward declarations for functions defined in this file. */
-static char *stripattributes PARAMS ((const char *));
-static const char *dwarf_cfi_name PARAMS ((unsigned));
-static dw_cfi_ref new_cfi PARAMS ((void));
-static void add_cfi PARAMS ((dw_cfi_ref *, dw_cfi_ref));
-static void add_fde_cfi PARAMS ((const char *, dw_cfi_ref));
-static void lookup_cfa_1 PARAMS ((dw_cfi_ref,
- dw_cfa_location *));
-static void lookup_cfa PARAMS ((dw_cfa_location *));
-static void reg_save PARAMS ((const char *, unsigned,
- unsigned, long));
-static void initial_return_save PARAMS ((rtx));
-static long stack_adjust_offset PARAMS ((rtx));
-static void output_cfi PARAMS ((dw_cfi_ref, dw_fde_ref, int));
-static void output_call_frame_info PARAMS ((int));
-static void dwarf2out_stack_adjust PARAMS ((rtx));
-static void queue_reg_save PARAMS ((const char *, rtx, long));
-static void flush_queued_reg_saves PARAMS ((void));
-static bool clobbers_queued_reg_save PARAMS ((rtx));
-static void dwarf2out_frame_debug_expr PARAMS ((rtx, const char *));
+static char *stripattributes (const char *);
+static const char *dwarf_cfi_name (unsigned);
+static dw_cfi_ref new_cfi (void);
+static void add_cfi (dw_cfi_ref *, dw_cfi_ref);
+static void add_fde_cfi (const char *, dw_cfi_ref);
+static void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *);
+static void lookup_cfa (dw_cfa_location *);
+static void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT);
+static void initial_return_save (rtx);
+static HOST_WIDE_INT stack_adjust_offset (rtx);
+static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
+static void output_call_frame_info (int);
+static void dwarf2out_stack_adjust (rtx);
+static void queue_reg_save (const char *, rtx, HOST_WIDE_INT);
+static void flush_queued_reg_saves (void);
+static bool clobbers_queued_reg_save (rtx);
+static void dwarf2out_frame_debug_expr (rtx, const char *);
/* Support for complex CFA locations. */
-static void output_cfa_loc PARAMS ((dw_cfi_ref));
-static void get_cfa_from_loc_descr PARAMS ((dw_cfa_location *,
- struct dw_loc_descr_struct *));
+static void output_cfa_loc (dw_cfi_ref);
+static void get_cfa_from_loc_descr (dw_cfa_location *,
+ struct dw_loc_descr_struct *);
static struct dw_loc_descr_struct *build_cfa_loc
- PARAMS ((dw_cfa_location *));
-static void def_cfa_1 PARAMS ((const char *,
- dw_cfa_location *));
+ (dw_cfa_location *);
+static void def_cfa_1 (const char *, dw_cfa_location *);
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
@@ -365,9 +407,9 @@ static void def_cfa_1 PARAMS ((const char *,
registers. */
#ifndef DWARF_FRAME_RETURN_COLUMN
#ifdef PC_REGNUM
-#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM)
#else
-#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS
#endif
#endif
@@ -386,7 +428,7 @@ static void def_cfa_1 PARAMS ((const char *,
/* Hook used by __throw. */
rtx
-expand_builtin_dwarf_sp_column ()
+expand_builtin_dwarf_sp_column (void)
{
return GEN_INT (DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM));
}
@@ -395,8 +437,7 @@ expand_builtin_dwarf_sp_column ()
attributes stripped off, and an asterisk prepended (for assemble_name). */
static inline char *
-stripattributes (s)
- const char *s;
+stripattributes (const char *s)
{
char *stripped = xmalloc (strlen (s) + 2);
char *p = stripped;
@@ -413,20 +454,30 @@ stripattributes (s)
/* Generate code to initialize the register size table. */
void
-expand_builtin_init_dwarf_reg_sizes (address)
- tree address;
+expand_builtin_init_dwarf_reg_sizes (tree address)
{
int i;
enum machine_mode mode = TYPE_MODE (char_type_node);
rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
rtx mem = gen_rtx_MEM (BLKmode, addr);
+ bool wrote_return_column = false;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS)
{
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
- HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
+ enum machine_mode save_mode = reg_raw_mode[i];
+ HOST_WIDE_INT size;
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
+ save_mode = choose_hard_reg_mode (i, 1, true);
+ if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
+ {
+ if (save_mode == VOIDmode)
+ continue;
+ wrote_return_column = true;
+ }
+ size = GET_MODE_SIZE (save_mode);
if (offset < 0)
continue;
@@ -434,20 +485,27 @@ expand_builtin_init_dwarf_reg_sizes (address)
}
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
- {
- enum machine_mode save_mode = Pmode;
- HOST_WIDE_INT offset = DWARF_ALT_FRAME_RETURN_COLUMN * GET_MODE_SIZE (mode);
- HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
- emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
- }
+ if (! wrote_return_column)
+ abort ();
+ i = DWARF_ALT_FRAME_RETURN_COLUMN;
+ wrote_return_column = false;
+#else
+ i = DWARF_FRAME_RETURN_COLUMN;
#endif
+
+ if (! wrote_return_column)
+ {
+ enum machine_mode save_mode = Pmode;
+ HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode);
+ HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
+ emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+ }
}
/* Convert a DWARF call frame info. operation to its string name */
static const char *
-dwarf_cfi_name (cfi_opc)
- unsigned cfi_opc;
+dwarf_cfi_name (unsigned int cfi_opc)
{
switch (cfi_opc)
{
@@ -520,9 +578,9 @@ dwarf_cfi_name (cfi_opc)
/* Return a pointer to a newly allocated Call Frame Instruction. */
static inline dw_cfi_ref
-new_cfi ()
+new_cfi (void)
{
- dw_cfi_ref cfi = (dw_cfi_ref) xmalloc (sizeof (dw_cfi_node));
+ dw_cfi_ref cfi = ggc_alloc (sizeof (dw_cfi_node));
cfi->dw_cfi_next = NULL;
cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
@@ -534,9 +592,7 @@ new_cfi ()
/* Add a Call Frame Instruction to list of instructions. */
static inline void
-add_cfi (list_head, cfi)
- dw_cfi_ref *list_head;
- dw_cfi_ref cfi;
+add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
{
dw_cfi_ref *p;
@@ -550,12 +606,11 @@ add_cfi (list_head, cfi)
/* Generate a new label for the CFI info to refer to. */
char *
-dwarf2out_cfi_label ()
+dwarf2out_cfi_label (void)
{
static char label[20];
- static unsigned long label_num = 0;
- ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", label_num++);
+ ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", dwarf2out_cfi_label_num++);
ASM_OUTPUT_LABEL (asm_out_file, label);
return label;
}
@@ -564,9 +619,7 @@ dwarf2out_cfi_label ()
or to the CIE if LABEL is NULL. */
static void
-add_fde_cfi (label, cfi)
- const char *label;
- dw_cfi_ref cfi;
+add_fde_cfi (const char *label, dw_cfi_ref cfi)
{
if (label)
{
@@ -599,9 +652,7 @@ add_fde_cfi (label, cfi)
/* Subroutine of lookup_cfa. */
static inline void
-lookup_cfa_1 (cfi, loc)
- dw_cfi_ref cfi;
- dw_cfa_location *loc;
+lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
{
switch (cfi->dw_cfi_opc)
{
@@ -626,8 +677,7 @@ lookup_cfa_1 (cfi, loc)
/* Find the previous value for the CFA. */
static void
-lookup_cfa (loc)
- dw_cfa_location *loc;
+lookup_cfa (dw_cfa_location *loc)
{
dw_cfi_ref cfi;
@@ -655,20 +705,17 @@ static dw_cfa_location cfa;
static dw_cfa_location cfa_store;
/* The running total of the size of arguments pushed onto the stack. */
-static long args_size;
+static HOST_WIDE_INT args_size;
/* The last args_size we actually output. */
-static long old_args_size;
+static HOST_WIDE_INT old_args_size;
/* Entry point to update the canonical frame address (CFA).
LABEL is passed to add_fde_cfi. The value of CFA is now to be
calculated from REG+OFFSET. */
void
-dwarf2out_def_cfa (label, reg, offset)
- const char *label;
- unsigned reg;
- long offset;
+dwarf2out_def_cfa (const char *label, unsigned int reg, HOST_WIDE_INT offset)
{
dw_cfa_location loc;
loc.indirect = 0;
@@ -682,9 +729,7 @@ dwarf2out_def_cfa (label, reg, offset)
the dw_cfa_location structure. */
static void
-def_cfa_1 (label, loc_p)
- const char *label;
- dw_cfa_location *loc_p;
+def_cfa_1 (const char *label, dw_cfa_location *loc_p)
{
dw_cfi_ref cfi;
dw_cfa_location old_cfa, loc;
@@ -757,11 +802,7 @@ def_cfa_1 (label, loc_p)
otherwise it is saved in SREG. */
static void
-reg_save (label, reg, sreg, offset)
- const char *label;
- unsigned reg;
- unsigned sreg;
- long offset;
+reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
{
dw_cfi_ref cfi = new_cfi ();
@@ -784,7 +825,7 @@ reg_save (label, reg, sreg, offset)
DWARF_CIE_DATA_ALIGNMENT, there is either a bug in the
definition of DWARF_CIE_DATA_ALIGNMENT, or a bug in the machine
description. */
- long check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
+ HOST_WIDE_INT check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
if (check_offset * DWARF_CIE_DATA_ALIGNMENT != offset)
abort ();
@@ -816,8 +857,7 @@ reg_save (label, reg, sreg, offset)
assuming 0(cfa)) and what registers are in the window. */
void
-dwarf2out_window_save (label)
- const char *label;
+dwarf2out_window_save (const char *label)
{
dw_cfi_ref cfi = new_cfi ();
@@ -829,9 +869,7 @@ dwarf2out_window_save (label)
pushed onto the stack. */
void
-dwarf2out_args_size (label, size)
- const char *label;
- long size;
+dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
{
dw_cfi_ref cfi;
@@ -850,10 +888,7 @@ dwarf2out_args_size (label, size)
number. LABEL and OFFSET are passed to reg_save. */
void
-dwarf2out_reg_save (label, reg, offset)
- const char *label;
- unsigned reg;
- long offset;
+dwarf2out_reg_save (const char *label, unsigned int reg, HOST_WIDE_INT offset)
{
reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
}
@@ -862,9 +897,7 @@ dwarf2out_reg_save (label, reg, offset)
LABEL and OFFSET are passed to reg_save. */
void
-dwarf2out_return_save (label, offset)
- const char *label;
- long offset;
+dwarf2out_return_save (const char *label, HOST_WIDE_INT offset)
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
}
@@ -873,9 +906,7 @@ dwarf2out_return_save (label, offset)
LABEL and SREG are passed to reg_save. */
void
-dwarf2out_return_reg (label, sreg)
- const char *label;
- unsigned sreg;
+dwarf2out_return_reg (const char *label, unsigned int sreg)
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0);
}
@@ -884,8 +915,7 @@ dwarf2out_return_reg (label, sreg)
INCOMING_RETURN_ADDR_RTX. */
static void
-initial_return_save (rtl)
- rtx rtl;
+initial_return_save (rtx rtl)
{
unsigned int reg = (unsigned int) -1;
HOST_WIDE_INT offset = 0;
@@ -945,9 +975,8 @@ initial_return_save (rtl)
/* Given a SET, calculate the amount of stack adjustment it
contains. */
-static long
-stack_adjust_offset (pattern)
- rtx pattern;
+static HOST_WIDE_INT
+stack_adjust_offset (rtx pattern)
{
rtx src = SET_SRC (pattern);
rtx dest = SET_DEST (pattern);
@@ -1022,13 +1051,19 @@ stack_adjust_offset (pattern)
much extra space it needs to pop off the stack. */
static void
-dwarf2out_stack_adjust (insn)
- rtx insn;
+dwarf2out_stack_adjust (rtx insn)
{
HOST_WIDE_INT offset;
const char *label;
int i;
+ /* Don't handle epilogues at all. Certainly it would be wrong to do so
+ with this function. Proper support would require all frame-related
+ insns to be marked, and to be able to handle saving state around
+ epilogues textually in the middle of the function. */
+ if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn))
+ return;
+
if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN)
{
/* Extract the size of the args from the CALL rtx itself. */
@@ -1093,27 +1128,28 @@ dwarf2out_stack_adjust (insn)
dwarf2out_args_size (label, args_size);
}
+#endif
+
/* We delay emitting a register save until either (a) we reach the end
of the prologue or (b) the register is clobbered. This clusters
register saves so that there are fewer pc advances. */
-struct queued_reg_save
+struct queued_reg_save GTY(())
{
struct queued_reg_save *next;
rtx reg;
- long cfa_offset;
+ HOST_WIDE_INT cfa_offset;
};
-static struct queued_reg_save *queued_reg_saves;
+static GTY(()) struct queued_reg_save *queued_reg_saves;
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
static const char *last_reg_save_label;
static void
-queue_reg_save (label, reg, offset)
- const char *label;
- rtx reg;
- long offset;
+queue_reg_save (const char *label, rtx reg, HOST_WIDE_INT offset)
{
- struct queued_reg_save *q = (struct queued_reg_save *) xmalloc (sizeof (*q));
+ struct queued_reg_save *q = ggc_alloc (sizeof (*q));
q->next = queued_reg_saves;
q->reg = reg;
@@ -1124,7 +1160,7 @@ queue_reg_save (label, reg, offset)
}
static void
-flush_queued_reg_saves ()
+flush_queued_reg_saves (void)
{
struct queued_reg_save *q, *next;
@@ -1132,7 +1168,6 @@ flush_queued_reg_saves ()
{
dwarf2out_reg_save (last_reg_save_label, REGNO (q->reg), q->cfa_offset);
next = q->next;
- free (q);
}
queued_reg_saves = NULL;
@@ -1140,8 +1175,7 @@ flush_queued_reg_saves ()
}
static bool
-clobbers_queued_reg_save (insn)
- rtx insn;
+clobbers_queued_reg_save (rtx insn)
{
struct queued_reg_save *q;
@@ -1204,7 +1238,7 @@ static dw_cfa_location cfa_temp;
to track stores to the stack via fp or a temp reg.
Rules 1- 4: Setting a register's value to cfa.reg or an expression
- with cfa.reg as the first operand changes the cfa.reg and its
+ with cfa.reg as the first operand changes the cfa.reg and its
cfa.offset. Rule 1 and 4 also set cfa_temp.reg and
cfa_temp.offset.
@@ -1227,7 +1261,7 @@ static dw_cfa_location cfa_temp;
Rule 1:
(set <reg1> <reg2>:cfa.reg)
effects: cfa.reg = <reg1>
- cfa.offset unchanged
+ cfa.offset unchanged
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
@@ -1235,19 +1269,19 @@ static dw_cfa_location cfa_temp;
(set sp ({minus,plus,losum} {sp,fp}:cfa.reg
{<const_int>,<reg>:cfa_temp.reg}))
effects: cfa.reg = sp if fp used
- cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
+ cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
cfa_store.offset += {+/- <const_int>, cfa_temp.offset}
if cfa_store.reg==sp
Rule 3:
(set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>))
effects: cfa.reg = fp
- cfa_offset += +/- <const_int>
+ cfa_offset += +/- <const_int>
Rule 4:
(set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>))
constraints: <reg1> != fp
- <reg1> != sp
+ <reg1> != sp
effects: cfa.reg = <reg1>
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
@@ -1255,14 +1289,14 @@ static dw_cfa_location cfa_temp;
Rule 5:
(set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg))
constraints: <reg1> != fp
- <reg1> != sp
+ <reg1> != sp
effects: cfa_store.reg = <reg1>
- cfa_store.offset = cfa.offset - cfa_temp.offset
+ cfa_store.offset = cfa.offset - cfa_temp.offset
Rule 6:
(set <reg> <const_int>)
effects: cfa_temp.reg = <reg>
- cfa_temp.offset = <const_int>
+ cfa_temp.offset = <const_int>
Rule 7:
(set <reg1>:cfa_temp.reg (ior <reg2>:cfa_temp.reg <const_int>))
@@ -1276,7 +1310,7 @@ static dw_cfa_location cfa_temp;
Rule 9:
(set <reg> (lo_sum <exp> <const_int>))
effects: cfa_temp.reg = <reg>
- cfa_temp.offset = <const_int>
+ cfa_temp.offset = <const_int>
Rule 10:
(set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>)
@@ -1311,9 +1345,7 @@ static dw_cfa_location cfa_temp;
cfa_temp.offset -= mode_size(mem) */
static void
-dwarf2out_frame_debug_expr (expr, label)
- rtx expr;
- const char *label;
+dwarf2out_frame_debug_expr (rtx expr, const char *label)
{
rtx src, dest;
HOST_WIDE_INT offset;
@@ -1348,7 +1380,7 @@ dwarf2out_frame_debug_expr (expr, label)
case REG:
/* Rule 1 */
/* Update the CFA rule wrt SP or FP. Make sure src is
- relative to the current CFA register. */
+ relative to the current CFA register. */
switch (GET_CODE (src))
{
/* Setting FP from SP. */
@@ -1611,7 +1643,7 @@ dwarf2out_frame_debug_expr (expr, label)
else
{
/* Otherwise, we'll need to look in the stack to
- calculate the CFA. */
+ calculate the CFA. */
rtx x = XEXP (dest, 0);
if (GET_CODE (x) != REG)
@@ -1641,8 +1673,7 @@ dwarf2out_frame_debug_expr (expr, label)
register to the stack. If INSN is NULL_RTX, initialize our state. */
void
-dwarf2out_frame_debug (insn)
- rtx insn;
+dwarf2out_frame_debug (rtx insn)
{
const char *label;
rtx src;
@@ -1685,32 +1716,111 @@ dwarf2out_frame_debug (insn)
dwarf2out_frame_debug_expr (insn, label);
}
+#endif
+
+/* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used. */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc
+ (enum dwarf_call_frame_info cfi);
+
+static enum dw_cfi_oprnd_type
+dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
+{
+ switch (cfi)
+ {
+ case DW_CFA_nop:
+ case DW_CFA_GNU_window_save:
+ return dw_cfi_oprnd_unused;
+
+ case DW_CFA_set_loc:
+ case DW_CFA_advance_loc1:
+ case DW_CFA_advance_loc2:
+ case DW_CFA_advance_loc4:
+ case DW_CFA_MIPS_advance_loc8:
+ return dw_cfi_oprnd_addr;
+
+ case DW_CFA_offset:
+ case DW_CFA_offset_extended:
+ case DW_CFA_def_cfa:
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_restore_extended:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_register:
+ return dw_cfi_oprnd_reg_num;
+
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_GNU_args_size:
+ case DW_CFA_def_cfa_offset_sf:
+ return dw_cfi_oprnd_offset;
+
+ case DW_CFA_def_cfa_expression:
+ case DW_CFA_expression:
+ return dw_cfi_oprnd_loc;
+
+ default:
+ abort ();
+ }
+}
+
+/* Describe for the GTY machinery what parts of dw_cfi_oprnd2 are used. */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc
+ (enum dwarf_call_frame_info cfi);
+
+static enum dw_cfi_oprnd_type
+dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
+{
+ switch (cfi)
+ {
+ case DW_CFA_def_cfa:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_offset:
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_offset_extended:
+ return dw_cfi_oprnd_offset;
+
+ case DW_CFA_register:
+ return dw_cfi_oprnd_reg_num;
+
+ default:
+ return dw_cfi_oprnd_unused;
+ }
+}
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. */
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
/* Output a Call Frame Information opcode and its operand(s). */
static void
-output_cfi (cfi, fde, for_eh)
- dw_cfi_ref cfi;
- dw_fde_ref fde;
- int for_eh;
+output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
{
+ unsigned long r;
if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
dw2_asm_output_data (1, (cfi->dw_cfi_opc
| (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
- "DW_CFA_advance_loc 0x%lx",
+ "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
cfi->dw_cfi_oprnd1.dw_cfi_offset);
else if (cfi->dw_cfi_opc == DW_CFA_offset)
{
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_offset, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_offset, column 0x%lx", r);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
}
else if (cfi->dw_cfi_opc == DW_CFA_restore)
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_restore, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ {
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_restore, column 0x%lx", r);
+ }
else
{
dw2_asm_output_data (1, cfi->dw_cfi_opc,
@@ -1755,15 +1865,15 @@ output_cfi (cfi, fde, for_eh)
case DW_CFA_offset_extended:
case DW_CFA_def_cfa:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
@@ -1771,15 +1881,15 @@ output_cfi (cfi, fde, for_eh)
case DW_CFA_undefined:
case DW_CFA_same_value:
case DW_CFA_def_cfa_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_def_cfa_offset:
@@ -1809,13 +1919,12 @@ output_cfi (cfi, fde, for_eh)
}
}
-/* Output the call frame information used to used to record information
+/* Output the call frame information used to record information
that relates to calculating the frame pointer, and records the
location of saved registers. */
static void
-output_call_frame_info (for_eh)
- int for_eh;
+output_call_frame_info (int for_eh)
{
unsigned int i;
dw_fde_ref fde;
@@ -1843,7 +1952,8 @@ output_call_frame_info (for_eh)
for (i = 0; i < fde_table_in_use; i++)
if (fde_table[i].uses_eh_lsda)
any_eh_needed = any_lsda_needed = true;
- else if (! fde_table[i].nothrow)
+ else if (! fde_table[i].nothrow
+ && ! fde_table[i].all_throwers_are_sibcalls)
any_eh_needed = true;
if (! any_eh_needed)
@@ -1885,7 +1995,7 @@ output_call_frame_info (for_eh)
/* Augmentation:
z Indicates that a uleb128 is present to size the
- augmentation section.
+ augmentation section.
L Indicates the encoding (and thus presence) of
an LSDA pointer in the FDE augmentation.
R Indicates a non-default pointer encoding for
@@ -1987,7 +2097,7 @@ output_call_frame_info (for_eh)
&& !fde->uses_eh_lsda)
continue;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
+ (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1,
@@ -2040,13 +2150,13 @@ output_call_frame_info (for_eh)
dw2_asm_output_data_uleb128 (size, "Augmentation size");
if (fde->uses_eh_lsda)
- {
- ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
+ {
+ ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
fde->funcdef_number);
- dw2_asm_output_encoded_addr_rtx (
+ dw2_asm_output_encoded_addr_rtx (
lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1),
- "Language Specific Data Area");
- }
+ "Language Specific Data Area");
+ }
else
{
if (lsda_encoding == DW_EH_PE_aligned)
@@ -2068,7 +2178,7 @@ output_call_frame_info (for_eh)
/* Pad the FDE out to an address sized boundary. */
ASM_OUTPUT_ALIGN (asm_out_file,
- floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
+ floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
ASM_OUTPUT_LABEL (asm_out_file, l2);
}
@@ -2089,9 +2199,8 @@ output_call_frame_info (for_eh)
the prologue. */
void
-dwarf2out_begin_prologue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
dw_fde_ref fde;
@@ -2127,9 +2236,10 @@ dwarf2out_begin_prologue (line, file)
if (fde_table_in_use == fde_table_allocated)
{
fde_table_allocated += FDE_TABLE_INCREMENT;
- fde_table
- = (dw_fde_ref) xrealloc (fde_table,
- fde_table_allocated * sizeof (dw_fde_node));
+ fde_table = ggc_realloc (fde_table,
+ fde_table_allocated * sizeof (dw_fde_node));
+ memset (fde_table + fde_table_in_use, 0,
+ FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
}
/* Record the FDE associated with this function. */
@@ -2161,9 +2271,8 @@ dwarf2out_begin_prologue (line, file)
been generated. */
void
-dwarf2out_end_epilogue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
dw_fde_ref fde;
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -2178,10 +2287,10 @@ dwarf2out_end_epilogue (line, file)
}
void
-dwarf2out_frame_init ()
+dwarf2out_frame_init (void)
{
/* Allocate the initial hunk of the fde_table. */
- fde_table = (dw_fde_ref) xcalloc (FDE_TABLE_INCREMENT, sizeof (dw_fde_node));
+ fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
fde_table_allocated = FDE_TABLE_INCREMENT;
fde_table_in_use = 0;
@@ -2196,7 +2305,7 @@ dwarf2out_frame_init ()
}
void
-dwarf2out_frame_finish ()
+dwarf2out_frame_finish (void)
{
/* Output call frame information. */
if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
@@ -2205,6 +2314,7 @@ dwarf2out_frame_finish ()
if (! USING_SJLJ_EXCEPTIONS && (flag_unwind_tables || flag_exceptions))
output_call_frame_info (1);
}
+#endif
/* And now, the subset of the debugging information support code necessary
for emitting location expressions. */
@@ -2223,7 +2333,7 @@ typedef struct dw_loc_list_struct *dw_loc_list_ref;
can take on several forms. The forms that are used in this
implementation are listed below. */
-typedef enum
+enum dw_val_class
{
dw_val_class_addr,
dw_val_class_offset,
@@ -2233,69 +2343,69 @@ typedef enum
dw_val_class_const,
dw_val_class_unsigned_const,
dw_val_class_long_long,
- dw_val_class_float,
+ dw_val_class_vec,
dw_val_class_flag,
dw_val_class_die_ref,
dw_val_class_fde_ref,
dw_val_class_lbl_id,
dw_val_class_lbl_offset,
dw_val_class_str
-}
-dw_val_class;
+};
/* Describe a double word constant value. */
/* ??? Every instance of long_long in the code really means CONST_DOUBLE. */
-typedef struct dw_long_long_struct
+typedef struct dw_long_long_struct GTY(())
{
unsigned long hi;
unsigned long low;
}
dw_long_long_const;
-/* Describe a floating point constant value. */
+/* Describe a floating point constant value, or a vector constant value. */
-typedef struct dw_fp_struct
+typedef struct dw_vec_struct GTY(())
{
- long *array;
+ unsigned char * GTY((length ("%h.length"))) array;
unsigned length;
+ unsigned elt_size;
}
-dw_float_const;
+dw_vec_const;
/* The dw_val_node describes an attribute's value, as it is
represented internally. */
-typedef struct dw_val_struct
+typedef struct dw_val_struct GTY(())
{
- dw_val_class val_class;
- union
+ enum dw_val_class val_class;
+ union dw_val_struct_union
{
- rtx val_addr;
- long unsigned val_offset;
- dw_loc_list_ref val_loc_list;
- dw_loc_descr_ref val_loc;
- long int val_int;
- long unsigned val_unsigned;
- dw_long_long_const val_long_long;
- dw_float_const val_float;
- struct
+ rtx GTY ((tag ("dw_val_class_addr"))) val_addr;
+ unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset;
+ dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list;
+ dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc;
+ HOST_WIDE_INT GTY ((default (""))) val_int;
+ unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
+ dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long;
+ dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
+ struct dw_val_die_union
{
dw_die_ref die;
int external;
- } val_die_ref;
- unsigned val_fde_index;
- struct indirect_string_node *val_str;
- char *val_lbl_id;
- unsigned char val_flag;
+ } GTY ((tag ("dw_val_class_die_ref"))) val_die_ref;
+ unsigned GTY ((tag ("dw_val_class_fde_ref"))) val_fde_index;
+ struct indirect_string_node * GTY ((tag ("dw_val_class_str"))) val_str;
+ char * GTY ((tag ("dw_val_class_lbl_id"))) val_lbl_id;
+ unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag;
}
- v;
+ GTY ((desc ("%1.val_class"))) v;
}
dw_val_node;
/* Locations in memory are described using a sequence of stack machine
operations. */
-typedef struct dw_loc_descr_struct
+typedef struct dw_loc_descr_struct GTY(())
{
dw_loc_descr_ref dw_loc_next;
enum dwarf_location_atom dw_loc_opc;
@@ -2308,7 +2418,7 @@ dw_loc_descr_node;
/* Location lists are ranges + location descriptions for that range,
so you can track variables that are in different places over
their entire life. */
-typedef struct dw_loc_list_struct
+typedef struct dw_loc_list_struct GTY(())
{
dw_loc_list_ref dw_loc_next;
const char *begin; /* Label for begin address of range */
@@ -2319,22 +2429,21 @@ typedef struct dw_loc_list_struct
dw_loc_descr_ref expr;
} dw_loc_list_node;
-static const char *dwarf_stack_op_name PARAMS ((unsigned));
-static dw_loc_descr_ref new_loc_descr PARAMS ((enum dwarf_location_atom,
- unsigned long,
- unsigned long));
-static void add_loc_descr PARAMS ((dw_loc_descr_ref *,
- dw_loc_descr_ref));
-static unsigned long size_of_loc_descr PARAMS ((dw_loc_descr_ref));
-static unsigned long size_of_locs PARAMS ((dw_loc_descr_ref));
-static void output_loc_operands PARAMS ((dw_loc_descr_ref));
-static void output_loc_sequence PARAMS ((dw_loc_descr_ref));
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
+static const char *dwarf_stack_op_name (unsigned);
+static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
+ unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
+static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
+static unsigned long size_of_loc_descr (dw_loc_descr_ref);
+static unsigned long size_of_locs (dw_loc_descr_ref);
+static void output_loc_operands (dw_loc_descr_ref);
+static void output_loc_sequence (dw_loc_descr_ref);
/* Convert a DWARF stack opcode into its string name. */
static const char *
-dwarf_stack_op_name (op)
- unsigned op;
+dwarf_stack_op_name (unsigned int op)
{
switch (op)
{
@@ -2649,15 +2758,10 @@ dwarf_stack_op_name (op)
together to form more complicated location (address) descriptions. */
static inline dw_loc_descr_ref
-new_loc_descr (op, oprnd1, oprnd2)
- enum dwarf_location_atom op;
- unsigned long oprnd1;
- unsigned long oprnd2;
+new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
+ unsigned HOST_WIDE_INT oprnd2)
{
- /* Use xcalloc here so we clear out all of the long_long constant in
- the union. */
- dw_loc_descr_ref descr
- = (dw_loc_descr_ref) xcalloc (1, sizeof (dw_loc_descr_node));
+ dw_loc_descr_ref descr = ggc_alloc_cleared (sizeof (dw_loc_descr_node));
descr->dw_loc_opc = op;
descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
@@ -2672,9 +2776,7 @@ new_loc_descr (op, oprnd1, oprnd2)
/* Add a location description term to a location description expression. */
static inline void
-add_loc_descr (list_head, descr)
- dw_loc_descr_ref *list_head;
- dw_loc_descr_ref descr;
+add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
{
dw_loc_descr_ref *d;
@@ -2688,8 +2790,7 @@ add_loc_descr (list_head, descr)
/* Return the size of a location descriptor. */
static unsigned long
-size_of_loc_descr (loc)
- dw_loc_descr_ref loc;
+size_of_loc_descr (dw_loc_descr_ref loc)
{
unsigned long size = 1;
@@ -2801,8 +2902,7 @@ size_of_loc_descr (loc)
/* Return the size of a series of location descriptors. */
static unsigned long
-size_of_locs (loc)
- dw_loc_descr_ref loc;
+size_of_locs (dw_loc_descr_ref loc)
{
unsigned long size;
@@ -2818,8 +2918,7 @@ size_of_locs (loc)
/* Output location description stack opcode's operands (if any). */
static void
-output_loc_operands (loc)
- dw_loc_descr_ref loc;
+output_loc_operands (dw_loc_descr_ref loc)
{
dw_val_ref val1 = &loc->dw_loc_oprnd1;
dw_val_ref val2 = &loc->dw_loc_oprnd2;
@@ -2868,9 +2967,9 @@ output_loc_operands (loc)
case DW_OP_skip:
case DW_OP_bra:
/* We currently don't make any attempt to make sure these are
- aligned properly like we do for the main unwind info, so
- don't support emitting things larger than a byte if we're
- only doing unwinding. */
+ aligned properly like we do for the main unwind info, so
+ don't support emitting things larger than a byte if we're
+ only doing unwinding. */
abort ();
#endif
case DW_OP_const1u:
@@ -2960,8 +3059,7 @@ output_loc_operands (loc)
/* Output a sequence of location operations. */
static void
-output_loc_sequence (loc)
- dw_loc_descr_ref loc;
+output_loc_sequence (dw_loc_descr_ref loc)
{
for (; loc != NULL; loc = loc->dw_loc_next)
{
@@ -2978,8 +3076,7 @@ output_loc_sequence (loc)
description based on a cfi entry with a complex address. */
static void
-output_cfa_loc (cfi)
- dw_cfi_ref cfi;
+output_cfa_loc (dw_cfi_ref cfi)
{
dw_loc_descr_ref loc;
unsigned long size;
@@ -2997,8 +3094,7 @@ output_cfa_loc (cfi)
a dw_cfa_location. */
static struct dw_loc_descr_struct *
-build_cfa_loc (cfa)
- dw_cfa_location *cfa;
+build_cfa_loc (dw_cfa_location *cfa)
{
struct dw_loc_descr_struct *head, *tmp;
@@ -3033,9 +3129,7 @@ build_cfa_loc (cfa)
descriptor sequence. */
static void
-get_cfa_from_loc_descr (cfa, loc)
- dw_cfa_location *cfa;
- struct dw_loc_descr_struct *loc;
+get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc)
{
struct dw_loc_descr_struct *ptr;
cfa->offset = 0;
@@ -3143,22 +3237,19 @@ get_cfa_from_loc_descr (cfa, loc)
#ifdef DWARF2_DEBUGGING_INFO
/* .debug_str support. */
-static hashnode indirect_string_alloc PARAMS ((hash_table *));
-static int output_indirect_string PARAMS ((struct cpp_reader *,
- hashnode, const PTR));
-
-
-static void dwarf2out_init PARAMS ((const char *));
-static void dwarf2out_finish PARAMS ((const char *));
-static void dwarf2out_define PARAMS ((unsigned int, const char *));
-static void dwarf2out_undef PARAMS ((unsigned int, const char *));
-static void dwarf2out_start_source_file PARAMS ((unsigned, const char *));
-static void dwarf2out_end_source_file PARAMS ((unsigned));
-static void dwarf2out_begin_block PARAMS ((unsigned, unsigned));
-static void dwarf2out_end_block PARAMS ((unsigned, unsigned));
-static bool dwarf2out_ignore_block PARAMS ((tree));
-static void dwarf2out_global_decl PARAMS ((tree));
-static void dwarf2out_abstract_function PARAMS ((tree));
+static int output_indirect_string (void **, void *);
+
+static void dwarf2out_init (const char *);
+static void dwarf2out_finish (const char *);
+static void dwarf2out_define (unsigned int, const char *);
+static void dwarf2out_undef (unsigned int, const char *);
+static void dwarf2out_start_source_file (unsigned, const char *);
+static void dwarf2out_end_source_file (unsigned);
+static void dwarf2out_begin_block (unsigned, unsigned);
+static void dwarf2out_end_block (unsigned, unsigned);
+static bool dwarf2out_ignore_block (tree);
+static void dwarf2out_global_decl (tree);
+static void dwarf2out_abstract_function (tree);
/* The debug hooks structure. */
@@ -3186,8 +3277,10 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
emitting the abstract description of inline functions until
something tries to reference them. */
dwarf2out_abstract_function, /* outlining_inline_function */
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ debug_nothing_int /* handle_pch */
};
+#endif
/* NOTE: In the comments in this file, many references are made to
"Debugging Information Entries". This term is abbreviated as `DIE'
@@ -3216,7 +3309,7 @@ typedef struct dw_ranges_struct *dw_ranges_ref;
entry. The label gives the PC value associated with
the line number entry. */
-typedef struct dw_line_info_struct
+typedef struct dw_line_info_struct GTY(())
{
unsigned long dw_file_num;
unsigned long dw_line_num;
@@ -3225,7 +3318,7 @@ dw_line_info_entry;
/* Line information for functions in separate sections; each one gets its
own sequence. */
-typedef struct dw_separate_line_info_struct
+typedef struct dw_separate_line_info_struct GTY(())
{
unsigned long dw_file_num;
unsigned long dw_line_num;
@@ -3237,7 +3330,7 @@ dw_separate_line_info_entry;
a link to the next attribute in the chain, and an attribute value.
Attributes are typically linked below the DIE they modify. */
-typedef struct dw_attr_struct
+typedef struct dw_attr_struct GTY(())
{
enum dwarf_attribute dw_attr;
dw_attr_ref dw_attr_next;
@@ -3247,7 +3340,7 @@ dw_attr_node;
/* The Debugging Information Entry (DIE) structure */
-typedef struct die_struct
+typedef struct die_struct GTY(())
{
enum dwarf_tag die_tag;
char *die_symbol;
@@ -3255,6 +3348,7 @@ typedef struct die_struct
dw_die_ref die_parent;
dw_die_ref die_child;
dw_die_ref die_sib;
+ dw_die_ref die_definition; /* ref from a specification to its definition */
dw_offset die_offset;
unsigned long die_abbrev;
int die_mark;
@@ -3263,20 +3357,20 @@ die_node;
/* The pubname structure */
-typedef struct pubname_struct
+typedef struct pubname_struct GTY(())
{
dw_die_ref die;
char *name;
}
pubname_entry;
-struct dw_ranges_struct
+struct dw_ranges_struct GTY(())
{
int block_num;
};
/* The limbo die list structure. */
-typedef struct limbo_die_struct
+typedef struct limbo_die_struct GTY(())
{
dw_die_ref die;
tree created_for;
@@ -3314,21 +3408,24 @@ limbo_die_node;
language, and compiler version. */
/* Fixed size portion of the DWARF compilation unit header. */
-#define DWARF_COMPILE_UNIT_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 3)
+#define DWARF_COMPILE_UNIT_HEADER_SIZE \
+ (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 3)
/* Fixed size portion of public names info. */
#define DWARF_PUBNAMES_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 2)
/* Fixed size portion of the address range info. */
#define DWARF_ARANGES_HEADER_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
- - DWARF_OFFSET_SIZE)
+ (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \
+ DWARF2_ADDR_SIZE * 2) \
+ - DWARF_INITIAL_LENGTH_SIZE)
/* Size of padding portion in the address range info. It must be
aligned to twice the pointer size. */
#define DWARF_ARANGES_PAD_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
- - (2 * DWARF_OFFSET_SIZE + 4))
+ (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \
+ DWARF2_ADDR_SIZE * 2) \
+ - (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4))
/* Use assembler line directives if available. */
#ifndef DWARF2_ASM_LINE_DEBUG_INFO
@@ -3355,50 +3452,33 @@ limbo_die_node;
is not made available by the GCC front-end. */
#define DWARF_LINE_DEFAULT_IS_STMT_START 1
+#ifdef DWARF2_DEBUGGING_INFO
/* This location is used by calc_die_sizes() to keep track
the offset of each DIE within the .debug_info section. */
static unsigned long next_die_offset;
+#endif
/* Record the root of the DIE's built for the current compilation unit. */
-static dw_die_ref comp_unit_die;
-
-/* We need special handling in dwarf2out_start_source_file if it is
- first one. */
-static int is_main_source;
+static GTY(()) dw_die_ref comp_unit_die;
/* A list of DIEs with a NULL parent waiting to be relocated. */
-static limbo_die_node *limbo_die_list = 0;
-
-/* Structure used by lookup_filename to manage sets of filenames. */
-struct file_table
-{
- char **table;
- unsigned allocated;
- unsigned in_use;
- unsigned last_lookup_index;
-};
-
-/* Size (in elements) of increments by which we may expand the filename
- table. */
-#define FILE_TABLE_INCREMENT 64
+static GTY(()) limbo_die_node *limbo_die_list;
/* Filenames referenced by this compilation unit. */
-static struct file_table file_table;
-
-/* Local pointer to the name of the main input file. Initialized in
- dwarf2out_init. */
-static const char *primary_filename;
+static GTY(()) varray_type file_table;
+static GTY(()) varray_type file_table_emitted;
+static GTY(()) size_t file_table_last_lookup_index;
/* A pointer to the base of a table of references to DIE's that describe
declarations. The table is indexed by DECL_UID() which is a unique
number identifying each decl. */
-static dw_die_ref *decl_die_table;
+static GTY((length ("decl_die_table_allocated"))) dw_die_ref *decl_die_table;
/* Number of elements currently allocated for the decl_die_table. */
-static unsigned decl_die_table_allocated;
+static GTY(()) unsigned decl_die_table_allocated;
/* Number of elements in decl_die_table currently in use. */
-static unsigned decl_die_table_in_use;
+static GTY(()) unsigned decl_die_table_in_use;
/* Size (in elements) of increments by which we may expand the
decl_die_table. */
@@ -3407,13 +3487,14 @@ static unsigned decl_die_table_in_use;
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
children DIE's, and list of attribute/value pairs. */
-static dw_die_ref *abbrev_die_table;
+static GTY((length ("abbrev_die_table_allocated")))
+ dw_die_ref *abbrev_die_table;
/* Number of elements currently allocated for abbrev_die_table. */
-static unsigned abbrev_die_table_allocated;
+static GTY(()) unsigned abbrev_die_table_allocated;
/* Number of elements in type_die_table currently in use. */
-static unsigned abbrev_die_table_in_use;
+static GTY(()) unsigned abbrev_die_table_in_use;
/* Size (in elements) of increments by which we may expand the
abbrev_die_table. */
@@ -3421,23 +3502,25 @@ static unsigned abbrev_die_table_in_use;
/* A pointer to the base of a table that contains line information
for each source code line in .text in the compilation unit. */
-static dw_line_info_ref line_info_table;
+static GTY((length ("line_info_table_allocated")))
+ dw_line_info_ref line_info_table;
/* Number of elements currently allocated for line_info_table. */
-static unsigned line_info_table_allocated;
+static GTY(()) unsigned line_info_table_allocated;
-/* Number of elements in separate_line_info_table currently in use. */
-static unsigned separate_line_info_table_in_use;
+/* Number of elements in line_info_table currently in use. */
+static GTY(()) unsigned line_info_table_in_use;
/* A pointer to the base of a table that contains line information
for each source code line outside of .text in the compilation unit. */
-static dw_separate_line_info_ref separate_line_info_table;
+static GTY ((length ("separate_line_info_table_allocated")))
+ dw_separate_line_info_ref separate_line_info_table;
/* Number of elements currently allocated for separate_line_info_table. */
-static unsigned separate_line_info_table_allocated;
+static GTY(()) unsigned separate_line_info_table_allocated;
-/* Number of elements in line_info_table currently in use. */
-static unsigned line_info_table_in_use;
+/* Number of elements in separate_line_info_table currently in use. */
+static GTY(()) unsigned separate_line_info_table_in_use;
/* Size (in elements) of increments by which we may expand the
line_info_table. */
@@ -3445,312 +3528,302 @@ static unsigned line_info_table_in_use;
/* A pointer to the base of a table that contains a list of publicly
accessible names. */
-static pubname_ref pubname_table;
+static GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table;
/* Number of elements currently allocated for pubname_table. */
-static unsigned pubname_table_allocated;
+static GTY(()) unsigned pubname_table_allocated;
/* Number of elements in pubname_table currently in use. */
-static unsigned pubname_table_in_use;
+static GTY(()) unsigned pubname_table_in_use;
/* Size (in elements) of increments by which we may expand the
pubname_table. */
#define PUBNAME_TABLE_INCREMENT 64
/* Array of dies for which we should generate .debug_arange info. */
-static dw_die_ref *arange_table;
+static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table;
/* Number of elements currently allocated for arange_table. */
-static unsigned arange_table_allocated;
+static GTY(()) unsigned arange_table_allocated;
/* Number of elements in arange_table currently in use. */
-static unsigned arange_table_in_use;
+static GTY(()) unsigned arange_table_in_use;
/* Size (in elements) of increments by which we may expand the
arange_table. */
#define ARANGE_TABLE_INCREMENT 64
/* Array of dies for which we should generate .debug_ranges info. */
-static dw_ranges_ref ranges_table;
+static GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table;
/* Number of elements currently allocated for ranges_table. */
-static unsigned ranges_table_allocated;
+static GTY(()) unsigned ranges_table_allocated;
/* Number of elements in ranges_table currently in use. */
-static unsigned ranges_table_in_use;
+static GTY(()) unsigned ranges_table_in_use;
/* Size (in elements) of increments by which we may expand the
ranges_table. */
#define RANGES_TABLE_INCREMENT 64
/* Whether we have location lists that need outputting */
-static unsigned have_location_lists;
+static GTY(()) unsigned have_location_lists;
+#ifdef DWARF2_DEBUGGING_INFO
/* Record whether the function being analyzed contains inlined functions. */
static int current_function_has_inlines;
+#endif
#if 0 && defined (MIPS_DEBUGGING_INFO)
static int comp_unit_has_inlines;
#endif
+/* Number of file tables emitted in maybe_emit_file(). */
+static GTY(()) int emitcount = 0;
+
+/* Number of internal labels generated by gen_internal_sym(). */
+static GTY(()) int label_num;
+
+#ifdef DWARF2_DEBUGGING_INFO
+
/* Forward declarations for functions defined in this file. */
-static int is_pseudo_reg PARAMS ((rtx));
-static tree type_main_variant PARAMS ((tree));
-static int is_tagged_type PARAMS ((tree));
-static const char *dwarf_tag_name PARAMS ((unsigned));
-static const char *dwarf_attr_name PARAMS ((unsigned));
-static const char *dwarf_form_name PARAMS ((unsigned));
+static int is_pseudo_reg (rtx);
+static tree type_main_variant (tree);
+static int is_tagged_type (tree);
+static const char *dwarf_tag_name (unsigned);
+static const char *dwarf_attr_name (unsigned);
+static const char *dwarf_form_name (unsigned);
#if 0
-static const char *dwarf_type_encoding_name PARAMS ((unsigned));
+static const char *dwarf_type_encoding_name (unsigned);
#endif
-static tree decl_ultimate_origin PARAMS ((tree));
-static tree block_ultimate_origin PARAMS ((tree));
-static tree decl_class_context PARAMS ((tree));
-static void add_dwarf_attr PARAMS ((dw_die_ref, dw_attr_ref));
-static inline dw_val_class AT_class PARAMS ((dw_attr_ref));
-static void add_AT_flag PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned));
-static inline unsigned AT_flag PARAMS ((dw_attr_ref));
-static void add_AT_int PARAMS ((dw_die_ref,
- enum dwarf_attribute, long));
-static inline long int AT_int PARAMS ((dw_attr_ref));
-static void add_AT_unsigned PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static inline unsigned long AT_unsigned PARAMS ((dw_attr_ref));
-static void add_AT_long_long PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long,
- unsigned long));
-static void add_AT_float PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned, long *));
-static void add_AT_string PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static inline const char *AT_string PARAMS ((dw_attr_ref));
-static int AT_string_form PARAMS ((dw_attr_ref));
-static void add_AT_die_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_die_ref));
-static inline dw_die_ref AT_ref PARAMS ((dw_attr_ref));
-static inline int AT_ref_external PARAMS ((dw_attr_ref));
-static inline void set_AT_ref_external PARAMS ((dw_attr_ref, int));
-static void add_AT_fde_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned));
-static void add_AT_loc PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_descr_ref));
-static inline dw_loc_descr_ref AT_loc PARAMS ((dw_attr_ref));
-static void add_AT_loc_list PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_list_ref));
-static inline dw_loc_list_ref AT_loc_list PARAMS ((dw_attr_ref));
-static void add_AT_addr PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- rtx));
-static inline rtx AT_addr PARAMS ((dw_attr_ref));
-static void add_AT_lbl_id PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static void add_AT_lbl_offset PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static void add_AT_offset PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static void add_AT_range_list PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static inline const char *AT_lbl PARAMS ((dw_attr_ref));
-static dw_attr_ref get_AT PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static const char *get_AT_low_pc PARAMS ((dw_die_ref));
-static const char *get_AT_hi_pc PARAMS ((dw_die_ref));
-static const char *get_AT_string PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static int get_AT_flag PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static unsigned get_AT_unsigned PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static inline dw_die_ref get_AT_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static int is_c_family PARAMS ((void));
-static int is_cxx PARAMS ((void));
-static int is_java PARAMS ((void));
-static int is_fortran PARAMS ((void));
-static void remove_AT PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static inline void free_die PARAMS ((dw_die_ref));
-static void remove_children PARAMS ((dw_die_ref));
-static void add_child_die PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref new_die PARAMS ((enum dwarf_tag, dw_die_ref,
- tree));
-static dw_die_ref lookup_type_die PARAMS ((tree));
-static void equate_type_number_to_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref lookup_decl_die PARAMS ((tree));
-static void equate_decl_number_to_die PARAMS ((tree, dw_die_ref));
-static void print_spaces PARAMS ((FILE *));
-static void print_die PARAMS ((dw_die_ref, FILE *));
-static void print_dwarf_line_table PARAMS ((FILE *));
-static void reverse_die_lists PARAMS ((dw_die_ref));
-static void reverse_all_dies PARAMS ((dw_die_ref));
-static dw_die_ref push_new_compile_unit PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref pop_compile_unit PARAMS ((dw_die_ref));
-static void loc_checksum PARAMS ((dw_loc_descr_ref,
- struct md5_ctx *));
-static void attr_checksum PARAMS ((dw_attr_ref,
- struct md5_ctx *,
- int *));
-static void die_checksum PARAMS ((dw_die_ref,
- struct md5_ctx *,
- int *));
-static int same_loc_p PARAMS ((dw_loc_descr_ref,
- dw_loc_descr_ref, int *));
-static int same_dw_val_p PARAMS ((dw_val_node *, dw_val_node *,
- int *));
-static int same_attr_p PARAMS ((dw_attr_ref, dw_attr_ref, int *));
-static int same_die_p PARAMS ((dw_die_ref, dw_die_ref, int *));
-static int same_die_p_wrap PARAMS ((dw_die_ref, dw_die_ref));
-static void compute_section_prefix PARAMS ((dw_die_ref));
-static int is_type_die PARAMS ((dw_die_ref));
-static int is_comdat_die PARAMS ((dw_die_ref));
-static int is_symbol_die PARAMS ((dw_die_ref));
-static void assign_symbol_names PARAMS ((dw_die_ref));
-static void break_out_includes PARAMS ((dw_die_ref));
-static hashval_t htab_cu_hash PARAMS ((const void *));
-static int htab_cu_eq PARAMS ((const void *, const void *));
-static void htab_cu_del PARAMS ((void *));
-static int check_duplicate_cu PARAMS ((dw_die_ref, htab_t, unsigned *));
-static void record_comdat_symbol_number PARAMS ((dw_die_ref, htab_t, unsigned));
-static void add_sibling_attributes PARAMS ((dw_die_ref));
-static void build_abbrev_table PARAMS ((dw_die_ref));
-static void output_location_lists PARAMS ((dw_die_ref));
-static int constant_size PARAMS ((long unsigned));
-static unsigned long size_of_die PARAMS ((dw_die_ref));
-static void calc_die_sizes PARAMS ((dw_die_ref));
-static void mark_dies PARAMS ((dw_die_ref));
-static void unmark_dies PARAMS ((dw_die_ref));
-static void unmark_all_dies PARAMS ((dw_die_ref));
-static unsigned long size_of_pubnames PARAMS ((void));
-static unsigned long size_of_aranges PARAMS ((void));
-static enum dwarf_form value_format PARAMS ((dw_attr_ref));
-static void output_value_format PARAMS ((dw_attr_ref));
-static void output_abbrev_section PARAMS ((void));
-static void output_die_symbol PARAMS ((dw_die_ref));
-static void output_die PARAMS ((dw_die_ref));
-static void output_compilation_unit_header PARAMS ((void));
-static void output_comp_unit PARAMS ((dw_die_ref, int));
-static const char *dwarf2_name PARAMS ((tree, int));
-static void add_pubname PARAMS ((tree, dw_die_ref));
-static void output_pubnames PARAMS ((void));
-static void add_arange PARAMS ((tree, dw_die_ref));
-static void output_aranges PARAMS ((void));
-static unsigned int add_ranges PARAMS ((tree));
-static void output_ranges PARAMS ((void));
-static void output_line_info PARAMS ((void));
-static void output_file_names PARAMS ((void));
-static dw_die_ref base_type_die PARAMS ((tree));
-static tree root_type PARAMS ((tree));
-static int is_base_type PARAMS ((tree));
-static dw_die_ref modified_type_die PARAMS ((tree, int, int, dw_die_ref));
-static int type_is_enum PARAMS ((tree));
-static unsigned int reg_number PARAMS ((rtx));
-static dw_loc_descr_ref reg_loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref int_loc_descriptor PARAMS ((HOST_WIDE_INT));
-static dw_loc_descr_ref based_loc_descr PARAMS ((unsigned, long));
-static int is_based_loc PARAMS ((rtx));
-static dw_loc_descr_ref mem_loc_descriptor PARAMS ((rtx, enum machine_mode mode));
-static dw_loc_descr_ref concat_loc_descriptor PARAMS ((rtx, rtx));
-static dw_loc_descr_ref loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref loc_descriptor_from_tree PARAMS ((tree, int));
-static HOST_WIDE_INT ceiling PARAMS ((HOST_WIDE_INT, unsigned int));
-static tree field_type PARAMS ((tree));
-static unsigned int simple_type_align_in_bits PARAMS ((tree));
-static unsigned int simple_decl_align_in_bits PARAMS ((tree));
-static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
-static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
-static void add_AT_location_description PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_descr_ref));
-static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
-static void add_const_value_attribute PARAMS ((dw_die_ref, rtx));
-static rtx rtl_for_decl_location PARAMS ((tree));
-static void add_location_or_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void tree_add_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void add_name_attribute PARAMS ((dw_die_ref, const char *));
-static void add_bound_info PARAMS ((dw_die_ref,
- enum dwarf_attribute, tree));
-static void add_subscript_info PARAMS ((dw_die_ref, tree));
-static void add_byte_size_attribute PARAMS ((dw_die_ref, tree));
-static void add_bit_offset_attribute PARAMS ((dw_die_ref, tree));
-static void add_bit_size_attribute PARAMS ((dw_die_ref, tree));
-static void add_prototyped_attribute PARAMS ((dw_die_ref, tree));
-static void add_abstract_origin_attribute PARAMS ((dw_die_ref, tree));
-static void add_pure_or_virtual_attribute PARAMS ((dw_die_ref, tree));
-static void add_src_coords_attributes PARAMS ((dw_die_ref, tree));
-static void add_name_and_src_coords_attributes PARAMS ((dw_die_ref, tree));
-static void push_decl_scope PARAMS ((tree));
-static void pop_decl_scope PARAMS ((void));
-static dw_die_ref scope_die_for PARAMS ((tree, dw_die_ref));
-static inline int local_scope_p PARAMS ((dw_die_ref));
-static inline int class_scope_p PARAMS ((dw_die_ref));
-static void add_type_attribute PARAMS ((dw_die_ref, tree, int, int,
- dw_die_ref));
-static const char *type_tag PARAMS ((tree));
-static tree member_declared_type PARAMS ((tree));
+static tree decl_ultimate_origin (tree);
+static tree block_ultimate_origin (tree);
+static tree decl_class_context (tree);
+static void add_dwarf_attr (dw_die_ref, dw_attr_ref);
+static inline enum dw_val_class AT_class (dw_attr_ref);
+static void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned);
+static inline unsigned AT_flag (dw_attr_ref);
+static void add_AT_int (dw_die_ref, enum dwarf_attribute, HOST_WIDE_INT);
+static inline HOST_WIDE_INT AT_int (dw_attr_ref);
+static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT);
+static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref);
+static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
+ unsigned long);
+static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
+ unsigned int, unsigned char *);
+static hashval_t debug_str_do_hash (const void *);
+static int debug_str_eq (const void *, const void *);
+static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
+static inline const char *AT_string (dw_attr_ref);
+static int AT_string_form (dw_attr_ref);
+static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref);
+static void add_AT_specification (dw_die_ref, dw_die_ref);
+static inline dw_die_ref AT_ref (dw_attr_ref);
+static inline int AT_ref_external (dw_attr_ref);
+static inline void set_AT_ref_external (dw_attr_ref, int);
+static void add_AT_fde_ref (dw_die_ref, enum dwarf_attribute, unsigned);
+static void add_AT_loc (dw_die_ref, enum dwarf_attribute, dw_loc_descr_ref);
+static inline dw_loc_descr_ref AT_loc (dw_attr_ref);
+static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute,
+ dw_loc_list_ref);
+static inline dw_loc_list_ref AT_loc_list (dw_attr_ref);
+static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
+static inline rtx AT_addr (dw_attr_ref);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_offset (dw_die_ref, enum dwarf_attribute,
+ unsigned HOST_WIDE_INT);
+static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
+ unsigned long);
+static inline const char *AT_lbl (dw_attr_ref);
+static dw_attr_ref get_AT (dw_die_ref, enum dwarf_attribute);
+static const char *get_AT_low_pc (dw_die_ref);
+static const char *get_AT_hi_pc (dw_die_ref);
+static const char *get_AT_string (dw_die_ref, enum dwarf_attribute);
+static int get_AT_flag (dw_die_ref, enum dwarf_attribute);
+static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute);
+static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute);
+static bool is_c_family (void);
+static bool is_cxx (void);
+static bool is_java (void);
+static bool is_fortran (void);
+static bool is_ada (void);
+static void remove_AT (dw_die_ref, enum dwarf_attribute);
+static inline void free_die (dw_die_ref);
+static void remove_children (dw_die_ref);
+static void add_child_die (dw_die_ref, dw_die_ref);
+static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
+static dw_die_ref lookup_type_die (tree);
+static void equate_type_number_to_die (tree, dw_die_ref);
+static dw_die_ref lookup_decl_die (tree);
+static void equate_decl_number_to_die (tree, dw_die_ref);
+static void print_spaces (FILE *);
+static void print_die (dw_die_ref, FILE *);
+static void print_dwarf_line_table (FILE *);
+static void reverse_die_lists (dw_die_ref);
+static void reverse_all_dies (dw_die_ref);
+static dw_die_ref push_new_compile_unit (dw_die_ref, dw_die_ref);
+static dw_die_ref pop_compile_unit (dw_die_ref);
+static void loc_checksum (dw_loc_descr_ref, struct md5_ctx *);
+static void attr_checksum (dw_attr_ref, struct md5_ctx *, int *);
+static void die_checksum (dw_die_ref, struct md5_ctx *, int *);
+static int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *);
+static int same_dw_val_p (dw_val_node *, dw_val_node *, int *);
+static int same_attr_p (dw_attr_ref, dw_attr_ref, int *);
+static int same_die_p (dw_die_ref, dw_die_ref, int *);
+static int same_die_p_wrap (dw_die_ref, dw_die_ref);
+static void compute_section_prefix (dw_die_ref);
+static int is_type_die (dw_die_ref);
+static int is_comdat_die (dw_die_ref);
+static int is_symbol_die (dw_die_ref);
+static void assign_symbol_names (dw_die_ref);
+static void break_out_includes (dw_die_ref);
+static hashval_t htab_cu_hash (const void *);
+static int htab_cu_eq (const void *, const void *);
+static void htab_cu_del (void *);
+static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *);
+static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned);
+static void add_sibling_attributes (dw_die_ref);
+static void build_abbrev_table (dw_die_ref);
+static void output_location_lists (dw_die_ref);
+static int constant_size (long unsigned);
+static unsigned long size_of_die (dw_die_ref);
+static void calc_die_sizes (dw_die_ref);
+static void mark_dies (dw_die_ref);
+static void unmark_dies (dw_die_ref);
+static void unmark_all_dies (dw_die_ref);
+static unsigned long size_of_pubnames (void);
+static unsigned long size_of_aranges (void);
+static enum dwarf_form value_format (dw_attr_ref);
+static void output_value_format (dw_attr_ref);
+static void output_abbrev_section (void);
+static void output_die_symbol (dw_die_ref);
+static void output_die (dw_die_ref);
+static void output_compilation_unit_header (void);
+static void output_comp_unit (dw_die_ref, int);
+static const char *dwarf2_name (tree, int);
+static void add_pubname (tree, dw_die_ref);
+static void output_pubnames (void);
+static void add_arange (tree, dw_die_ref);
+static void output_aranges (void);
+static unsigned int add_ranges (tree);
+static void output_ranges (void);
+static void output_line_info (void);
+static void output_file_names (void);
+static dw_die_ref base_type_die (tree);
+static tree root_type (tree);
+static int is_base_type (tree);
+static bool is_subrange_type (tree);
+static dw_die_ref subrange_type_die (tree, dw_die_ref);
+static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
+static int type_is_enum (tree);
+static unsigned int dbx_reg_number (rtx);
+static dw_loc_descr_ref reg_loc_descriptor (rtx);
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
+static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
+static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT);
+static int is_based_loc (rtx);
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref loc_descriptor (rtx);
+static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
+static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
+static tree field_type (tree);
+static unsigned int simple_type_align_in_bits (tree);
+static unsigned int simple_decl_align_in_bits (tree);
+static unsigned HOST_WIDE_INT simple_type_size_in_bits (tree);
+static HOST_WIDE_INT field_byte_offset (tree);
+static void add_AT_location_description (dw_die_ref, enum dwarf_attribute,
+ dw_loc_descr_ref);
+static void add_data_member_location_attribute (dw_die_ref, tree);
+static void add_const_value_attribute (dw_die_ref, rtx);
+static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
+static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
+static void insert_float (rtx, unsigned char *);
+static rtx rtl_for_decl_location (tree);
+static void add_location_or_const_value_attribute (dw_die_ref, tree);
+static void tree_add_const_value_attribute (dw_die_ref, tree);
+static void add_name_attribute (dw_die_ref, const char *);
+static void add_comp_dir_attribute (dw_die_ref);
+static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
+static void add_subscript_info (dw_die_ref, tree);
+static void add_byte_size_attribute (dw_die_ref, tree);
+static void add_bit_offset_attribute (dw_die_ref, tree);
+static void add_bit_size_attribute (dw_die_ref, tree);
+static void add_prototyped_attribute (dw_die_ref, tree);
+static void add_abstract_origin_attribute (dw_die_ref, tree);
+static void add_pure_or_virtual_attribute (dw_die_ref, tree);
+static void add_src_coords_attributes (dw_die_ref, tree);
+static void add_name_and_src_coords_attributes (dw_die_ref, tree);
+static void push_decl_scope (tree);
+static void pop_decl_scope (void);
+static dw_die_ref scope_die_for (tree, dw_die_ref);
+static inline int local_scope_p (dw_die_ref);
+static inline int class_or_namespace_scope_p (dw_die_ref);
+static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
+static const char *type_tag (tree);
+static tree member_declared_type (tree);
#if 0
-static const char *decl_start_label PARAMS ((tree));
+static const char *decl_start_label (tree);
#endif
-static void gen_array_type_die PARAMS ((tree, dw_die_ref));
-static void gen_set_type_die PARAMS ((tree, dw_die_ref));
+static void gen_array_type_die (tree, dw_die_ref);
+static void gen_set_type_die (tree, dw_die_ref);
#if 0
-static void gen_entry_point_die PARAMS ((tree, dw_die_ref));
+static void gen_entry_point_die (tree, dw_die_ref);
#endif
-static void gen_inlined_enumeration_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_structure_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_enumeration_type_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_formal_parameter_die PARAMS ((tree, dw_die_ref));
-static void gen_unspecified_parameters_die PARAMS ((tree, dw_die_ref));
-static void gen_formal_types_die PARAMS ((tree, dw_die_ref));
-static void gen_subprogram_die PARAMS ((tree, dw_die_ref));
-static void gen_variable_die PARAMS ((tree, dw_die_ref));
-static void gen_label_die PARAMS ((tree, dw_die_ref));
-static void gen_lexical_block_die PARAMS ((tree, dw_die_ref, int));
-static void gen_inlined_subroutine_die PARAMS ((tree, dw_die_ref, int));
-static void gen_field_die PARAMS ((tree, dw_die_ref));
-static void gen_ptr_to_mbr_type_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_compile_unit_die PARAMS ((const char *));
-static void gen_string_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inheritance_die PARAMS ((tree, dw_die_ref));
-static void gen_member_die PARAMS ((tree, dw_die_ref));
-static void gen_struct_or_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_subroutine_type_die PARAMS ((tree, dw_die_ref));
-static void gen_typedef_die PARAMS ((tree, dw_die_ref));
-static void gen_type_die PARAMS ((tree, dw_die_ref));
-static void gen_tagged_type_instantiation_die PARAMS ((tree, dw_die_ref));
-static void gen_block_die PARAMS ((tree, dw_die_ref, int));
-static void decls_for_scope PARAMS ((tree, dw_die_ref, int));
-static int is_redundant_typedef PARAMS ((tree));
-static void gen_decl_die PARAMS ((tree, dw_die_ref));
-static unsigned lookup_filename PARAMS ((const char *));
-static void init_file_table PARAMS ((void));
-static void retry_incomplete_types PARAMS ((void));
-static void gen_type_die_for_member PARAMS ((tree, tree, dw_die_ref));
-static void splice_child_die PARAMS ((dw_die_ref, dw_die_ref));
-static int file_info_cmp PARAMS ((const void *, const void *));
-static dw_loc_list_ref new_loc_list PARAMS ((dw_loc_descr_ref,
- const char *, const char *,
- const char *, unsigned));
-static void add_loc_descr_to_loc_list PARAMS ((dw_loc_list_ref *,
- dw_loc_descr_ref,
- const char *, const char *, const char *));
-static void output_loc_list PARAMS ((dw_loc_list_ref));
-static char *gen_internal_sym PARAMS ((const char *));
-static void mark_limbo_die_list PARAMS ((void *));
+static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
+static void gen_inlined_structure_type_die (tree, dw_die_ref);
+static void gen_inlined_union_type_die (tree, dw_die_ref);
+static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
+static void gen_unspecified_parameters_die (tree, dw_die_ref);
+static void gen_formal_types_die (tree, dw_die_ref);
+static void gen_subprogram_die (tree, dw_die_ref);
+static void gen_variable_die (tree, dw_die_ref);
+static void gen_label_die (tree, dw_die_ref);
+static void gen_lexical_block_die (tree, dw_die_ref, int);
+static void gen_inlined_subroutine_die (tree, dw_die_ref, int);
+static void gen_field_die (tree, dw_die_ref);
+static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
+static dw_die_ref gen_compile_unit_die (const char *);
+static void gen_string_type_die (tree, dw_die_ref);
+static void gen_inheritance_die (tree, tree, dw_die_ref);
+static void gen_member_die (tree, dw_die_ref);
+static void gen_struct_or_union_type_die (tree, dw_die_ref);
+static void gen_subroutine_type_die (tree, dw_die_ref);
+static void gen_typedef_die (tree, dw_die_ref);
+static void gen_type_die (tree, dw_die_ref);
+static void gen_tagged_type_instantiation_die (tree, dw_die_ref);
+static void gen_block_die (tree, dw_die_ref, int);
+static void decls_for_scope (tree, dw_die_ref, int);
+static int is_redundant_typedef (tree);
+static void gen_namespace_die (tree);
+static void gen_decl_die (tree, dw_die_ref);
+static dw_die_ref force_namespace_die (tree);
+static dw_die_ref setup_namespace_context (tree, dw_die_ref);
+static void declare_in_namespace (tree, dw_die_ref);
+static unsigned lookup_filename (const char *);
+static void init_file_table (void);
+static void retry_incomplete_types (void);
+static void gen_type_die_for_member (tree, tree, dw_die_ref);
+static void splice_child_die (dw_die_ref, dw_die_ref);
+static int file_info_cmp (const void *, const void *);
+static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
+ const char *, const char *, unsigned);
+static void add_loc_descr_to_loc_list (dw_loc_list_ref *, dw_loc_descr_ref,
+ const char *, const char *,
+ const char *);
+static void output_loc_list (dw_loc_list_ref);
+static char *gen_internal_sym (const char *);
+
+static void prune_unmark_dies (dw_die_ref);
+static void prune_unused_types_mark (dw_die_ref, int);
+static void prune_unused_types_walk (dw_die_ref);
+static void prune_unused_types_walk_attribs (dw_die_ref);
+static void prune_unused_types_prune (dw_die_ref);
+static void prune_unused_types (void);
+static int maybe_emit_file (int);
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_INFO_SECTION
@@ -3787,12 +3860,10 @@ static void mark_limbo_die_list PARAMS ((void *));
#endif
/* Section flags for .debug_str section. */
-#ifdef HAVE_GAS_SHF_MERGE
#define DEBUG_STR_SECTION_FLAGS \
- (SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1)
-#else
-#define DEBUG_STR_SECTION_FLAGS SECTION_DEBUG
-#endif
+ (HAVE_GAS_SHF_MERGE && flag_merge_constants \
+ ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \
+ : SECTION_DEBUG)
/* Labels we insert at beginning sections we can reference instead of
the section names themselves. */
@@ -3821,7 +3892,7 @@ static void mark_limbo_die_list PARAMS ((void *));
/* Definitions of defaults for formats and names of various special
(artificial) labels which may be generated within this file (when the -g
- options is used and DWARF_DEBUGGING_INFO is in effect.
+ options is used and DWARF2_DEBUGGING_INFO is in effect.
If necessary, these may be overridden from within the tm.h file, but
typically, overriding these defaults is unnecessary. */
@@ -3853,11 +3924,10 @@ static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
/* We allow a language front-end to designate a function that is to be
called to "demangle" any name before it it put into a DIE. */
-static const char *(*demangle_name_func) PARAMS ((const char *));
+static const char *(*demangle_name_func) (const char *);
void
-dwarf2out_set_demangle_name_func (func)
- const char *(*func) PARAMS ((const char *));
+dwarf2out_set_demangle_name_func (const char *(*func) (const char *))
{
demangle_name_func = func;
}
@@ -3865,8 +3935,7 @@ dwarf2out_set_demangle_name_func (func)
/* Test if rtl node points to a pseudo register. */
static inline int
-is_pseudo_reg (rtl)
- rtx rtl;
+is_pseudo_reg (rtx rtl)
{
return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
|| (GET_CODE (rtl) == SUBREG
@@ -3877,8 +3946,7 @@ is_pseudo_reg (rtl)
removed. */
static inline tree
-type_main_variant (type)
- tree type;
+type_main_variant (tree type)
{
type = TYPE_MAIN_VARIANT (type);
@@ -3897,8 +3965,7 @@ type_main_variant (type)
/* Return nonzero if the given type node represents a tagged type. */
static inline int
-is_tagged_type (type)
- tree type;
+is_tagged_type (tree type)
{
enum tree_code code = TREE_CODE (type);
@@ -3909,8 +3976,7 @@ is_tagged_type (type)
/* Convert a DIE tag into its string name. */
static const char *
-dwarf_tag_name (tag)
- unsigned tag;
+dwarf_tag_name (unsigned int tag)
{
switch (tag)
{
@@ -3992,6 +4058,8 @@ dwarf_tag_name (tag)
return "DW_TAG_namelist";
case DW_TAG_namelist_item:
return "DW_TAG_namelist_item";
+ case DW_TAG_namespace:
+ return "DW_TAG_namespace";
case DW_TAG_packed_type:
return "DW_TAG_packed_type";
case DW_TAG_subprogram:
@@ -4030,8 +4098,7 @@ dwarf_tag_name (tag)
/* Convert a DWARF attribute code into its string name. */
static const char *
-dwarf_attr_name (attr)
- unsigned attr;
+dwarf_attr_name (unsigned int attr)
{
switch (attr)
{
@@ -4234,8 +4301,7 @@ dwarf_attr_name (attr)
/* Convert a DWARF value form code into its string name. */
static const char *
-dwarf_form_name (form)
- unsigned form;
+dwarf_form_name (unsigned int form)
{
switch (form)
{
@@ -4290,8 +4356,7 @@ dwarf_form_name (form)
#if 0
static const char *
-dwarf_type_encoding_name (enc)
- unsigned enc;
+dwarf_type_encoding_name (unsigned enc)
{
switch (enc)
{
@@ -4324,8 +4389,7 @@ dwarf_type_encoding_name (enc)
given block. */
static tree
-decl_ultimate_origin (decl)
- tree decl;
+decl_ultimate_origin (tree decl)
{
/* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
nodes in the function to point to themselves; ignore that if
@@ -4350,8 +4414,7 @@ decl_ultimate_origin (decl)
given block. */
static tree
-block_ultimate_origin (block)
- tree block;
+block_ultimate_origin (tree block)
{
tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
@@ -4385,8 +4448,7 @@ block_ultimate_origin (block)
parameter. */
static tree
-decl_class_context (decl)
- tree decl;
+decl_class_context (tree decl)
{
tree context = NULL_TREE;
@@ -4406,9 +4468,7 @@ decl_class_context (decl)
addition order, and correct that in reverse_all_dies. */
static inline void
-add_dwarf_attr (die, attr)
- dw_die_ref die;
- dw_attr_ref attr;
+add_dwarf_attr (dw_die_ref die, dw_attr_ref attr)
{
if (die != NULL && attr != NULL)
{
@@ -4417,9 +4477,8 @@ add_dwarf_attr (die, attr)
}
}
-static inline dw_val_class
-AT_class (a)
- dw_attr_ref a;
+static inline enum dw_val_class
+AT_class (dw_attr_ref a)
{
return a->dw_attr_val.val_class;
}
@@ -4427,12 +4486,9 @@ AT_class (a)
/* Add a flag value attribute to a DIE. */
static inline void
-add_AT_flag (die, attr_kind, flag)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned flag;
+add_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int flag)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4442,8 +4498,7 @@ add_AT_flag (die, attr_kind, flag)
}
static inline unsigned
-AT_flag (a)
- dw_attr_ref a;
+AT_flag (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_flag)
return a->dw_attr_val.v.val_flag;
@@ -4454,12 +4509,9 @@ AT_flag (a)
/* Add a signed integer attribute value to a DIE. */
static inline void
-add_AT_int (die, attr_kind, int_val)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- long int int_val;
+add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, HOST_WIDE_INT int_val)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4468,9 +4520,8 @@ add_AT_int (die, attr_kind, int_val)
add_dwarf_attr (die, attr);
}
-static inline long int
-AT_int (a)
- dw_attr_ref a;
+static inline HOST_WIDE_INT
+AT_int (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_const)
return a->dw_attr_val.v.val_int;
@@ -4481,12 +4532,10 @@ AT_int (a)
/* Add an unsigned integer attribute value to a DIE. */
static inline void
-add_AT_unsigned (die, attr_kind, unsigned_val)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long unsigned_val;
+add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned HOST_WIDE_INT unsigned_val)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4495,9 +4544,8 @@ add_AT_unsigned (die, attr_kind, unsigned_val)
add_dwarf_attr (die, attr);
}
-static inline unsigned long
-AT_unsigned (a)
- dw_attr_ref a;
+static inline unsigned HOST_WIDE_INT
+AT_unsigned (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_unsigned_const)
return a->dw_attr_val.v.val_unsigned;
@@ -4508,13 +4556,10 @@ AT_unsigned (a)
/* Add an unsigned double integer attribute value to a DIE. */
static inline void
-add_AT_long_long (die, attr_kind, val_hi, val_low)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long val_hi;
- unsigned long val_low;
+add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind,
+ long unsigned int val_hi, long unsigned int val_low)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4527,42 +4572,54 @@ add_AT_long_long (die, attr_kind, val_hi, val_low)
/* Add a floating point attribute value to a DIE and return it. */
static inline void
-add_AT_float (die, attr_kind, length, array)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned length;
- long *array;
+add_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned int length, unsigned int elt_size, unsigned char *array)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
- attr->dw_attr_val.val_class = dw_val_class_float;
- attr->dw_attr_val.v.val_float.length = length;
- attr->dw_attr_val.v.val_float.array = array;
+ attr->dw_attr_val.val_class = dw_val_class_vec;
+ attr->dw_attr_val.v.val_vec.length = length;
+ attr->dw_attr_val.v.val_vec.elt_size = elt_size;
+ attr->dw_attr_val.v.val_vec.array = array;
add_dwarf_attr (die, attr);
}
+/* Hash and equality functions for debug_str_hash. */
+
+static hashval_t
+debug_str_do_hash (const void *x)
+{
+ return htab_hash_string (((const struct indirect_string_node *)x)->str);
+}
+
+static int
+debug_str_eq (const void *x1, const void *x2)
+{
+ return strcmp ((((const struct indirect_string_node *)x1)->str),
+ (const char *)x2) == 0;
+}
+
/* Add a string attribute value to a DIE. */
static inline void
-add_AT_string (die, attr_kind, str)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *str;
+add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
struct indirect_string_node *node;
+ void **slot;
if (! debug_str_hash)
- {
- debug_str_hash = ht_create (10);
- debug_str_hash->alloc_node = indirect_string_alloc;
- }
-
- node = (struct indirect_string_node *)
- ht_lookup (debug_str_hash, (const unsigned char *) str,
- strlen (str), HT_ALLOC);
+ debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
+ debug_str_eq, NULL);
+
+ slot = htab_find_slot_with_hash (debug_str_hash, str,
+ htab_hash_string (str), INSERT);
+ if (*slot == NULL)
+ *slot = ggc_alloc_cleared (sizeof (struct indirect_string_node));
+ node = (struct indirect_string_node *) *slot;
+ node->str = ggc_strdup (str);
node->refcount++;
attr->dw_attr_next = NULL;
@@ -4573,11 +4630,10 @@ add_AT_string (die, attr_kind, str)
}
static inline const char *
-AT_string (a)
- dw_attr_ref a;
+AT_string (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_str)
- return (const char *) HT_STR (&a->dw_attr_val.v.val_str->id);
+ return a->dw_attr_val.v.val_str->str;
abort ();
}
@@ -4586,21 +4642,19 @@ AT_string (a)
or out-of-line in .debug_str section. */
static int
-AT_string_form (a)
- dw_attr_ref a;
+AT_string_form (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_str)
{
struct indirect_string_node *node;
unsigned int len;
- extern int const_labelno;
char label[32];
node = a->dw_attr_val.v.val_str;
if (node->form)
return node->form;
- len = HT_LEN (&node->id) + 1;
+ len = strlen (node->str) + 1;
/* If the string is shorter or equal to the size of the reference, it is
always better to put it inline. */
@@ -4614,8 +4668,8 @@ AT_string_form (a)
&& (len - DWARF_OFFSET_SIZE) * node->refcount <= len)
return node->form = DW_FORM_string;
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
- ++const_labelno;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LASF", dw2_string_counter);
+ ++dw2_string_counter;
node->label = xstrdup (label);
return node->form = DW_FORM_strp;
@@ -4627,12 +4681,9 @@ AT_string_form (a)
/* Add a DIE reference attribute value to a DIE. */
static inline void
-add_AT_die_ref (die, attr_kind, targ_die)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_die_ref targ_die;
+add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_die)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4642,9 +4693,20 @@ add_AT_die_ref (die, attr_kind, targ_die)
add_dwarf_attr (die, attr);
}
+/* Add an AT_specification attribute to a DIE, and also make the back
+ pointer from the specification to the definition. */
+
+static inline void
+add_AT_specification (dw_die_ref die, dw_die_ref targ_die)
+{
+ add_AT_die_ref (die, DW_AT_specification, targ_die);
+ if (targ_die->die_definition)
+ abort ();
+ targ_die->die_definition = die;
+}
+
static inline dw_die_ref
-AT_ref (a)
- dw_attr_ref a;
+AT_ref (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_die_ref)
return a->dw_attr_val.v.val_die_ref.die;
@@ -4653,8 +4715,7 @@ AT_ref (a)
}
static inline int
-AT_ref_external (a)
- dw_attr_ref a;
+AT_ref_external (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_die_ref)
return a->dw_attr_val.v.val_die_ref.external;
@@ -4663,9 +4724,7 @@ AT_ref_external (a)
}
static inline void
-set_AT_ref_external (a, i)
- dw_attr_ref a;
- int i;
+set_AT_ref_external (dw_attr_ref a, int i)
{
if (a && AT_class (a) == dw_val_class_die_ref)
a->dw_attr_val.v.val_die_ref.external = i;
@@ -4676,12 +4735,9 @@ set_AT_ref_external (a, i)
/* Add an FDE reference attribute value to a DIE. */
static inline void
-add_AT_fde_ref (die, attr_kind, targ_fde)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned targ_fde;
+add_AT_fde_ref (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int targ_fde)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4693,12 +4749,9 @@ add_AT_fde_ref (die, attr_kind, targ_fde)
/* Add a location description attribute value to a DIE. */
static inline void
-add_AT_loc (die, attr_kind, loc)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_descr_ref loc;
+add_AT_loc (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_descr_ref loc)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4708,8 +4761,7 @@ add_AT_loc (die, attr_kind, loc)
}
static inline dw_loc_descr_ref
-AT_loc (a)
- dw_attr_ref a;
+AT_loc (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_loc)
return a->dw_attr_val.v.val_loc;
@@ -4718,12 +4770,9 @@ AT_loc (a)
}
static inline void
-add_AT_loc_list (die, attr_kind, loc_list)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_list_ref loc_list;
+add_AT_loc_list (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref loc_list)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4734,8 +4783,7 @@ add_AT_loc_list (die, attr_kind, loc_list)
}
static inline dw_loc_list_ref
-AT_loc_list (a)
- dw_attr_ref a;
+AT_loc_list (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_loc_list)
return a->dw_attr_val.v.val_loc_list;
@@ -4746,12 +4794,9 @@ AT_loc_list (a)
/* Add an address constant attribute value to a DIE. */
static inline void
-add_AT_addr (die, attr_kind, addr)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- rtx addr;
+add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4761,8 +4806,7 @@ add_AT_addr (die, attr_kind, addr)
}
static inline rtx
-AT_addr (a)
- dw_attr_ref a;
+AT_addr (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_addr)
return a->dw_attr_val.v.val_addr;
@@ -4773,12 +4817,9 @@ AT_addr (a)
/* Add a label identifier attribute value to a DIE. */
static inline void
-add_AT_lbl_id (die, attr_kind, lbl_id)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *lbl_id;
+add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, const char *lbl_id)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4790,12 +4831,9 @@ add_AT_lbl_id (die, attr_kind, lbl_id)
/* Add a section offset attribute value to a DIE. */
static inline void
-add_AT_lbl_offset (die, attr_kind, label)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *label;
+add_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *label)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4807,12 +4845,10 @@ add_AT_lbl_offset (die, attr_kind, label)
/* Add an offset attribute value to a DIE. */
static inline void
-add_AT_offset (die, attr_kind, offset)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long offset;
+add_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned HOST_WIDE_INT offset)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4824,12 +4860,10 @@ add_AT_offset (die, attr_kind, offset)
/* Add an range_list attribute value to a DIE. */
static void
-add_AT_range_list (die, attr_kind, offset)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long offset;
+add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind,
+ long unsigned int offset)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4839,8 +4873,7 @@ add_AT_range_list (die, attr_kind, offset)
}
static inline const char *
-AT_lbl (a)
- dw_attr_ref a;
+AT_lbl (dw_attr_ref a)
{
if (a && (AT_class (a) == dw_val_class_lbl_id
|| AT_class (a) == dw_val_class_lbl_offset))
@@ -4851,10 +4884,8 @@ AT_lbl (a)
/* Get the attribute of type attr_kind. */
-static inline dw_attr_ref
-get_AT (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+static dw_attr_ref
+get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a;
dw_die_ref spec = NULL;
@@ -4880,8 +4911,7 @@ get_AT (die, attr_kind)
cannot be represented as an assembler label identifier. */
static inline const char *
-get_AT_low_pc (die)
- dw_die_ref die;
+get_AT_low_pc (dw_die_ref die)
{
dw_attr_ref a = get_AT (die, DW_AT_low_pc);
@@ -4893,8 +4923,7 @@ get_AT_low_pc (die)
cannot be represented as an assembler label identifier. */
static inline const char *
-get_AT_hi_pc (die)
- dw_die_ref die;
+get_AT_hi_pc (dw_die_ref die)
{
dw_attr_ref a = get_AT (die, DW_AT_high_pc);
@@ -4905,9 +4934,7 @@ get_AT_hi_pc (die)
NULL if it is not present. */
static inline const char *
-get_AT_string (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4918,9 +4945,7 @@ get_AT_string (die, attr_kind)
if it is not present. */
static inline int
-get_AT_flag (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4931,9 +4956,7 @@ get_AT_flag (die, attr_kind)
if it is not present. */
static inline unsigned
-get_AT_unsigned (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4941,83 +4964,78 @@ get_AT_unsigned (die, attr_kind)
}
static inline dw_die_ref
-get_AT_ref (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_ref (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
return a ? AT_ref (a) : NULL;
}
-static inline int
-is_c_family ()
+/* Return TRUE if the language is C or C++. */
+
+static inline bool
+is_c_family (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
return (lang == DW_LANG_C || lang == DW_LANG_C89
|| lang == DW_LANG_C_plus_plus);
}
-static inline int
-is_cxx ()
+/* Return TRUE if the language is C++. */
+
+static inline bool
+is_cxx (void)
{
return (get_AT_unsigned (comp_unit_die, DW_AT_language)
== DW_LANG_C_plus_plus);
}
-static inline int
-is_fortran ()
+/* Return TRUE if the language is Fortran. */
+
+static inline bool
+is_fortran (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- return (lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90);
+ return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90;
}
-static inline int
-is_java ()
+/* Return TRUE if the language is Java. */
+
+static inline bool
+is_java (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- return (lang == DW_LANG_Java);
+ return lang == DW_LANG_Java;
}
-/* Free up the memory used by A. */
+/* Return TRUE if the language is Ada. */
-static inline void free_AT PARAMS ((dw_attr_ref));
-static inline void
-free_AT (a)
- dw_attr_ref a;
+static inline bool
+is_ada (void)
{
- switch (AT_class (a))
- {
- case dw_val_class_str:
- if (a->dw_attr_val.v.val_str->refcount)
- a->dw_attr_val.v.val_str->refcount--;
- break;
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- case dw_val_class_lbl_id:
- case dw_val_class_lbl_offset:
- free (a->dw_attr_val.v.val_lbl_id);
- break;
-
- case dw_val_class_float:
- free (a->dw_attr_val.v.val_float.array);
- break;
+ return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
+}
- default:
- break;
- }
+/* Free up the memory used by A. */
- free (a);
+static inline void free_AT (dw_attr_ref);
+static inline void
+free_AT (dw_attr_ref a)
+{
+ if (AT_class (a) == dw_val_class_str)
+ if (a->dw_attr_val.v.val_str->refcount)
+ a->dw_attr_val.v.val_str->refcount--;
}
/* Remove the specified attribute if present. */
static void
-remove_AT (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref *p;
dw_attr_ref removed = NULL;
@@ -5040,18 +5058,15 @@ remove_AT (die, attr_kind)
/* Free up the memory used by DIE. */
static inline void
-free_die (die)
- dw_die_ref die;
+free_die (dw_die_ref die)
{
remove_children (die);
- free (die);
}
/* Discard the children of this DIE. */
static void
-remove_children (die)
- dw_die_ref die;
+remove_children (dw_die_ref die)
{
dw_die_ref child_die = die->die_child;
@@ -5080,9 +5095,7 @@ remove_children (die)
addition order, and correct that in reverse_all_dies. */
static inline void
-add_child_die (die, child_die)
- dw_die_ref die;
- dw_die_ref child_die;
+add_child_die (dw_die_ref die, dw_die_ref child_die)
{
if (die != NULL && child_die != NULL)
{
@@ -5099,8 +5112,7 @@ add_child_die (die, child_die)
is the specification, to the front of PARENT's list of children. */
static void
-splice_child_die (parent, child)
- dw_die_ref parent, child;
+splice_child_die (dw_die_ref parent, dw_die_ref child)
{
dw_die_ref *p;
@@ -5125,6 +5137,7 @@ splice_child_die (parent, child)
break;
}
+ child->die_parent = parent;
child->die_sib = parent->die_child;
parent->die_child = child;
}
@@ -5132,12 +5145,9 @@ splice_child_die (parent, child)
/* Return a pointer to a newly created DIE node. */
static inline dw_die_ref
-new_die (tag_value, parent_die, t)
- enum dwarf_tag tag_value;
- dw_die_ref parent_die;
- tree t;
+new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
{
- dw_die_ref die = (dw_die_ref) xcalloc (1, sizeof (die_node));
+ dw_die_ref die = ggc_alloc_cleared (sizeof (die_node));
die->die_tag = tag_value;
@@ -5147,7 +5157,7 @@ new_die (tag_value, parent_die, t)
{
limbo_die_node *limbo_node;
- limbo_node = (limbo_die_node *) xmalloc (sizeof (limbo_die_node));
+ limbo_node = ggc_alloc_cleared (sizeof (limbo_die_node));
limbo_node->die = die;
limbo_node->created_for = t;
limbo_node->next = limbo_die_list;
@@ -5160,8 +5170,7 @@ new_die (tag_value, parent_die, t)
/* Return the DIE associated with the given type specifier. */
static inline dw_die_ref
-lookup_type_die (type)
- tree type;
+lookup_type_die (tree type)
{
return TYPE_SYMTAB_DIE (type);
}
@@ -5169,9 +5178,7 @@ lookup_type_die (type)
/* Equate a DIE to a given type specifier. */
static inline void
-equate_type_number_to_die (type, type_die)
- tree type;
- dw_die_ref type_die;
+equate_type_number_to_die (tree type, dw_die_ref type_die)
{
TYPE_SYMTAB_DIE (type) = type_die;
}
@@ -5179,8 +5186,7 @@ equate_type_number_to_die (type, type_die)
/* Return the DIE associated with a given declaration. */
static inline dw_die_ref
-lookup_decl_die (decl)
- tree decl;
+lookup_decl_die (tree decl)
{
unsigned decl_id = DECL_UID (decl);
@@ -5190,9 +5196,7 @@ lookup_decl_die (decl)
/* Equate a DIE to a particular declaration. */
static void
-equate_decl_number_to_die (decl, decl_die)
- tree decl;
- dw_die_ref decl_die;
+equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
{
unsigned int decl_id = DECL_UID (decl);
unsigned int num_allocated;
@@ -5204,11 +5208,10 @@ equate_decl_number_to_die (decl, decl_die)
/ DECL_DIE_TABLE_INCREMENT)
* DECL_DIE_TABLE_INCREMENT;
- decl_die_table
- = (dw_die_ref *) xrealloc (decl_die_table,
- sizeof (dw_die_ref) * num_allocated);
+ decl_die_table = ggc_realloc (decl_die_table,
+ sizeof (dw_die_ref) * num_allocated);
- memset ((char *) &decl_die_table[decl_die_table_allocated], 0,
+ memset (&decl_die_table[decl_die_table_allocated], 0,
(num_allocated - decl_die_table_allocated) * sizeof (dw_die_ref));
decl_die_table_allocated = num_allocated;
}
@@ -5227,8 +5230,7 @@ static int print_indent;
/* Indent the line the number of spaces given by print_indent. */
static inline void
-print_spaces (outfile)
- FILE *outfile;
+print_spaces (FILE *outfile)
{
fprintf (outfile, "%*s", print_indent, "");
}
@@ -5237,9 +5239,7 @@ print_spaces (outfile)
This routine is a debugging aid only. */
static void
-print_die (die, outfile)
- dw_die_ref die;
- FILE *outfile;
+print_die (dw_die_ref die, FILE *outfile)
{
dw_attr_ref a;
dw_die_ref c;
@@ -5275,18 +5275,18 @@ print_die (die, outfile)
fprintf (outfile, "range list");
break;
case dw_val_class_const:
- fprintf (outfile, "%ld", AT_int (a));
+ fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a));
break;
case dw_val_class_unsigned_const:
- fprintf (outfile, "%lu", AT_unsigned (a));
+ fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a));
break;
case dw_val_class_long_long:
fprintf (outfile, "constant (%lu,%lu)",
a->dw_attr_val.v.val_long_long.hi,
a->dw_attr_val.v.val_long_long.low);
break;
- case dw_val_class_float:
- fprintf (outfile, "floating-point constant");
+ case dw_val_class_vec:
+ fprintf (outfile, "floating-point or vector constant");
break;
case dw_val_class_flag:
fprintf (outfile, "%u", AT_flag (a));
@@ -5335,8 +5335,7 @@ print_die (die, outfile)
This routine is a debugging aid only. */
static void
-print_dwarf_line_table (outfile)
- FILE *outfile;
+print_dwarf_line_table (FILE *outfile)
{
unsigned i;
dw_line_info_ref line_info;
@@ -5346,7 +5345,8 @@ print_dwarf_line_table (outfile)
{
line_info = &line_info_table[i];
fprintf (outfile, "%5d: ", i);
- fprintf (outfile, "%-20s", file_table.table[line_info->dw_file_num]);
+ fprintf (outfile, "%-20s",
+ VARRAY_CHAR_PTR (file_table, line_info->dw_file_num));
fprintf (outfile, "%6ld", line_info->dw_line_num);
fprintf (outfile, "\n");
}
@@ -5357,8 +5357,7 @@ print_dwarf_line_table (outfile)
/* Print the information collected for a given DIE. */
void
-debug_dwarf_die (die)
- dw_die_ref die;
+debug_dwarf_die (dw_die_ref die)
{
print_die (die, stderr);
}
@@ -5367,7 +5366,7 @@ debug_dwarf_die (die)
This routine is a debugging aid only. */
void
-debug_dwarf ()
+debug_dwarf (void)
{
print_indent = 0;
print_die (comp_unit_die, stderr);
@@ -5380,8 +5379,7 @@ debug_dwarf ()
they are in order of addition. */
static void
-reverse_die_lists (die)
- dw_die_ref die;
+reverse_die_lists (dw_die_ref die)
{
dw_die_ref c, cp, cn;
dw_attr_ref a, ap, an;
@@ -5412,8 +5410,7 @@ reverse_die_lists (die)
recursively reverse all the dies. This is that routine. */
static void
-reverse_all_dies (die)
- dw_die_ref die;
+reverse_all_dies (dw_die_ref die)
{
dw_die_ref c;
@@ -5428,8 +5425,7 @@ reverse_all_dies (die)
DIE that marks the start of the DIEs for this include file. */
static dw_die_ref
-push_new_compile_unit (old_unit, bincl_die)
- dw_die_ref old_unit, bincl_die;
+push_new_compile_unit (dw_die_ref old_unit, dw_die_ref bincl_die)
{
const char *filename = get_AT_string (bincl_die, DW_AT_name);
dw_die_ref new_unit = gen_compile_unit_die (filename);
@@ -5441,8 +5437,7 @@ push_new_compile_unit (old_unit, bincl_die)
/* Close an include-file CU and reopen the enclosing one. */
static dw_die_ref
-pop_compile_unit (old_unit)
- dw_die_ref old_unit;
+pop_compile_unit (dw_die_ref old_unit)
{
dw_die_ref new_unit = old_unit->die_sib;
@@ -5456,9 +5451,7 @@ pop_compile_unit (old_unit)
/* Calculate the checksum of a location expression. */
static inline void
-loc_checksum (loc, ctx)
- dw_loc_descr_ref loc;
- struct md5_ctx *ctx;
+loc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx)
{
CHECKSUM (loc->dw_loc_opc);
CHECKSUM (loc->dw_loc_oprnd1);
@@ -5468,10 +5461,7 @@ loc_checksum (loc, ctx)
/* Calculate the checksum of an attribute. */
static void
-attr_checksum (at, ctx, mark)
- dw_attr_ref at;
- struct md5_ctx *ctx;
- int *mark;
+attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
{
dw_loc_descr_ref loc;
rtx r;
@@ -5496,8 +5486,8 @@ attr_checksum (at, ctx, mark)
case dw_val_class_long_long:
CHECKSUM (at->dw_attr_val.v.val_long_long);
break;
- case dw_val_class_float:
- CHECKSUM (at->dw_attr_val.v.val_float);
+ case dw_val_class_vec:
+ CHECKSUM (at->dw_attr_val.v.val_vec);
break;
case dw_val_class_flag:
CHECKSUM (at->dw_attr_val.v.val_flag);
@@ -5545,10 +5535,7 @@ attr_checksum (at, ctx, mark)
/* Calculate the checksum of a DIE. */
static void
-die_checksum (die, ctx, mark)
- dw_die_ref die;
- struct md5_ctx *ctx;
- int *mark;
+die_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark)
{
dw_die_ref c;
dw_attr_ref a;
@@ -5575,10 +5562,7 @@ die_checksum (die, ctx, mark)
/* Do the location expressions look same? */
static inline int
-same_loc_p (loc1, loc2, mark)
- dw_loc_descr_ref loc1;
- dw_loc_descr_ref loc2;
- int *mark;
+same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark)
{
return loc1->dw_loc_opc == loc2->dw_loc_opc
&& same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
@@ -5587,14 +5571,10 @@ same_loc_p (loc1, loc2, mark)
/* Do the values look the same? */
static int
-same_dw_val_p (v1, v2, mark)
- dw_val_node *v1;
- dw_val_node *v2;
- int *mark;
+same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark)
{
dw_loc_descr_ref loc1, loc2;
rtx r1, r2;
- unsigned i;
if (v1->val_class != v2->val_class)
return 0;
@@ -5607,19 +5587,19 @@ same_dw_val_p (v1, v2, mark)
return v1->v.val_unsigned == v2->v.val_unsigned;
case dw_val_class_long_long:
return v1->v.val_long_long.hi == v2->v.val_long_long.hi
- && v1->v.val_long_long.low == v2->v.val_long_long.low;
- case dw_val_class_float:
- if (v1->v.val_float.length != v2->v.val_float.length)
+ && v1->v.val_long_long.low == v2->v.val_long_long.low;
+ case dw_val_class_vec:
+ if (v1->v.val_vec.length != v2->v.val_vec.length
+ || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size)
+ return 0;
+ if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array,
+ v1->v.val_vec.length * v1->v.val_vec.elt_size))
return 0;
- for (i = 0; i < v1->v.val_float.length; i++)
- if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
- return 0;
return 1;
case dw_val_class_flag:
return v1->v.val_flag == v2->v.val_flag;
case dw_val_class_str:
- return !strcmp((const char *) HT_STR (&v1->v.val_str->id),
- (const char *) HT_STR (&v2->v.val_str->id));
+ return !strcmp(v1->v.val_str->str, v2->v.val_str->str);
case dw_val_class_addr:
r1 = v1->v.val_addr;
@@ -5662,10 +5642,7 @@ same_dw_val_p (v1, v2, mark)
/* Do the attributes look the same? */
static int
-same_attr_p (at1, at2, mark)
- dw_attr_ref at1;
- dw_attr_ref at2;
- int *mark;
+same_attr_p (dw_attr_ref at1, dw_attr_ref at2, int *mark)
{
if (at1->dw_attr != at2->dw_attr)
return 0;
@@ -5683,10 +5660,7 @@ same_attr_p (at1, at2, mark)
/* Do the dies look the same? */
static int
-same_die_p (die1, die2, mark)
- dw_die_ref die1;
- dw_die_ref die2;
- int *mark;
+same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark)
{
dw_die_ref c1, c2;
dw_attr_ref a1, a2;
@@ -5721,9 +5695,7 @@ same_die_p (die1, die2, mark)
/* Do the dies look the same? Wrapper around same_die_p. */
static int
-same_die_p_wrap (die1, die2)
- dw_die_ref die1;
- dw_die_ref die2;
+same_die_p_wrap (dw_die_ref die1, dw_die_ref die2)
{
int mark = 0;
int ret = same_die_p (die1, die2, &mark);
@@ -5745,12 +5717,11 @@ static unsigned int comdat_symbol_number;
children, and set comdat_symbol_id accordingly. */
static void
-compute_section_prefix (unit_die)
- dw_die_ref unit_die;
+compute_section_prefix (dw_die_ref unit_die)
{
const char *die_name = get_AT_string (unit_die, DW_AT_name);
const char *base = die_name ? lbasename (die_name) : "anonymous";
- char *name = (char *) alloca (strlen (base) + 64);
+ char *name = alloca (strlen (base) + 64);
char *p;
int i, mark;
unsigned char checksum[16];
@@ -5782,8 +5753,7 @@ compute_section_prefix (unit_die)
/* Returns nonzero if DIE represents a type, in the sense of TYPE_P. */
static int
-is_type_die (die)
- dw_die_ref die;
+is_type_die (dw_die_ref die)
{
switch (die->die_tag)
{
@@ -5817,8 +5787,7 @@ is_type_die (die)
compilations (functions). */
static int
-is_comdat_die (c)
- dw_die_ref c;
+is_comdat_die (dw_die_ref c)
{
/* I think we want to leave base types and __vtbl_ptr_type in the main CU, as
we do for stabs. The advantage is a greater likelihood of sharing between
@@ -5845,8 +5814,7 @@ is_comdat_die (c)
compilation unit. */
static int
-is_symbol_die (c)
- dw_die_ref c;
+is_symbol_die (dw_die_ref c)
{
return (is_type_die (c)
|| (get_AT (c, DW_AT_declaration)
@@ -5854,11 +5822,9 @@ is_symbol_die (c)
}
static char *
-gen_internal_sym (prefix)
- const char *prefix;
+gen_internal_sym (const char *prefix)
{
char buf[256];
- static int label_num;
ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
return xstrdup (buf);
@@ -5867,8 +5833,7 @@ gen_internal_sym (prefix)
/* Assign symbols to all worthy DIEs under DIE. */
static void
-assign_symbol_names (die)
- dw_die_ref die;
+assign_symbol_names (dw_die_ref die)
{
dw_die_ref c;
@@ -5899,8 +5864,7 @@ struct cu_hash_table_entry
/* Routines to manipulate hash table of CUs. */
static hashval_t
-htab_cu_hash (of)
- const void *of;
+htab_cu_hash (const void *of)
{
const struct cu_hash_table_entry *entry = of;
@@ -5908,9 +5872,7 @@ htab_cu_hash (of)
}
static int
-htab_cu_eq (of1, of2)
- const void *of1;
- const void *of2;
+htab_cu_eq (const void *of1, const void *of2)
{
const struct cu_hash_table_entry *entry1 = of1;
const struct die_struct *entry2 = of2;
@@ -5919,8 +5881,7 @@ htab_cu_eq (of1, of2)
}
static void
-htab_cu_del (what)
- void *what;
+htab_cu_del (void *what)
{
struct cu_hash_table_entry *next, *entry = what;
@@ -5935,10 +5896,7 @@ htab_cu_del (what)
/* Check whether we have already seen this CU and set up SYM_NUM
accordingly. */
static int
-check_duplicate_cu (cu, htable, sym_num)
- dw_die_ref cu;
- htab_t htable;
- unsigned *sym_num;
+check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
{
struct cu_hash_table_entry dummy;
struct cu_hash_table_entry **slot, *entry, *last = &dummy;
@@ -5973,10 +5931,7 @@ check_duplicate_cu (cu, htable, sym_num)
/* Record SYM_NUM to record of CU in HTABLE. */
static void
-record_comdat_symbol_number (cu, htable, sym_num)
- dw_die_ref cu;
- htab_t htable;
- unsigned sym_num;
+record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num)
{
struct cu_hash_table_entry **slot, *entry;
@@ -5993,8 +5948,7 @@ record_comdat_symbol_number (cu, htable, sym_num)
bracketed by BINCL/EINCL. */
static void
-break_out_includes (die)
- dw_die_ref die;
+break_out_includes (dw_die_ref die)
{
dw_die_ref *ptr;
dw_die_ref unit = NULL;
@@ -6054,7 +6008,7 @@ break_out_includes (die)
if (is_dupl)
*pnode = node->next;
else
- {
+ {
pnode = &node->next;
record_comdat_symbol_number (node->die, cu_hash_table,
comdat_symbol_number);
@@ -6068,8 +6022,7 @@ break_out_includes (die)
avoid generating sibling attributes for DIE's without children. */
static void
-add_sibling_attributes (die)
- dw_die_ref die;
+add_sibling_attributes (dw_die_ref die)
{
dw_die_ref c;
@@ -6085,8 +6038,7 @@ add_sibling_attributes (die)
/* Output all location lists for the DIE and its children. */
static void
-output_location_lists (die)
- dw_die_ref die;
+output_location_lists (dw_die_ref die)
{
dw_die_ref c;
dw_attr_ref d_attr;
@@ -6106,8 +6058,7 @@ output_location_lists (die)
die are visited recursively. */
static void
-build_abbrev_table (die)
- dw_die_ref die;
+build_abbrev_table (dw_die_ref die)
{
unsigned long abbrev_id;
unsigned int n_alloc;
@@ -6158,11 +6109,10 @@ build_abbrev_table (die)
if (abbrev_die_table_in_use >= abbrev_die_table_allocated)
{
n_alloc = abbrev_die_table_allocated + ABBREV_DIE_TABLE_INCREMENT;
- abbrev_die_table
- = (dw_die_ref *) xrealloc (abbrev_die_table,
- sizeof (dw_die_ref) * n_alloc);
+ abbrev_die_table = ggc_realloc (abbrev_die_table,
+ sizeof (dw_die_ref) * n_alloc);
- memset ((char *) &abbrev_die_table[abbrev_die_table_allocated], 0,
+ memset (&abbrev_die_table[abbrev_die_table_allocated], 0,
(n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref));
abbrev_die_table_allocated = n_alloc;
}
@@ -6179,8 +6129,7 @@ build_abbrev_table (die)
/* Return the power-of-two number of bytes necessary to represent VALUE. */
static int
-constant_size (value)
- long unsigned value;
+constant_size (long unsigned int value)
{
int log;
@@ -6199,8 +6148,7 @@ constant_size (value)
.debug_info section. */
static unsigned long
-size_of_die (die)
- dw_die_ref die;
+size_of_die (dw_die_ref die)
{
unsigned long size = 0;
dw_attr_ref a;
@@ -6240,14 +6188,18 @@ size_of_die (die)
case dw_val_class_long_long:
size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */
break;
- case dw_val_class_float:
- size += 1 + a->dw_attr_val.v.val_float.length * 4; /* block */
+ case dw_val_class_vec:
+ size += 1 + (a->dw_attr_val.v.val_vec.length
+ * a->dw_attr_val.v.val_vec.elt_size); /* block */
break;
case dw_val_class_flag:
size += 1;
break;
case dw_val_class_die_ref:
- size += DWARF_OFFSET_SIZE;
+ if (AT_ref_external (a))
+ size += DWARF2_ADDR_SIZE;
+ else
+ size += DWARF_OFFSET_SIZE;
break;
case dw_val_class_fde_ref:
size += DWARF_OFFSET_SIZE;
@@ -6262,7 +6214,7 @@ size_of_die (die)
if (AT_string_form (a) == DW_FORM_strp)
size += DWARF_OFFSET_SIZE;
else
- size += HT_LEN (&a->dw_attr_val.v.val_str->id) + 1;
+ size += strlen (a->dw_attr_val.v.val_str->str) + 1;
break;
default:
abort ();
@@ -6278,8 +6230,7 @@ size_of_die (die)
die_offset field in each DIE. */
static void
-calc_die_sizes (die)
- dw_die_ref die;
+calc_die_sizes (dw_die_ref die)
{
dw_die_ref c;
@@ -6300,14 +6251,13 @@ calc_die_sizes (die)
and use that as the flag, but ran into ordering problems. */
static void
-mark_dies (die)
- dw_die_ref die;
+mark_dies (dw_die_ref die)
{
dw_die_ref c;
if (die->die_mark)
abort ();
-
+
die->die_mark = 1;
for (c = die->die_child; c; c = c->die_sib)
mark_dies (c);
@@ -6316,14 +6266,13 @@ mark_dies (die)
/* Clear the marks for a die and its children. */
static void
-unmark_dies (die)
- dw_die_ref die;
+unmark_dies (dw_die_ref die)
{
dw_die_ref c;
if (!die->die_mark)
abort ();
-
+
die->die_mark = 0;
for (c = die->die_child; c; c = c->die_sib)
unmark_dies (c);
@@ -6332,8 +6281,7 @@ unmark_dies (die)
/* Clear the marks for a die, its children and referred dies. */
static void
-unmark_all_dies (die)
- dw_die_ref die;
+unmark_all_dies (dw_die_ref die)
{
dw_die_ref c;
dw_attr_ref a;
@@ -6354,7 +6302,7 @@ unmark_all_dies (die)
compilation unit. */
static unsigned long
-size_of_pubnames ()
+size_of_pubnames (void)
{
unsigned long size;
unsigned i;
@@ -6373,7 +6321,7 @@ size_of_pubnames ()
/* Return the size of the information in the .debug_aranges section. */
static unsigned long
-size_of_aranges ()
+size_of_aranges (void)
{
unsigned long size;
@@ -6391,8 +6339,7 @@ size_of_aranges ()
/* Select the encoding of an attribute value. */
static enum dwarf_form
-value_format (a)
- dw_attr_ref a;
+value_format (dw_attr_ref a)
{
switch (a->dw_attr_val.val_class)
{
@@ -6437,7 +6384,7 @@ value_format (a)
}
case dw_val_class_long_long:
return DW_FORM_block1;
- case dw_val_class_float:
+ case dw_val_class_vec:
return DW_FORM_block1;
case dw_val_class_flag:
return DW_FORM_flag;
@@ -6463,8 +6410,7 @@ value_format (a)
/* Output the encoding of an attribute value. */
static void
-output_value_format (a)
- dw_attr_ref a;
+output_value_format (dw_attr_ref a)
{
enum dwarf_form form = value_format (a);
@@ -6475,7 +6421,7 @@ output_value_format (a)
table. */
static void
-output_abbrev_section ()
+output_abbrev_section (void)
{
unsigned long abbrev_id;
@@ -6513,8 +6459,7 @@ output_abbrev_section ()
/* Output a symbol we can use to refer to this DIE from another CU. */
static inline void
-output_die_symbol (die)
- dw_die_ref die;
+output_die_symbol (dw_die_ref die)
{
char *sym = die->die_symbol;
@@ -6535,15 +6480,10 @@ output_die_symbol (die)
this location list node, which is done for the head of the list only. */
static inline dw_loc_list_ref
-new_loc_list (expr, begin, end, section, gensym)
- dw_loc_descr_ref expr;
- const char *begin;
- const char *end;
- const char *section;
- unsigned gensym;
+new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
+ const char *section, unsigned int gensym)
{
- dw_loc_list_ref retlist
- = (dw_loc_list_ref) xcalloc (1, sizeof (dw_loc_list_node));
+ dw_loc_list_ref retlist = ggc_alloc_cleared (sizeof (dw_loc_list_node));
retlist->begin = begin;
retlist->end = end;
@@ -6555,15 +6495,12 @@ new_loc_list (expr, begin, end, section, gensym)
return retlist;
}
-/* Add a location description expression to a location list */
+/* Add a location description expression to a location list. */
static inline void
-add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
- dw_loc_list_ref *list_head;
- dw_loc_descr_ref descr;
- const char *begin;
- const char *end;
- const char *section;
+add_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr,
+ const char *begin, const char *end,
+ const char *section)
{
dw_loc_list_ref *d;
@@ -6571,15 +6508,14 @@ add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
;
- /* Add a new location list node to the list */
+ /* Add a new location list node to the list. */
*d = new_loc_list (descr, begin, end, section, 0);
}
-/* Output the location list given to us */
+/* Output the location list given to us. */
static void
-output_loc_list (list_head)
- dw_loc_list_ref list_head;
+output_loc_list (dw_loc_list_ref list_head)
{
dw_loc_list_ref curr = list_head;
@@ -6629,8 +6565,7 @@ output_loc_list (list_head)
the definitions of each child DIE. */
static void
-output_die (die)
- dw_die_ref die;
+output_die (dw_die_ref die)
{
dw_attr_ref a;
dw_die_ref c;
@@ -6663,7 +6598,8 @@ output_die (die)
{
char *p = strchr (ranges_section_label, '\0');
- sprintf (p, "+0x%lx", a->dw_attr_val.v.val_offset);
+ sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX,
+ a->dw_attr_val.v.val_offset);
dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label,
"%s", name);
*p = '\0';
@@ -6717,16 +6653,24 @@ output_die (die)
}
break;
- case dw_val_class_float:
+ case dw_val_class_vec:
{
+ unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size;
+ unsigned int len = a->dw_attr_val.v.val_vec.length;
unsigned int i;
+ unsigned char *p;
- dw2_asm_output_data (1, a->dw_attr_val.v.val_float.length * 4,
- "%s", name);
-
- for (i = 0; i < a->dw_attr_val.v.val_float.length; i++)
- dw2_asm_output_data (4, a->dw_attr_val.v.val_float.array[i],
- "fp constant word %u", i);
+ dw2_asm_output_data (1, len * elt_size, "%s", name);
+ if (elt_size > sizeof (HOST_WIDE_INT))
+ {
+ elt_size /= 2;
+ len *= 2;
+ }
+ for (i = 0, p = a->dw_attr_val.v.val_vec.array;
+ i < len;
+ i++, p += elt_size)
+ dw2_asm_output_data (elt_size, extract_int (p, elt_size),
+ "fp or vector constant word %u", i);
break;
}
@@ -6806,9 +6750,13 @@ output_die (die)
.debug_info section, and precedes the DIE descriptions. */
static void
-output_compilation_unit_header ()
+output_compilation_unit_header (void)
{
- dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset - DWARF_OFFSET_SIZE,
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
+ dw2_asm_output_data (DWARF_OFFSET_SIZE,
+ next_die_offset - DWARF_INITIAL_LENGTH_SIZE,
"Length of Compilation Unit Info");
dw2_asm_output_data (2, DWARF_VERSION, "DWARF version number");
dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
@@ -6819,9 +6767,7 @@ output_compilation_unit_header ()
/* Output the compilation unit DIE and its children. */
static void
-output_comp_unit (die, output_if_empty)
- dw_die_ref die;
- int output_if_empty;
+output_comp_unit (dw_die_ref die, int output_if_empty)
{
const char *secname;
char *oldsym, *tmp;
@@ -6846,7 +6792,7 @@ output_comp_unit (die, output_if_empty)
oldsym = die->die_symbol;
if (oldsym)
{
- tmp = (char *) alloca (strlen (oldsym) + 24);
+ tmp = alloca (strlen (oldsym) + 24);
sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
secname = tmp;
@@ -6874,9 +6820,7 @@ output_comp_unit (die, output_if_empty)
"A::f(int)". Let's drop the argument list, and maybe the scope. */
static const char *
-dwarf2_name (decl, scope)
- tree decl;
- int scope;
+dwarf2_name (tree decl, int scope)
{
return (*lang_hooks.decl_printable_name) (decl, scope ? 1 : 0);
}
@@ -6884,9 +6828,7 @@ dwarf2_name (decl, scope)
/* Add a new entry to .debug_pubnames if appropriate. */
static void
-add_pubname (decl, die)
- tree decl;
- dw_die_ref die;
+add_pubname (tree decl, dw_die_ref die)
{
pubname_ref p;
@@ -6897,9 +6839,10 @@ add_pubname (decl, die)
{
pubname_table_allocated += PUBNAME_TABLE_INCREMENT;
pubname_table
- = (pubname_ref) xrealloc (pubname_table,
- (pubname_table_allocated
- * sizeof (pubname_entry)));
+ = ggc_realloc (pubname_table,
+ (pubname_table_allocated * sizeof (pubname_entry)));
+ memset (pubname_table + pubname_table_in_use, 0,
+ PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry));
}
p = &pubname_table[pubname_table_in_use++];
@@ -6912,11 +6855,14 @@ add_pubname (decl, die)
visible procedures. */
static void
-output_pubnames ()
+output_pubnames (void)
{
unsigned i;
unsigned long pubnames_length = size_of_pubnames ();
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
"Length of Public Names Info");
dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
@@ -6945,9 +6891,7 @@ output_pubnames ()
/* Add a new entry to .debug_aranges if appropriate. */
static void
-add_arange (decl, die)
- tree decl;
- dw_die_ref die;
+add_arange (tree decl, dw_die_ref die)
{
if (! DECL_SECTION_NAME (decl))
return;
@@ -6955,8 +6899,11 @@ add_arange (decl, die)
if (arange_table_in_use == arange_table_allocated)
{
arange_table_allocated += ARANGE_TABLE_INCREMENT;
- arange_table = (dw_die_ref *)
- xrealloc (arange_table, arange_table_allocated * sizeof (dw_die_ref));
+ arange_table = ggc_realloc (arange_table,
+ (arange_table_allocated
+ * sizeof (dw_die_ref)));
+ memset (arange_table + arange_table_in_use, 0,
+ ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
}
arange_table[arange_table_in_use++] = die;
@@ -6967,11 +6914,14 @@ add_arange (decl, die)
text section generated for this compilation unit. */
static void
-output_aranges ()
+output_aranges (void)
{
unsigned i;
unsigned long aranges_length = size_of_aranges ();
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length,
"Length of Address Ranges Info");
dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
@@ -6984,7 +6934,7 @@ output_aranges ()
if (DWARF_ARANGES_PAD_SIZE)
{
/* Pad using a 2 byte words so that padding is correct for any
- pointer size. */
+ pointer size. */
dw2_asm_output_data (2, 0, "Pad to %d byte boundary",
2 * DWARF2_ADDR_SIZE);
for (i = 2; i < (unsigned) DWARF_ARANGES_PAD_SIZE; i += 2)
@@ -7042,17 +6992,18 @@ output_aranges ()
was placed. */
static unsigned int
-add_ranges (block)
- tree block;
+add_ranges (tree block)
{
unsigned int in_use = ranges_table_in_use;
if (in_use == ranges_table_allocated)
{
ranges_table_allocated += RANGES_TABLE_INCREMENT;
- ranges_table = (dw_ranges_ref)
- xrealloc (ranges_table, (ranges_table_allocated
- * sizeof (struct dw_ranges_struct)));
+ ranges_table
+ = ggc_realloc (ranges_table, (ranges_table_allocated
+ * sizeof (struct dw_ranges_struct)));
+ memset (ranges_table + ranges_table_in_use, 0,
+ RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
}
ranges_table[in_use].block_num = (block ? BLOCK_NUMBER (block) : 0);
@@ -7062,7 +7013,7 @@ add_ranges (block)
}
static void
-output_ranges ()
+output_ranges (void)
{
unsigned i;
static const char *const start_fmt = "Offset 0x%x";
@@ -7140,9 +7091,7 @@ struct dir_info
the directories in the path. */
static int
-file_info_cmp (p1, p2)
- const void *p1;
- const void *p2;
+file_info_cmp (const void *p1, const void *p2)
{
const struct file_info *s1 = p1;
const struct file_info *s2 = p2;
@@ -7181,31 +7130,37 @@ file_info_cmp (p1, p2)
slowdowns with many input files. */
static void
-output_file_names ()
+output_file_names (void)
{
struct file_info *files;
struct dir_info *dirs;
int *saved;
int *savehere;
int *backmap;
- int ndirs;
+ size_t ndirs;
int idx_offset;
- int i;
+ size_t i;
int idx;
+ /* Handle the case where file_table is empty. */
+ if (VARRAY_ACTIVE_SIZE (file_table) <= 1)
+ {
+ dw2_asm_output_data (1, 0, "End directory table");
+ dw2_asm_output_data (1, 0, "End file name table");
+ return;
+ }
+
/* Allocate the various arrays we need. */
- files = (struct file_info *) alloca (file_table.in_use
- * sizeof (struct file_info));
- dirs = (struct dir_info *) alloca (file_table.in_use
- * sizeof (struct dir_info));
+ files = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct file_info));
+ dirs = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct dir_info));
/* Sort the file names. */
- for (i = 1; i < (int) file_table.in_use; i++)
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
char *f;
/* Skip all leading "./". */
- f = file_table.table[i];
+ f = VARRAY_CHAR_PTR (file_table, i);
while (f[0] == '.' && f[1] == '/')
f += 2;
@@ -7219,7 +7174,8 @@ output_file_names ()
files[i].fname = f == NULL ? files[i].path : f + 1;
}
- qsort (files + 1, file_table.in_use - 1, sizeof (files[0]), file_info_cmp);
+ qsort (files + 1, VARRAY_ACTIVE_SIZE (file_table) - 1,
+ sizeof (files[0]), file_info_cmp);
/* Find all the different directories used. */
dirs[0].path = files[1].path;
@@ -7231,7 +7187,7 @@ output_file_names ()
files[1].dir_idx = 0;
ndirs = 1;
- for (i = 2; i < (int) file_table.in_use; i++)
+ for (i = 2; i < VARRAY_ACTIVE_SIZE (file_table); i++)
if (files[i].fname - files[i].path == dirs[ndirs - 1].length
&& memcmp (dirs[ndirs - 1].path, files[i].path,
dirs[ndirs - 1].length) == 0)
@@ -7242,7 +7198,7 @@ output_file_names ()
}
else
{
- int j;
+ size_t j;
/* This is a new directory. */
dirs[ndirs].path = files[i].path;
@@ -7271,13 +7227,13 @@ output_file_names ()
where we would have to check out every combination of every single
possible prefix. Instead we use a heuristic which provides nearly optimal
results in most cases and never is much off. */
- saved = (int *) alloca (ndirs * sizeof (int));
- savehere = (int *) alloca (ndirs * sizeof (int));
+ saved = alloca (ndirs * sizeof (int));
+ savehere = alloca (ndirs * sizeof (int));
memset (saved, '\0', ndirs * sizeof (saved[0]));
for (i = 0; i < ndirs; i++)
{
- int j;
+ size_t j;
int total;
/* We can always save some space for the current directory. But this
@@ -7295,10 +7251,10 @@ output_file_names ()
int k;
k = dirs[j].prefix;
- while (k != -1 && k != i)
+ while (k != -1 && k != (int) i)
k = dirs[k].prefix;
- if (k == i)
+ if (k == (int) i)
{
/* Yes it is. We can possibly safe some memory but
writing the filenames in dirs[j] relative to
@@ -7329,8 +7285,8 @@ output_file_names ()
/* We have to emit them in the order they appear in the file_table array
since the index is used in the debug info generation. To do this
efficiently we generate a back-mapping of the indices first. */
- backmap = (int *) alloca (file_table.in_use * sizeof (int));
- for (i = 1; i < (int) file_table.in_use; i++)
+ backmap = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (int));
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
backmap[files[i].file_idx] = i;
@@ -7361,13 +7317,13 @@ output_file_names ()
dirs[0].used = 0;
/* Now write all the file names. */
- for (i = 1; i < (int) file_table.in_use; i++)
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
int file_idx = backmap[i];
int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
dw2_asm_output_nstring (files[file_idx].path + dirs[dir_idx].length, -1,
- "File Entry: 0x%x", i);
+ "File Entry: 0x%lx", (unsigned long) i);
/* Include directory index. */
dw2_asm_output_data_uleb128 (dirs[dir_idx].used, NULL);
@@ -7387,7 +7343,7 @@ output_file_names ()
information goes into the .debug_line section. */
static void
-output_line_info ()
+output_line_info (void)
{
char l1[20], l2[20], p1[20], p2[20];
char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -7406,6 +7362,9 @@ output_line_info ()
ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL, 0);
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1,
"Length of Source Line Info");
ASM_OUTPUT_LABEL (asm_out_file, l1);
@@ -7477,8 +7436,8 @@ output_line_info ()
prologue. */
/* Don't emit anything for redundant notes. Just updating the
- address doesn't accomplish anything, because we already assume
- that anything after the last address is this line. */
+ address doesn't accomplish anything, because we already assume
+ that anything after the last address is this line. */
if (line_info->dw_line_num == current_line
&& line_info->dw_file_num == current_file)
continue;
@@ -7504,7 +7463,7 @@ output_line_info ()
else
{
/* This can handle any delta. This takes
- 4+DWARF2_ADDR_SIZE bytes. */
+ 4+DWARF2_ADDR_SIZE bytes. */
dw2_asm_output_data (1, 0, "DW_LNE_set_address");
dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7520,7 +7479,8 @@ output_line_info ()
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
- file_table.table[current_file]);
+ VARRAY_CHAR_PTR (file_table,
+ current_file));
}
/* Emit debug info for the current line number, choosing the encoding
@@ -7595,7 +7555,7 @@ output_line_info ()
{
function = line_info->function;
- /* Set the address register to the first line in the function */
+ /* Set the address register to the first line in the function. */
dw2_asm_output_data (1, 0, "DW_LNE_set_address");
dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7628,7 +7588,8 @@ output_line_info ()
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
- file_table.table[current_file]);
+ VARRAY_CHAR_PTR (file_table,
+ current_file));
}
/* Emit debug info for the current line number, choosing the encoding
@@ -7699,8 +7660,7 @@ output_line_info ()
Dwarf base (fundamental) types. */
static dw_die_ref
-base_type_die (type)
- tree type;
+base_type_die (tree type)
{
dw_die_ref base_type_result;
const char *type_name;
@@ -7724,9 +7684,9 @@ base_type_die (type)
{
case INTEGER_TYPE:
/* Carefully distinguish the C character types, without messing
- up if the language is not C. Note that we check only for the names
- that contain spaces; other names might occur by coincidence in other
- languages. */
+ up if the language is not C. Note that we check only for the names
+ that contain spaces; other names might occur by coincidence in other
+ languages. */
if (! (TYPE_PRECISION (type) == CHAR_TYPE_SIZE
&& (type == char_type_node
|| ! strcmp (type_name, "signed char")
@@ -7793,8 +7753,7 @@ base_type_die (type)
root type of the given type without the qualifiers. */
static tree
-root_type (type)
- tree type;
+root_type (tree type)
{
if (TREE_CODE (type) == ERROR_MARK)
return error_mark_node;
@@ -7817,8 +7776,7 @@ root_type (type)
given input type is a Dwarf "fundamental" type. Otherwise return null. */
static inline int
-is_base_type (type)
- tree type;
+is_base_type (tree type)
{
switch (TREE_CODE (type))
{
@@ -7854,15 +7812,96 @@ is_base_type (type)
return 0;
}
+/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
+ node, return the size in bits for the type if it is a constant, or else
+ return the alignment for the type if the type's size is not constant, or
+ else return BITS_PER_WORD if the type actually turns out to be an
+ ERROR_MARK node. */
+
+static inline unsigned HOST_WIDE_INT
+simple_type_size_in_bits (tree type)
+{
+ if (TREE_CODE (type) == ERROR_MARK)
+ return BITS_PER_WORD;
+ else if (TYPE_SIZE (type) == NULL_TREE)
+ return 0;
+ else if (host_integerp (TYPE_SIZE (type), 1))
+ return tree_low_cst (TYPE_SIZE (type), 1);
+ else
+ return TYPE_ALIGN (type);
+}
+
+/* Return true if the debug information for the given type should be
+ emitted as a subrange type. */
+
+static inline bool
+is_subrange_type (tree type)
+{
+ tree subtype = TREE_TYPE (type);
+
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && subtype != NULL_TREE)
+ {
+ if (TREE_CODE (subtype) == INTEGER_TYPE)
+ return true;
+ if (TREE_CODE (subtype) == ENUMERAL_TYPE)
+ return true;
+ }
+ return false;
+}
+
+/* Given a pointer to a tree node for a subrange type, return a pointer
+ to a DIE that describes the given type. */
+
+static dw_die_ref
+subrange_type_die (tree type, dw_die_ref context_die)
+{
+ dw_die_ref subtype_die;
+ dw_die_ref subrange_die;
+ tree name = TYPE_NAME (type);
+ const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);
+
+ if (context_die == NULL)
+ context_die = comp_unit_die;
+
+ if (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE)
+ subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die);
+ else
+ subtype_die = base_type_die (TREE_TYPE (type));
+
+ subrange_die = new_die (DW_TAG_subrange_type, context_die, type);
+
+ if (name != NULL)
+ {
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+ add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
+ }
+
+ if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes)
+ {
+ /* The size of the subrange type and its base type do not match,
+ so we need to generate a size attribute for the subrange type. */
+ add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes);
+ }
+
+ if (TYPE_MIN_VALUE (type) != NULL)
+ add_bound_info (subrange_die, DW_AT_lower_bound,
+ TYPE_MIN_VALUE (type));
+ if (TYPE_MAX_VALUE (type) != NULL)
+ add_bound_info (subrange_die, DW_AT_upper_bound,
+ TYPE_MAX_VALUE (type));
+ add_AT_die_ref (subrange_die, DW_AT_type, subtype_die);
+
+ return subrange_die;
+}
+
/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
entry that chains various modifiers in front of the given type. */
static dw_die_ref
-modified_type_die (type, is_const_type, is_volatile_type, context_die)
- tree type;
- int is_const_type;
- int is_volatile_type;
- dw_die_ref context_die;
+modified_type_die (tree type, int is_const_type, int is_volatile_type,
+ dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref mod_type_die = NULL;
@@ -7931,7 +7970,8 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
else if (code == POINTER_TYPE)
{
mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die, type);
- add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+ add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+ simple_type_size_in_bits (type) / BITS_PER_UNIT);
#if 0
add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
#endif
@@ -7940,12 +7980,15 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
else if (code == REFERENCE_TYPE)
{
mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type);
- add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+ add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+ simple_type_size_in_bits (type) / BITS_PER_UNIT);
#if 0
add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
#endif
item_type = TREE_TYPE (type);
}
+ else if (is_subrange_type (type))
+ mod_type_die = subrange_type_die (type, context_die);
else if (is_base_type (type))
mod_type_die = base_type_die (type);
else
@@ -7994,17 +8037,15 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
an enumerated type. */
static inline int
-type_is_enum (type)
- tree type;
+type_is_enum (tree type)
{
return TREE_CODE (type) == ENUMERAL_TYPE;
}
-/* Return the register number described by a given RTL node. */
+/* Return the DBX register number described by a given RTL node. */
static unsigned int
-reg_number (rtl)
- rtx rtl;
+dbx_reg_number (rtx rtl)
{
unsigned regno = REGNO (rtl);
@@ -8015,32 +8056,94 @@ reg_number (rtl)
}
/* Return a location descriptor that designates a machine register or
- zero if there is no such. */
+ zero if there is none. */
static dw_loc_descr_ref
-reg_loc_descriptor (rtl)
- rtx rtl;
+reg_loc_descriptor (rtx rtl)
{
- dw_loc_descr_ref loc_result = NULL;
unsigned reg;
+ rtx regs;
if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
return 0;
- reg = reg_number (rtl);
- if (reg <= 31)
- loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
+ reg = dbx_reg_number (rtl);
+ regs = (*targetm.dwarf_register_span) (rtl);
+
+ if (HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl)) > 1
+ || regs)
+ return multiple_reg_loc_descriptor (rtl, regs);
+ else
+ return one_reg_loc_descriptor (reg);
+}
+
+/* Return a location descriptor that designates a machine register for
+ a given hard register number. */
+
+static dw_loc_descr_ref
+one_reg_loc_descriptor (unsigned int regno)
+{
+ if (regno <= 31)
+ return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
else
- loc_result = new_loc_descr (DW_OP_regx, reg, 0);
+ return new_loc_descr (DW_OP_regx, regno, 0);
+}
+
+/* Given an RTL of a register, return a location descriptor that
+ designates a value that spans more than one register. */
+
+static dw_loc_descr_ref
+multiple_reg_loc_descriptor (rtx rtl, rtx regs)
+{
+ int nregs, size, i;
+ unsigned reg;
+ dw_loc_descr_ref loc_result = NULL;
+
+ reg = dbx_reg_number (rtl);
+ nregs = HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl));
+
+ /* Simple, contiguous registers. */
+ if (regs == NULL_RTX)
+ {
+ size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+
+ loc_result = NULL;
+ while (nregs--)
+ {
+ dw_loc_descr_ref t;
+
+ t = one_reg_loc_descriptor (reg);
+ add_loc_descr (&loc_result, t);
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ ++reg;
+ }
+ return loc_result;
+ }
+
+ /* Now onto stupid register sets in non contiguous locations. */
+ if (GET_CODE (regs) != PARALLEL)
+ abort ();
+
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ loc_result = NULL;
+
+ for (i = 0; i < XVECLEN (regs, 0); ++i)
+ {
+ dw_loc_descr_ref t;
+
+ t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+ add_loc_descr (&loc_result, t);
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ }
return loc_result;
}
/* Return a location descriptor that designates a constant. */
static dw_loc_descr_ref
-int_loc_descriptor (i)
- HOST_WIDE_INT i;
+int_loc_descriptor (HOST_WIDE_INT i)
{
enum dwarf_location_atom op;
@@ -8079,9 +8182,7 @@ int_loc_descriptor (i)
/* Return a location descriptor that designates a base+offset location. */
static dw_loc_descr_ref
-based_loc_descr (reg, offset)
- unsigned reg;
- long int offset;
+based_loc_descr (unsigned int reg, HOST_WIDE_INT offset)
{
dw_loc_descr_ref loc_result;
/* For the "frame base", we use the frame pointer or stack pointer
@@ -8104,8 +8205,7 @@ based_loc_descr (reg, offset)
/* Return true if this RTL expression describes a base+offset calculation. */
static inline int
-is_based_loc (rtl)
- rtx rtl;
+is_based_loc (rtx rtl)
{
return (GET_CODE (rtl) == PLUS
&& ((GET_CODE (XEXP (rtl, 0)) == REG
@@ -8129,9 +8229,7 @@ is_based_loc (rtl)
Return 0 if we can't represent the location. */
static dw_loc_descr_ref
-mem_loc_descriptor (rtl, mode)
- rtx rtl;
- enum machine_mode mode;
+mem_loc_descriptor (rtx rtl, enum machine_mode mode)
{
dw_loc_descr_ref mem_loc_result = NULL;
@@ -8140,9 +8238,7 @@ mem_loc_descriptor (rtl, mode)
actually within the array. That's *not* necessarily the same as the
zeroth element of the array. */
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
switch (GET_CODE (rtl))
{
@@ -8156,30 +8252,30 @@ mem_loc_descriptor (rtl, mode)
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
- variable or a formal (register) parameter which doesn't quite fill
- up an entire register. For now, just assume that it is
- legitimate to make the Dwarf info refer to the whole register which
- contains the given subreg. */
+ variable or a formal (register) parameter which doesn't quite fill
+ up an entire register. For now, just assume that it is
+ legitimate to make the Dwarf info refer to the whole register which
+ contains the given subreg. */
rtl = SUBREG_REG (rtl);
/* ... fall through ... */
case REG:
/* Whenever a register number forms a part of the description of the
- method for calculating the (dynamic) address of a memory resident
- object, DWARF rules require the register number be referred to as
- a "base register". This distinction is not based in any way upon
- what category of register the hardware believes the given register
- belongs to. This is strictly DWARF terminology we're dealing with
- here. Note that in cases where the location of a memory-resident
- data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
- OP_CONST (0)) the actual DWARF location descriptor that we generate
- may just be OP_BASEREG (basereg). This may look deceptively like
- the object in question was allocated to a register (rather than in
- memory) so DWARF consumers need to be aware of the subtle
- distinction between OP_REG and OP_BASEREG. */
+ method for calculating the (dynamic) address of a memory resident
+ object, DWARF rules require the register number be referred to as
+ a "base register". This distinction is not based in any way upon
+ what category of register the hardware believes the given register
+ belongs to. This is strictly DWARF terminology we're dealing with
+ here. Note that in cases where the location of a memory-resident
+ data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
+ OP_CONST (0)) the actual DWARF location descriptor that we generate
+ may just be OP_BASEREG (basereg). This may look deceptively like
+ the object in question was allocated to a register (rather than in
+ memory) so DWARF consumers need to be aware of the subtle
+ distinction between OP_REG and OP_BASEREG. */
if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
- mem_loc_result = based_loc_descr (reg_number (rtl), 0);
+ mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0);
break;
case MEM:
@@ -8195,8 +8291,8 @@ mem_loc_descriptor (rtl, mode)
case LABEL_REF:
/* 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. */
+ the symbol ref is too far away and has to be dumped into a constant
+ pool. */
case CONST:
case SYMBOL_REF:
/* Alternatively, the symbol in the constant pool might be referenced
@@ -8231,7 +8327,7 @@ mem_loc_descriptor (rtl, mode)
case PRE_MODIFY:
/* Extract the PLUS expression nested inside and fall into
- PLUS code below. */
+ PLUS code below. */
rtl = XEXP (rtl, 1);
goto plus;
@@ -8249,7 +8345,7 @@ mem_loc_descriptor (rtl, mode)
case PLUS:
plus:
if (is_based_loc (rtl))
- mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
+ mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)),
INTVAL (XEXP (rtl, 1)));
else
{
@@ -8311,8 +8407,7 @@ mem_loc_descriptor (rtl, mode)
This is typically a complex variable. */
static dw_loc_descr_ref
-concat_loc_descriptor (x0, x1)
- rtx x0, x1;
+concat_loc_descriptor (rtx x0, rtx x1)
{
dw_loc_descr_ref cc_loc_result = NULL;
dw_loc_descr_ref x0_ref = loc_descriptor (x0);
@@ -8343,8 +8438,7 @@ concat_loc_descriptor (x0, x1)
If we don't know how to describe it, return 0. */
static dw_loc_descr_ref
-loc_descriptor (rtl)
- rtx rtl;
+loc_descriptor (rtx rtl)
{
dw_loc_descr_ref loc_result = NULL;
@@ -8352,10 +8446,10 @@ loc_descriptor (rtl)
{
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
- variable or a formal (register) parameter which doesn't quite fill
- up an entire register. For now, just assume that it is
- legitimate to make the Dwarf info refer to the whole register which
- contains the given subreg. */
+ variable or a formal (register) parameter which doesn't quite fill
+ up an entire register. For now, just assume that it is
+ legitimate to make the Dwarf info refer to the whole register which
+ contains the given subreg. */
rtl = SUBREG_REG (rtl);
/* ... fall through ... */
@@ -8385,9 +8479,7 @@ loc_descriptor (rtl)
descriptor, return 0. */
static dw_loc_descr_ref
-loc_descriptor_from_tree (loc, addressp)
- tree loc;
- int addressp;
+loc_descriptor_from_tree (tree loc, int addressp)
{
dw_loc_descr_ref ret, ret1;
int indirect_p = 0;
@@ -8414,6 +8506,13 @@ loc_descriptor_from_tree (loc, addressp)
case CALL_EXPR:
return 0;
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ /* There are no opcodes for these operations. */
+ return 0;
+
case ADDR_EXPR:
/* We can support this only if we can look through conversions and
find an INDIRECT_EXPR. */
@@ -8464,7 +8563,7 @@ loc_descriptor_from_tree (loc, addressp)
indirect_p = 1;
break;
}
- /* FALLTHRU */
+ /* Fall through. */
case PARM_DECL:
{
@@ -8507,6 +8606,7 @@ loc_descriptor_from_tree (loc, addressp)
case NON_LVALUE_EXPR:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
+ case MODIFY_EXPR:
return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
case COMPONENT_REF:
@@ -8558,6 +8658,24 @@ loc_descriptor_from_tree (loc, addressp)
return 0;
break;
+ case CONSTRUCTOR:
+ {
+ /* Get an RTL for this, if something has been emitted. */
+ rtx rtl = lookup_constant_def (loc);
+ enum machine_mode mode;
+
+ if (GET_CODE (rtl) != MEM)
+ return 0;
+ mode = GET_MODE (rtl);
+ rtl = XEXP (rtl, 0);
+
+ rtl = (*targetm.delegitimize_address) (rtl);
+
+ indirect_p = 1;
+ ret = mem_loc_descriptor (rtl, mode);
+ break;
+ }
+
case TRUTH_AND_EXPR:
case TRUTH_ANDIF_EXPR:
case BIT_AND_EXPR:
@@ -8575,6 +8693,9 @@ loc_descriptor_from_tree (loc, addressp)
op = DW_OP_or;
goto do_binop;
+ case FLOOR_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case ROUND_DIV_EXPR:
case TRUNC_DIV_EXPR:
op = DW_OP_div;
goto do_binop;
@@ -8583,6 +8704,9 @@ loc_descriptor_from_tree (loc, addressp)
op = DW_OP_minus;
goto do_binop;
+ case FLOOR_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case ROUND_MOD_EXPR:
case TRUNC_MOD_EXPR:
op = DW_OP_mod;
goto do_binop;
@@ -8724,7 +8848,18 @@ loc_descriptor_from_tree (loc, addressp)
}
break;
+ case EXPR_WITH_FILE_LOCATION:
+ return loc_descriptor_from_tree (EXPR_WFL_NODE (loc), addressp);
+
default:
+ /* Leave front-end specific codes as simply unknown. This comes
+ up, for instance, with the C STMT_EXPR. */
+ if ((unsigned int) TREE_CODE (loc)
+ >= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
+ return 0;
+
+ /* Otherwise this is a generic code; we should just lists all of
+ these explicitly. Aborting means we forgot one. */
abort ();
}
@@ -8754,9 +8889,7 @@ loc_descriptor_from_tree (loc, addressp)
which is not less than the value itself. */
static inline HOST_WIDE_INT
-ceiling (value, boundary)
- HOST_WIDE_INT value;
- unsigned int boundary;
+ceiling (HOST_WIDE_INT value, unsigned int boundary)
{
return (((value + boundary - 1) / boundary) * boundary);
}
@@ -8767,8 +8900,7 @@ ceiling (value, boundary)
ERROR_MARK node. */
static inline tree
-field_type (decl)
- tree decl;
+field_type (tree decl)
{
tree type;
@@ -8787,40 +8919,17 @@ field_type (decl)
be an ERROR_MARK node. */
static inline unsigned
-simple_type_align_in_bits (type)
- tree type;
+simple_type_align_in_bits (tree type)
{
return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
}
static inline unsigned
-simple_decl_align_in_bits (decl)
- tree decl;
+simple_decl_align_in_bits (tree decl)
{
return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
}
-/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
- node, return the size in bits for the type if it is a constant, or else
- return the alignment for the type if the type's size is not constant, or
- else return BITS_PER_WORD if the type actually turns out to be an
- ERROR_MARK node. */
-
-static inline unsigned HOST_WIDE_INT
-simple_type_size_in_bits (type)
- tree type;
-{
-
- if (TREE_CODE (type) == ERROR_MARK)
- return BITS_PER_WORD;
- else if (TYPE_SIZE (type) == NULL_TREE)
- return 0;
- else if (host_integerp (TYPE_SIZE (type), 1))
- return tree_low_cst (TYPE_SIZE (type), 1);
- else
- return TYPE_ALIGN (type);
-}
-
/* Given a pointer to a FIELD_DECL, compute and return the byte offset of the
lowest addressed byte of the "containing object" for the given FIELD_DECL,
or return 0 if we are unable to determine what that offset is, either
@@ -8829,8 +8938,7 @@ simple_type_size_in_bits (type)
just yet). */
static HOST_WIDE_INT
-field_byte_offset (decl)
- tree decl;
+field_byte_offset (tree decl)
{
unsigned int type_align_in_bits;
unsigned int decl_align_in_bits;
@@ -8949,10 +9057,8 @@ field_byte_offset (decl)
generated by the routine `data_member_location_attribute' below. */
static inline void
-add_AT_location_description (die, attr_kind, descr)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_descr_ref descr;
+add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
+ dw_loc_descr_ref descr)
{
if (descr != 0)
add_AT_loc (die, attr_kind, descr);
@@ -8978,11 +9084,9 @@ add_AT_location_description (die, attr_kind, descr)
function below.) */
static void
-add_data_member_location_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_data_member_location_attribute (dw_die_ref die, tree decl)
{
- long offset;
+ HOST_WIDE_INT offset;
dw_loc_descr_ref loc_descr = 0;
if (TREE_CODE (decl) == TREE_VEC)
@@ -9056,80 +9160,93 @@ add_data_member_location_attribute (die, decl)
add_AT_loc (die, DW_AT_data_member_location, loc_descr);
}
-/* Attach an DW_AT_const_value attribute for a variable or a parameter which
+/* Writes integer values to dw_vec_const array. */
+
+static void
+insert_int (HOST_WIDE_INT val, unsigned int size, unsigned char *dest)
+{
+ while (size != 0)
+ {
+ *dest++ = val & 0xff;
+ val >>= 8;
+ --size;
+ }
+}
+
+/* Reads integers from dw_vec_const array. Inverse of insert_int. */
+
+static HOST_WIDE_INT
+extract_int (const unsigned char *src, unsigned int size)
+{
+ HOST_WIDE_INT val = 0;
+
+ src += size;
+ while (size != 0)
+ {
+ val <<= 8;
+ val |= *--src & 0xff;
+ --size;
+ }
+ return val;
+}
+
+/* Writes floating point values to dw_vec_const array. */
+
+static void
+insert_float (rtx rtl, unsigned char *array)
+{
+ REAL_VALUE_TYPE rv;
+ long val[4];
+ int i;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
+ real_to_target (val, &rv, GET_MODE (rtl));
+
+ /* real_to_target puts 32-bit pieces in each long. Pack them. */
+ for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++)
+ {
+ insert_int (val[i], 4, array);
+ array += 4;
+ }
+}
+
+/* Attach a DW_AT_const_value attribute for a variable or a parameter which
does not have a "location" either in memory or in a register. These
things can arise in GNU C when a constant is passed as an actual parameter
to an inlined function. They can also arise in C++ where declared
constants do not necessarily get memory "homes". */
static void
-add_const_value_attribute (die, rtl)
- dw_die_ref die;
- rtx rtl;
+add_const_value_attribute (dw_die_ref die, rtx rtl)
{
switch (GET_CODE (rtl))
{
case CONST_INT:
- /* Note that a CONST_INT rtx could represent either an integer
- or a floating-point constant. A CONST_INT is used whenever
- the constant will fit into a single word. In all such
- cases, the original mode of the constant value is wiped
- out, and the CONST_INT rtx is assigned VOIDmode. */
{
HOST_WIDE_INT val = INTVAL (rtl);
- /* ??? We really should be using HOST_WIDE_INT throughout. */
- if (val < 0 && (long) val == val)
- add_AT_int (die, DW_AT_const_value, (long) val);
- else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val)
- add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
- else
- {
-#if HOST_BITS_PER_LONG * 2 == HOST_BITS_PER_WIDE_INT
- add_AT_long_long (die, DW_AT_const_value,
- val >> HOST_BITS_PER_LONG, val);
-#else
- abort ();
-#endif
- }
+ if (val < 0)
+ add_AT_int (die, DW_AT_const_value, val);
+ else
+ add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
}
break;
case CONST_DOUBLE:
/* Note that a CONST_DOUBLE rtx could represent either an integer or a
- floating-point constant. A CONST_DOUBLE is used whenever the
- constant requires more than one word in order to be adequately
- represented. We output CONST_DOUBLEs as blocks. */
+ floating-point constant. A CONST_DOUBLE is used whenever the
+ constant requires more than one word in order to be adequately
+ represented. We output CONST_DOUBLEs as blocks. */
{
enum machine_mode mode = GET_MODE (rtl);
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- unsigned length = GET_MODE_SIZE (mode) / 4;
- long *array = (long *) xmalloc (sizeof (long) * length);
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
- switch (mode)
- {
- case SFmode:
- REAL_VALUE_TO_TARGET_SINGLE (rv, array[0]);
- break;
-
- case DFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (rv, array);
- break;
-
- case XFmode:
- case TFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, array);
- break;
+ unsigned int length = GET_MODE_SIZE (mode);
+ unsigned char *array = ggc_alloc (length);
- default:
- abort ();
- }
-
- add_AT_float (die, DW_AT_const_value, length, array);
+ insert_float (rtl, array);
+ add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
}
else
{
@@ -9143,6 +9260,68 @@ add_const_value_attribute (die, rtl)
}
break;
+ case CONST_VECTOR:
+ {
+ enum machine_mode mode = GET_MODE (rtl);
+ unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
+ unsigned int length = CONST_VECTOR_NUNITS (rtl);
+ unsigned char *array = ggc_alloc (length * elt_size);
+ unsigned int i;
+ unsigned char *p;
+
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+ {
+ for (i = 0, p = array; i < length; i++, p += elt_size)
+ {
+ rtx elt = CONST_VECTOR_ELT (rtl, i);
+ HOST_WIDE_INT lo, hi;
+ if (GET_CODE (elt) == CONST_INT)
+ {
+ lo = INTVAL (elt);
+ hi = -(lo < 0);
+ }
+ else if (GET_CODE (elt) == CONST_DOUBLE)
+ {
+ lo = CONST_DOUBLE_LOW (elt);
+ hi = CONST_DOUBLE_HIGH (elt);
+ }
+ else
+ abort ();
+
+ if (elt_size <= sizeof (HOST_WIDE_INT))
+ insert_int (lo, elt_size, p);
+ else if (elt_size == 2 * sizeof (HOST_WIDE_INT))
+ {
+ unsigned char *p0 = p;
+ unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
+ if (WORDS_BIG_ENDIAN)
+ {
+ p0 = p1;
+ p1 = p;
+ }
+ insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+ insert_int (hi, sizeof (HOST_WIDE_INT), p1);
+ }
+ else
+ abort ();
+ }
+ }
+ else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ {
+ for (i = 0, p = array; i < length; i++, p += elt_size)
+ {
+ rtx elt = CONST_VECTOR_ELT (rtl, i);
+ insert_float (elt, p);
+ }
+ }
+ else
+ abort ();
+
+ add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
+ }
+ break;
+
case CONST_STRING:
add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0));
break;
@@ -9156,16 +9335,16 @@ add_const_value_attribute (die, rtl)
case PLUS:
/* In cases where an inlined instance of an inline function is passed
- the address of an `auto' variable (which is local to the caller) we
- can get a situation where the DECL_RTL of the artificial local
- variable (for the inlining) which acts as a stand-in for the
- corresponding formal parameter (of the inline function) will look
- like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). This is not
- exactly a compile-time constant expression, but it isn't the address
- of the (artificial) local variable either. Rather, it represents the
- *value* which the artificial local variable always has during its
- lifetime. We currently have no way to represent such quasi-constant
- values in Dwarf, so for now we just punt and generate nothing. */
+ the address of an `auto' variable (which is local to the caller) we
+ can get a situation where the DECL_RTL of the artificial local
+ variable (for the inlining) which acts as a stand-in for the
+ corresponding formal parameter (of the inline function) will look
+ like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). This is not
+ exactly a compile-time constant expression, but it isn't the address
+ of the (artificial) local variable either. Rather, it represents the
+ *value* which the artificial local variable always has during its
+ lifetime. We currently have no way to represent such quasi-constant
+ values in Dwarf, so for now we just punt and generate nothing. */
break;
default:
@@ -9176,8 +9355,7 @@ add_const_value_attribute (die, rtl)
}
static rtx
-rtl_for_decl_location (decl)
- tree decl;
+rtl_for_decl_location (tree decl)
{
rtx rtl;
@@ -9270,9 +9448,7 @@ rtl_for_decl_location (decl)
&& TREE_CODE (decl) == VAR_DECL
&& TREE_STATIC (decl))))
{
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
return rtl;
}
rtl = NULL_RTX;
@@ -9378,10 +9554,8 @@ rtl_for_decl_location (decl)
}
}
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
if (rtl)
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
@@ -9392,7 +9566,7 @@ rtl_for_decl_location (decl)
return rtl;
}
-/* Generate *either* an DW_AT_location attribute or else an DW_AT_const_value
+/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
data attribute for a variable or a parameter. We generate the
DW_AT_const_value attribute only in those cases where the given variable
or parameter does not have a true "location" either in memory or in a
@@ -9404,9 +9578,7 @@ rtl_for_decl_location (decl)
function call evaluates to a compile-time constant address. */
static void
-add_location_or_const_value_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_location_or_const_value_attribute (dw_die_ref die, tree decl)
{
rtx rtl;
dw_loc_descr_ref descr;
@@ -9429,6 +9601,7 @@ add_location_or_const_value_attribute (die, decl)
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case CONST_STRING:
case SYMBOL_REF:
case LABEL_REF:
@@ -9456,7 +9629,34 @@ add_location_or_const_value_attribute (die, decl)
}
add_AT_location_description (die, DW_AT_location, descr);
break;
-
+
+ case PARALLEL:
+ {
+ rtvec par_elems = XVEC (rtl, 0);
+ int num_elem = GET_NUM_ELEM (par_elems);
+ enum machine_mode mode;
+ int i;
+
+ /* Create the first one, so we have something to add to. */
+ descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
+ mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
+ add_loc_descr (&descr,
+ new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
+ for (i = 1; i < num_elem; i++)
+ {
+ dw_loc_descr_ref temp;
+
+ temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
+ add_loc_descr (&descr, temp);
+ mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
+ add_loc_descr (&descr,
+ new_loc_descr (DW_OP_piece,
+ GET_MODE_SIZE (mode), 0));
+ }
+ }
+ add_AT_location_description (die, DW_AT_location, descr);
+ break;
+
default:
abort ();
}
@@ -9467,9 +9667,7 @@ add_location_or_const_value_attribute (die, decl)
we should tell the debugger about the constant value. */
static void
-tree_add_const_value_attribute (var_die, decl)
- dw_die_ref var_die;
- tree decl;
+tree_add_const_value_attribute (dw_die_ref var_die, tree decl)
{
tree init = DECL_INITIAL (decl);
tree type = TREE_TYPE (decl);
@@ -9496,13 +9694,11 @@ tree_add_const_value_attribute (var_die, decl)
}
}
-/* Generate an DW_AT_name attribute given some string value to be included as
+/* Generate a DW_AT_name attribute given some string value to be included as
the value of the attribute. */
-static inline void
-add_name_attribute (die, name_string)
- dw_die_ref die;
- const char *name_string;
+static void
+add_name_attribute (dw_die_ref die, const char *name_string)
{
if (name_string != NULL && *name_string != 0)
{
@@ -9513,14 +9709,21 @@ add_name_attribute (die, name_string)
}
}
+/* Generate a DW_AT_comp_dir attribute for DIE. */
+
+static void
+add_comp_dir_attribute (dw_die_ref die)
+{
+ const char *wd = get_src_pwd ();
+ if (wd != NULL)
+ add_AT_string (die, DW_AT_comp_dir, wd);
+}
+
/* Given a tree node describing an array bound (either lower or upper) output
a representation for that bound. */
static void
-add_bound_info (subrange_die, bound_attr, bound)
- dw_die_ref subrange_die;
- enum dwarf_attribute bound_attr;
- tree bound;
+add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree bound)
{
switch (TREE_CODE (bound))
{
@@ -9548,23 +9751,23 @@ add_bound_info (subrange_die, bound_attr, bound)
case SAVE_EXPR:
/* If optimization is turned on, the SAVE_EXPRs that describe how to
- access the upper bound values may be bogus. If they refer to a
- register, they may only describe how to get at these values at the
- points in the generated code right after they have just been
- computed. Worse yet, in the typical case, the upper bound values
- will not even *be* computed in the optimized code (though the
- number of elements will), so these SAVE_EXPRs are entirely
- bogus. In order to compensate for this fact, we check here to see
- if optimization is enabled, and if so, we don't add an attribute
- for the (unknown and unknowable) upper bound. This should not
- cause too much trouble for existing (stupid?) debuggers because
- they have to deal with empty upper bounds location descriptions
- anyway in order to be able to deal with incomplete array types.
- Of course an intelligent debugger (GDB?) should be able to
- comprehend that a missing upper bound specification in an array
- type used for a storage class `auto' local array variable
- indicates that the upper bound is both unknown (at compile- time)
- and unknowable (at run-time) due to optimization.
+ access the upper bound values may be bogus. If they refer to a
+ register, they may only describe how to get at these values at the
+ points in the generated code right after they have just been
+ computed. Worse yet, in the typical case, the upper bound values
+ will not even *be* computed in the optimized code (though the
+ number of elements will), so these SAVE_EXPRs are entirely
+ bogus. In order to compensate for this fact, we check here to see
+ if optimization is enabled, and if so, we don't add an attribute
+ for the (unknown and unknowable) upper bound. This should not
+ cause too much trouble for existing (stupid?) debuggers because
+ they have to deal with empty upper bounds location descriptions
+ anyway in order to be able to deal with incomplete array types.
+ Of course an intelligent debugger (GDB?) should be able to
+ comprehend that a missing upper bound specification in an array
+ type used for a storage class `auto' local array variable
+ indicates that the upper bound is both unknown (at compile- time)
+ and unknowable (at run-time) due to optimization.
We assume that a MEM rtx is safe because gcc wouldn't put the
value there unless it was going to be used repeatedly in the
@@ -9652,9 +9855,7 @@ add_bound_info (subrange_die, bound_attr, bound)
includes information about the element type of type given array type. */
static void
-add_subscript_info (type_die, type)
- dw_die_ref type_die;
- tree type;
+add_subscript_info (dw_die_ref type_die, tree type)
{
#ifndef MIPS_DEBUGGING_INFO
unsigned dimension_number;
@@ -9685,7 +9886,7 @@ add_subscript_info (type_die, type)
/* Arrays come in three flavors: Unspecified bounds, fixed bounds,
and (in GNU C only) variable bounds. Handle all three forms
- here. */
+ here. */
subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL);
if (domain)
{
@@ -9693,7 +9894,7 @@ add_subscript_info (type_die, type)
lower = TYPE_MIN_VALUE (domain);
upper = TYPE_MAX_VALUE (domain);
- /* define the index type. */
+ /* Define the index type. */
if (TREE_TYPE (domain))
{
/* ??? This is probably an Ada unnamed subrange type. Ignore the
@@ -9712,7 +9913,7 @@ add_subscript_info (type_die, type)
/* ??? If upper is NULL, the array has unspecified length,
but it does have a lower bound. This happens with Fortran
dimension arr(N:*)
- Since the debugger is definitely going to need to know N
+ Since the debugger is definitely going to need to know N
to produce useful results, go ahead and output the lower
bound solo, and hope the debugger can cope. */
@@ -9728,9 +9929,7 @@ add_subscript_info (type_die, type)
}
static void
-add_byte_size_attribute (die, tree_node)
- dw_die_ref die;
- tree tree_node;
+add_byte_size_attribute (dw_die_ref die, tree tree_node)
{
unsigned size;
@@ -9747,9 +9946,9 @@ add_byte_size_attribute (die, tree_node)
break;
case FIELD_DECL:
/* For a data member of a struct or union, the DW_AT_byte_size is
- generally given as the number of bytes normally allocated for an
- object of the *declared* type of the member itself. This is true
- even for bit-fields. */
+ generally given as the number of bytes normally allocated for an
+ object of the *declared* type of the member itself. This is true
+ even for bit-fields. */
size = simple_type_size_in_bits (field_type (tree_node)) / BITS_PER_UNIT;
break;
default:
@@ -9780,9 +9979,7 @@ add_byte_size_attribute (die, tree_node)
(See `byte_size_attribute' above). */
static inline void
-add_bit_offset_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_bit_offset_attribute (dw_die_ref die, tree decl)
{
HOST_WIDE_INT object_offset_in_bytes = field_byte_offset (decl);
tree type = DECL_BIT_FIELD_TYPE (decl);
@@ -9831,9 +10028,7 @@ add_bit_offset_attribute (die, decl)
which specifies the length in bits of the given field. */
static inline void
-add_bit_size_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_bit_size_attribute (dw_die_ref die, tree decl)
{
/* Must be a field and a bit field. */
if (TREE_CODE (decl) != FIELD_DECL
@@ -9848,9 +10043,7 @@ add_bit_size_attribute (die, decl)
attribute, if arg types are given for the parameters of a function. */
static inline void
-add_prototyped_attribute (die, func_type)
- dw_die_ref die;
- tree func_type;
+add_prototyped_attribute (dw_die_ref die, tree func_type)
{
if (get_AT_unsigned (comp_unit_die, DW_AT_language) == DW_LANG_C89
&& TYPE_ARG_TYPES (func_type) != NULL)
@@ -9862,9 +10055,7 @@ add_prototyped_attribute (die, func_type)
equate table. */
static inline void
-add_abstract_origin_attribute (die, origin)
- dw_die_ref die;
- tree origin;
+add_abstract_origin_attribute (dw_die_ref die, tree origin)
{
dw_die_ref origin_die = NULL;
@@ -9874,7 +10065,7 @@ add_abstract_origin_attribute (die, origin)
function, if we're in an exception handler or some such; make
sure that the abstract function has been written out.
- Doing this for nested functions is wrong, however; functions are
+ Doing this for nested functions is wrong, however; functions are
distinct units, and our context might not even be inline. */
tree fn = origin;
@@ -9900,9 +10091,7 @@ add_abstract_origin_attribute (die, origin)
/* We do not currently support the pure_virtual attribute. */
static inline void
-add_pure_or_virtual_attribute (die, func_decl)
- dw_die_ref die;
- tree func_decl;
+add_pure_or_virtual_attribute (dw_die_ref die, tree func_decl)
{
if (DECL_VINDEX (func_decl))
{
@@ -9924,9 +10113,7 @@ add_pure_or_virtual_attribute (die, func_decl)
/* Add source coordinate attributes for the given decl. */
static void
-add_src_coords_attributes (die, decl)
- dw_die_ref die;
- tree decl;
+add_src_coords_attributes (dw_die_ref die, tree decl)
{
unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
@@ -9934,13 +10121,11 @@ add_src_coords_attributes (die, decl)
add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
}
-/* Add an DW_AT_name attribute and source coordinate attribute for the
+/* Add a DW_AT_name attribute and source coordinate attribute for the
given decl, but only if it actually has a name. */
static void
-add_name_and_src_coords_attributes (die, decl)
- dw_die_ref die;
- tree decl;
+add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
{
tree decl_name;
@@ -9974,8 +10159,7 @@ add_name_and_src_coords_attributes (die, decl)
/* Push a new declaration scope. */
static void
-push_decl_scope (scope)
- tree scope;
+push_decl_scope (tree scope)
{
VARRAY_PUSH_TREE (decl_scope_table, scope);
}
@@ -9983,7 +10167,7 @@ push_decl_scope (scope)
/* Pop a declaration scope. */
static inline void
-pop_decl_scope ()
+pop_decl_scope (void)
{
if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0)
abort ();
@@ -9998,9 +10182,7 @@ pop_decl_scope ()
the current active scope. */
static dw_die_ref
-scope_die_for (t, context_die)
- tree t;
- dw_die_ref context_die;
+scope_die_for (tree t, dw_die_ref context_die)
{
dw_die_ref scope_die = NULL;
tree containing_scope;
@@ -10012,9 +10194,14 @@ scope_die_for (t, context_die)
containing_scope = TYPE_CONTEXT (t);
- /* Ignore namespaces for the moment. */
+ /* Use the containing namespace if it was passed in (for a declaration). */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
- containing_scope = NULL_TREE;
+ {
+ if (context_die == lookup_decl_die (containing_scope))
+ /* OK */;
+ else
+ containing_scope = NULL_TREE;
+ }
/* Ignore function type "scopes" from the C frontend. They mean that
a tagged type is local to a parmlist of a function declarator, but
@@ -10054,8 +10241,7 @@ scope_die_for (t, context_die)
/* Returns nonzero if CONTEXT_DIE is internal to a function. */
static inline int
-local_scope_p (context_die)
- dw_die_ref context_die;
+local_scope_p (dw_die_ref context_die)
{
for (; context_die; context_die = context_die->die_parent)
if (context_die->die_tag == DW_TAG_inlined_subroutine
@@ -10065,28 +10251,25 @@ local_scope_p (context_die)
return 0;
}
-/* Returns nonzero if CONTEXT_DIE is a class. */
+/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding
+ whether or not to treat a DIE in this context as a declaration. */
static inline int
-class_scope_p (context_die)
- dw_die_ref context_die;
+class_or_namespace_scope_p (dw_die_ref context_die)
{
return (context_die
&& (context_die->die_tag == DW_TAG_structure_type
- || context_die->die_tag == DW_TAG_union_type));
+ || context_die->die_tag == DW_TAG_union_type
+ || context_die->die_tag == DW_TAG_namespace));
}
/* Many forms of DIEs require a "type description" attribute. This
routine locates the proper "type descriptor" die for the type given
- by 'type', and adds an DW_AT_type attribute below the given die. */
+ by 'type', and adds a DW_AT_type attribute below the given die. */
static void
-add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
- dw_die_ref object_die;
- tree type;
- int decl_const;
- int decl_volatile;
- dw_die_ref context_die;
+add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
+ int decl_volatile, dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref type_die = NULL;
@@ -10120,8 +10303,7 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
was declared without a tag. */
static const char *
-type_tag (type)
- tree type;
+type_tag (tree type)
{
const char *name = 0;
@@ -10134,8 +10316,8 @@ type_tag (type)
t = TYPE_NAME (type);
/* The g++ front end makes the TYPE_NAME of *each* tagged type point to
- a TYPE_DECL node, regardless of whether or not a `typedef' was
- involved. */
+ a TYPE_DECL node, regardless of whether or not a `typedef' was
+ involved. */
else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& ! DECL_IGNORED_P (TYPE_NAME (type)))
t = DECL_NAME (TYPE_NAME (type));
@@ -10152,8 +10334,7 @@ type_tag (type)
for bit field types. */
static inline tree
-member_declared_type (member)
- tree member;
+member_declared_type (tree member)
{
return (DECL_BIT_FIELD_TYPE (member)
? DECL_BIT_FIELD_TYPE (member) : TREE_TYPE (member));
@@ -10164,8 +10345,7 @@ member_declared_type (member)
#if 0
static const char *
-decl_start_label (decl)
- tree decl;
+decl_start_label (tree decl)
{
rtx x;
const char *fnname;
@@ -10188,9 +10368,7 @@ decl_start_label (decl)
the declaration trees passed in from dwarf2out_decl(). */
static void
-gen_array_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_array_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref scope_die = scope_die_for (type, context_die);
dw_die_ref array_die;
@@ -10230,7 +10408,7 @@ gen_array_type_die (type, context_die)
/* The SGI compilers handle arrays of unknown bound by setting
AT_declaration and not emitting any subrange DIEs. */
if (! TYPE_DOMAIN (type))
- add_AT_unsigned (array_die, DW_AT_declaration, 1);
+ add_AT_flag (array_die, DW_AT_declaration, 1);
else
#endif
add_subscript_info (array_die, type);
@@ -10253,9 +10431,7 @@ gen_array_type_die (type, context_die)
}
static void
-gen_set_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_set_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die
= new_die (DW_TAG_set_type, scope_die_for (type, context_die), type);
@@ -10266,9 +10442,7 @@ gen_set_type_die (type, context_die)
#if 0
static void
-gen_entry_point_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_entry_point_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl);
@@ -10293,7 +10467,7 @@ gen_entry_point_die (decl, context_die)
emit full debugging info for them. */
static void
-retry_incomplete_types ()
+retry_incomplete_types (void)
{
int i;
@@ -10304,9 +10478,7 @@ retry_incomplete_types ()
/* Generate a DIE to represent an inlined instance of an enumeration type. */
static void
-gen_inlined_enumeration_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_enumeration_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die, type);
@@ -10318,9 +10490,7 @@ gen_inlined_enumeration_type_die (type, context_die)
/* Generate a DIE to represent an inlined instance of a structure type. */
static void
-gen_inlined_structure_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_structure_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die, type);
@@ -10332,9 +10502,7 @@ gen_inlined_structure_type_die (type, context_die)
/* Generate a DIE to represent an inlined instance of a union type. */
static void
-gen_inlined_union_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_union_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_union_type, context_die, type);
@@ -10348,10 +10516,8 @@ gen_inlined_union_type_die (type, context_die)
enumerated type name/value is listed as a child of the enumerated type
DIE. */
-static void
-gen_enumeration_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+static dw_die_ref
+gen_enumeration_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = lookup_type_die (type);
@@ -10363,7 +10529,7 @@ gen_enumeration_type_die (type, context_die)
add_name_attribute (type_die, type_tag (type));
}
else if (! TYPE_SIZE (type))
- return;
+ return type_die;
else
remove_AT (type_die, DW_AT_declaration);
@@ -10388,24 +10554,26 @@ gen_enumeration_type_die (type, context_die)
link != NULL; link = TREE_CHAIN (link))
{
dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link);
+ tree value = TREE_VALUE (link);
add_name_attribute (enum_die,
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
- if (host_integerp (TREE_VALUE (link),
- TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (link)))))
- {
- if (tree_int_cst_sgn (TREE_VALUE (link)) < 0)
- add_AT_int (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 0));
- else
- add_AT_unsigned (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 1));
- }
+ if (host_integerp (value, TREE_UNSIGNED (TREE_TYPE (value))))
+ /* DWARF2 does not provide a way of indicating whether or
+ not enumeration constants are signed or unsigned. GDB
+ always assumes the values are signed, so we output all
+ values as if they were signed. That means that
+ enumeration constants with very large unsigned values
+ will appear to have negative values in the debugger. */
+ add_AT_int (enum_die, DW_AT_const_value,
+ tree_low_cst (value, tree_int_cst_sgn (value) > 0));
}
}
else
add_AT_flag (type_die, DW_AT_declaration, 1);
+
+ return type_die;
}
/* Generate a DIE to represent either a real live formal parameter decl or to
@@ -10422,9 +10590,7 @@ gen_enumeration_type_die (type, context_die)
argument type of some subprogram type. */
static dw_die_ref
-gen_formal_parameter_die (node, context_die)
- tree node;
- dw_die_ref context_die;
+gen_formal_parameter_die (tree node, dw_die_ref context_die)
{
dw_die_ref parm_die
= new_die (DW_TAG_formal_parameter, context_die, node);
@@ -10469,9 +10635,7 @@ gen_formal_parameter_die (node, context_die)
at the end of an (ANSI prototyped) formal parameters list. */
static void
-gen_unspecified_parameters_die (decl_or_type, context_die)
- tree decl_or_type;
- dw_die_ref context_die;
+gen_unspecified_parameters_die (tree decl_or_type, dw_die_ref context_die)
{
new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type);
}
@@ -10482,9 +10646,7 @@ gen_unspecified_parameters_die (decl_or_type, context_die)
those which appear as part of a function *definition*). */
static void
-gen_formal_types_die (function_or_method_type, context_die)
- tree function_or_method_type;
- dw_die_ref context_die;
+gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
{
tree link;
tree formal_type = NULL;
@@ -10543,9 +10705,7 @@ gen_formal_types_die (function_or_method_type, context_die)
trick; we need to attach the member declaration by hand. */
static void
-gen_type_die_for_member (type, member, context_die)
- tree type, member;
- dw_die_ref context_die;
+gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
{
gen_type_die (type, context_die);
@@ -10571,8 +10731,7 @@ gen_type_die_for_member (type, member, context_die)
may later generate inlined and/or out-of-line instances of. */
static void
-dwarf2out_abstract_function (decl)
- tree decl;
+dwarf2out_abstract_function (tree decl)
{
dw_die_ref old_die;
tree save_fn;
@@ -10583,7 +10742,7 @@ dwarf2out_abstract_function (decl)
decl = DECL_ORIGIN (decl);
old_die = lookup_decl_die (decl);
- if (old_die && get_AT_unsigned (old_die, DW_AT_inline))
+ if (old_die && get_AT (old_die, DW_AT_inline))
/* We've already generated the abstract instance. */
return;
@@ -10613,9 +10772,7 @@ dwarf2out_abstract_function (decl)
block-local). */
static void
-gen_subprogram_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_subprogram_die (tree decl, dw_die_ref context_die)
{
char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
tree origin = decl_ultimate_origin (decl);
@@ -10625,7 +10782,7 @@ gen_subprogram_die (decl, context_die)
tree outer_scope;
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (current_function_decl != decl
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
/* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we
started to generate the abstract instance of an inline, decided to output
@@ -10634,7 +10791,7 @@ gen_subprogram_die (decl, context_die)
we'll get back to the abstract instance when done with the class. */
/* The class-scope declaration DIE must be the primary DIE. */
- if (origin && declaration && class_scope_p (context_die))
+ if (origin && declaration && class_or_namespace_scope_p (context_die))
{
origin = NULL;
if (old_die)
@@ -10662,7 +10819,7 @@ gen_subprogram_die (decl, context_die)
/* We can have a normal definition following an inline one in the
case of redefinition of GNU C extern inlines.
It seems reasonable to use AT_specification in this case. */
- && !get_AT_unsigned (old_die, DW_AT_inline))
+ && !get_AT (old_die, DW_AT_inline))
{
/* ??? This can happen if there is a bug in the program, for
instance, if it has duplicate function definitions. Ideally,
@@ -10696,7 +10853,7 @@ gen_subprogram_die (decl, context_die)
else
{
subr_die = new_die (DW_TAG_subprogram, context_die, decl);
- add_AT_die_ref (subr_die, DW_AT_specification, old_die);
+ add_AT_specification (subr_die, old_die);
if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index)
add_AT_unsigned (subr_die, DW_AT_decl_file, file_index);
if (get_AT_unsigned (old_die, DW_AT_decl_line)
@@ -10732,7 +10889,7 @@ gen_subprogram_die (decl, context_die)
if (declaration)
{
- if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+ if (!old_die || !get_AT (old_die, DW_AT_inline))
{
add_AT_flag (subr_die, DW_AT_declaration, 1);
@@ -10746,26 +10903,26 @@ gen_subprogram_die (decl, context_die)
}
else if (DECL_ABSTRACT (decl))
{
- if (DECL_INLINE (decl) && !flag_no_inline)
+ if (DECL_DECLARED_INLINE_P (decl))
{
- /* ??? Checking DECL_DEFER_OUTPUT is correct for static
- inline functions, but not for extern inline functions.
- We can't get this completely correct because information
- about whether the function was declared inline is not
- saved anywhere. */
- if (DECL_DEFER_OUTPUT (decl))
+ if (cgraph_function_possibly_inlined_p (decl))
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined);
else
- add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
}
else
- add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
+ {
+ if (cgraph_function_possibly_inlined_p (decl))
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+ else
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined);
+ }
equate_decl_number_to_die (decl, subr_die);
}
else if (!DECL_EXTERNAL (decl))
{
- if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+ if (!old_die || !get_AT (old_die, DW_AT_inline))
equate_decl_number_to_die (decl, subr_die);
ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL,
@@ -10784,8 +10941,8 @@ gen_subprogram_die (decl, context_die)
#endif
/* Define the "frame base" location for this routine. We use the
- frame pointer or stack pointer registers, since the RTL for local
- variables is relative to one of them. */
+ frame pointer or stack pointer registers, since the RTL for local
+ variables is relative to one of them. */
fp_reg
= frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
@@ -10818,12 +10975,12 @@ gen_subprogram_die (decl, context_die)
gen_formal_types_die (decl, subr_die);
else
{
- /* Generate DIEs to represent all known formal parameters */
+ /* Generate DIEs to represent all known formal parameters. */
tree arg_decls = DECL_ARGUMENTS (decl);
tree parm;
/* When generating DIEs, generate the unspecified_parameters DIE
- instead if we come across the arg "__builtin_va_alist" */
+ instead if we come across the arg "__builtin_va_alist" */
for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
if (TREE_CODE (parm) == PARM_DECL)
{
@@ -10836,15 +10993,15 @@ gen_subprogram_die (decl, context_die)
}
/* Decide whether we need an unspecified_parameters DIE at the end.
- There are 2 more cases to do this for: 1) the ansi ... declaration -
- this is detectable when the end of the arg list is not a
- void_type_node 2) an unprototyped function declaration (not a
- definition). This just means that we have no info about the
- parameters at all. */
+ There are 2 more cases to do this for: 1) the ansi ... declaration -
+ this is detectable when the end of the arg list is not a
+ void_type_node 2) an unprototyped function declaration (not a
+ definition). This just means that we have no info about the
+ parameters at all. */
fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
if (fn_arg_types != NULL)
{
- /* this is the prototyped case, check for ... */
+ /* This is the prototyped case, check for.... */
if (TREE_VALUE (tree_last (fn_arg_types)) != void_type_node)
gen_unspecified_parameters_die (decl, subr_die);
}
@@ -10892,16 +11049,14 @@ gen_subprogram_die (decl, context_die)
/* Generate a DIE to represent a declared data object. */
static void
-gen_variable_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_variable_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl);
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl)
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
if (origin != NULL)
add_abstract_origin_attribute (var_die, origin);
@@ -10918,7 +11073,7 @@ gen_variable_die (decl, context_die)
&& get_AT_flag (old_die, DW_AT_declaration) == 1)
{
/* This is a definition of a C++ class level static. */
- add_AT_die_ref (var_die, DW_AT_specification, old_die);
+ add_AT_specification (var_die, old_die);
if (DECL_NAME (decl))
{
unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
@@ -10954,7 +11109,7 @@ gen_variable_die (decl, context_die)
if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1);
- if (class_scope_p (context_die) || DECL_ABSTRACT (decl))
+ if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl))
equate_decl_number_to_die (decl, var_die);
if (! declaration && ! DECL_ABSTRACT (decl))
@@ -10969,9 +11124,7 @@ gen_variable_die (decl, context_die)
/* Generate a DIE to represent a label identifier. */
static void
-gen_label_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_label_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref lbl_die = new_die (DW_TAG_label, context_die, decl);
@@ -10987,14 +11140,15 @@ gen_label_die (decl, context_die)
equate_decl_number_to_die (decl, lbl_die);
else
{
- insn = DECL_RTL (decl);
+ insn = DECL_RTL_IF_SET (decl);
/* Deleted labels are programmer specified labels which have been
- eliminated because of various optimisations. We still emit them
+ eliminated because of various optimizations. We still emit them
here so that it is possible to put breakpoints on them. */
- if (GET_CODE (insn) == CODE_LABEL
- || ((GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
+ if (insn
+ && (GET_CODE (insn) == CODE_LABEL
+ || ((GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))))
{
/* When optimization is enabled (via -O) some parts of the compiler
(e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
@@ -11013,10 +11167,7 @@ gen_label_die (decl, context_die)
/* Generate a DIE for a lexical block. */
static void
-gen_lexical_block_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
{
dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -11055,10 +11206,7 @@ gen_lexical_block_die (stmt, context_die, depth)
/* Generate a DIE for an inlined subprogram. */
static void
-gen_inlined_subroutine_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
{
tree decl = block_ultimate_origin (stmt);
@@ -11103,15 +11251,13 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
/* Generate a DIE for a field in a record, or structure. */
static void
-gen_field_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_field_die (tree decl, dw_die_ref context_die)
{
dw_die_ref decl_die;
if (TREE_TYPE (decl) == error_mark_node)
return;
-
+
decl_die = new_die (DW_TAG_member, context_die, decl);
add_name_and_src_coords_attributes (decl_die, decl);
add_type_attribute (decl_die, member_declared_type (decl),
@@ -11144,9 +11290,7 @@ gen_field_die (decl, context_die)
represent certain things in other languages (e.g. Pascal) someday. */
static void
-gen_pointer_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_pointer_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ptr_die
= new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type);
@@ -11162,9 +11306,7 @@ gen_pointer_type_die (type, context_die)
represent certain things in other languages (e.g. Pascal) someday. */
static void
-gen_reference_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_reference_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ref_die
= new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type);
@@ -11178,9 +11320,7 @@ gen_reference_type_die (type, context_die)
/* Generate a DIE for a pointer to a member type. */
static void
-gen_ptr_to_mbr_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ptr_die
= new_die (DW_TAG_ptr_to_member_type,
@@ -11195,20 +11335,22 @@ gen_ptr_to_mbr_type_die (type, context_die)
/* Generate the DIE for the compilation unit. */
static dw_die_ref
-gen_compile_unit_die (filename)
- const char *filename;
+gen_compile_unit_die (const char *filename)
{
dw_die_ref die;
char producer[250];
- const char *wd = getpwd ();
const char *language_string = lang_hooks.name;
int language;
die = new_die (DW_TAG_compile_unit, NULL, NULL);
- add_name_attribute (die, filename);
- if (wd != NULL && filename[0] != DIR_SEPARATOR)
- add_AT_string (die, DW_AT_comp_dir, wd);
+ if (filename)
+ {
+ add_name_attribute (die, filename);
+ /* Don't add cwd for <built-in>. */
+ if (filename[0] != DIR_SEPARATOR && filename[0] != '<')
+ add_comp_dir_attribute (die);
+ }
sprintf (producer, "%s %s", language_string, version_string);
@@ -11228,7 +11370,7 @@ gen_compile_unit_die (filename)
if (strcmp (language_string, "GNU C++") == 0)
language = DW_LANG_C_plus_plus;
else if (strcmp (language_string, "GNU Ada") == 0)
- language = DW_LANG_Ada83;
+ language = DW_LANG_Ada95;
else if (strcmp (language_string, "GNU F77") == 0)
language = DW_LANG_Fortran77;
else if (strcmp (language_string, "GNU Pascal") == 0)
@@ -11245,9 +11387,7 @@ gen_compile_unit_die (filename)
/* Generate a DIE for a string type. */
static void
-gen_string_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_string_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die
= new_die (DW_TAG_string_type, scope_die_for (type, context_die), type);
@@ -11265,9 +11405,7 @@ gen_string_type_die (type, context_die)
/* Generate the DIE for a base class. */
static void
-gen_inheritance_die (binfo, context_die)
- tree binfo;
- dw_die_ref context_die;
+gen_inheritance_die (tree binfo, tree access, dw_die_ref context_die)
{
dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo);
@@ -11277,20 +11415,19 @@ gen_inheritance_die (binfo, context_die)
if (TREE_VIA_VIRTUAL (binfo))
add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);
- if (TREE_VIA_PUBLIC (binfo))
+ if (access == access_public_node)
add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public);
- else if (TREE_VIA_PROTECTED (binfo))
+ else if (access == access_protected_node)
add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected);
}
/* Generate a DIE for a class member. */
static void
-gen_member_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_member_die (tree type, dw_die_ref context_die)
{
tree member;
+ tree binfo = TYPE_BINFO (type);
dw_die_ref child;
/* If this is not an incomplete type, output descriptions of each of its
@@ -11306,14 +11443,17 @@ gen_member_die (type, context_die)
the TREE node representing the appropriate (containing) type. */
/* First output info about the base classes. */
- if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
+ if (binfo && BINFO_BASETYPES (binfo))
{
- tree bases = TYPE_BINFO_BASETYPES (type);
+ tree bases = BINFO_BASETYPES (binfo);
+ tree accesses = BINFO_BASEACCESSES (binfo);
int n_bases = TREE_VEC_LENGTH (bases);
int i;
for (i = 0; i < n_bases; i++)
- gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die);
+ gen_inheritance_die (TREE_VEC_ELT (bases, i),
+ (accesses ? TREE_VEC_ELT (accesses, i)
+ : access_public_node), context_die);
}
/* Now output info about the data members and type members. */
@@ -11351,9 +11491,7 @@ gen_member_die (type, context_die)
member DIEs needed by later specification DIEs. */
static void
-gen_struct_or_union_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = lookup_type_die (type);
dw_die_ref scope_die = 0;
@@ -11361,12 +11499,14 @@ gen_struct_or_union_type_die (type, context_die)
int complete = (TYPE_SIZE (type)
&& (! TYPE_STUB_DECL (type)
|| ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
+ int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
if (type_die && ! complete)
return;
if (TYPE_CONTEXT (type) != NULL_TREE
- && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)))
+ && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
+ || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL))
nested = 1;
scope_die = scope_die_for (type, context_die);
@@ -11381,7 +11521,7 @@ gen_struct_or_union_type_die (type, context_die)
scope_die, type);
equate_type_number_to_die (type, type_die);
if (old_die)
- add_AT_die_ref (type_die, DW_AT_specification, old_die);
+ add_AT_specification (type_die, old_die);
else
add_name_attribute (type_die, type_tag (type));
}
@@ -11390,10 +11530,10 @@ gen_struct_or_union_type_die (type, context_die)
/* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */
- if (complete)
+ if (complete && !ns_decl)
{
/* Prevent infinite recursion in cases where the type of some member of
- this type is expressed in terms of this type itself. */
+ this type is expressed in terms of this type itself. */
TREE_ASM_WRITTEN (type) = 1;
add_byte_size_attribute (type_die, type);
if (TYPE_STUB_DECL (type) != NULL_TREE)
@@ -11432,9 +11572,7 @@ gen_struct_or_union_type_die (type, context_die)
/* Generate a DIE for a subroutine _type_. */
static void
-gen_subroutine_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_subroutine_type_die (tree type, dw_die_ref context_die)
{
tree return_type = TREE_TYPE (type);
dw_die_ref subr_die
@@ -11447,12 +11585,10 @@ gen_subroutine_type_die (type, context_die)
gen_formal_types_die (type, subr_die);
}
-/* Generate a DIE for a type definition */
+/* Generate a DIE for a type definition. */
static void
-gen_typedef_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_typedef_die (tree decl, dw_die_ref context_die)
{
dw_die_ref type_die;
tree origin;
@@ -11493,9 +11629,7 @@ gen_typedef_die (decl, context_die)
/* Generate a type description DIE. */
static void
-gen_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_type_die (tree type, dw_die_ref context_die)
{
int need_pop;
@@ -11543,7 +11677,7 @@ gen_type_die (type, context_die)
TREE_ASM_WRITTEN (type) = 1;
/* For these types, all that is required is that we output a DIE (or a
- set of DIEs) to represent the "basis" type. */
+ set of DIEs) to represent the "basis" type. */
gen_type_die (TREE_TYPE (type), context_die);
break;
@@ -11556,7 +11690,7 @@ gen_type_die (type, context_die)
gen_type_die (TREE_TYPE (type), context_die);
/* Now output a DIE to represent this pointer-to-data-member type
- itself. */
+ itself. */
gen_ptr_to_mbr_type_die (type, context_die);
break;
@@ -11601,11 +11735,11 @@ gen_type_die (type, context_die)
case UNION_TYPE:
case QUAL_UNION_TYPE:
/* If this is a nested type whose containing class hasn't been written
- out yet, writing it out will cover this one, too. This does not apply
- to instantiations of member class templates; they need to be added to
- the containing class as they are generated. FIXME: This hurts the
- idea of combining type decls from multiple TUs, since we can't predict
- what set of template instantiations we'll get. */
+ out yet, writing it out will cover this one, too. This does not apply
+ to instantiations of member class templates; they need to be added to
+ the containing class as they are generated. FIXME: This hurts the
+ idea of combining type decls from multiple TUs, since we can't predict
+ what set of template instantiations we'll get. */
if (TYPE_CONTEXT (type)
&& AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
@@ -11621,7 +11755,10 @@ gen_type_die (type, context_die)
need_pop = 1;
}
else
- need_pop = 0;
+ {
+ declare_in_namespace (type, context_die);
+ need_pop = 0;
+ }
if (TREE_CODE (type) == ENUMERAL_TYPE)
gen_enumeration_type_die (type, context_die);
@@ -11659,9 +11796,7 @@ gen_type_die (type, context_die)
/* Generate a DIE for a tagged type instantiation. */
static void
-gen_tagged_type_instantiation_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_tagged_type_instantiation_die (tree type, dw_die_ref context_die)
{
if (type == NULL_TREE || type == error_mark_node)
return;
@@ -11703,10 +11838,7 @@ gen_tagged_type_instantiation_die (type, context_die)
things which are local to the given block. */
static void
-gen_block_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_block_die (tree stmt, dw_die_ref context_die, int depth)
{
int must_output_die = 0;
tree origin;
@@ -11748,12 +11880,12 @@ gen_block_die (stmt, context_die, depth)
else
{
/* In the case where the current block represents an inlining of the
- "body block" of an inline function, we must *NOT* output any DIE for
- this block because we have already output a DIE to represent the whole
- inlined function scope and the "body block" of any function doesn't
- really represent a different scope according to ANSI C rules. So we
- check here to make sure that this block does not represent a "body
- block inlining" before trying to set the MUST_OUTPUT_DIE flag. */
+ "body block" of an inline function, we must *NOT* output any DIE for
+ this block because we have already output a DIE to represent the whole
+ inlined function scope and the "body block" of any function doesn't
+ really represent a different scope according to ANSI C rules. So we
+ check here to make sure that this block does not represent a "body
+ block inlining" before trying to set the MUST_OUTPUT_DIE flag. */
if (! is_body_block (origin ? origin : stmt))
{
/* Determine if this block directly contains any "significant"
@@ -11798,10 +11930,7 @@ gen_block_die (stmt, context_die, depth)
all of its sub-blocks. */
static void
-decls_for_scope (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
{
tree decl;
tree subblocks;
@@ -11846,8 +11975,7 @@ decls_for_scope (stmt, context_die, depth)
/* Is this a typedef we can avoid emitting? */
static inline int
-is_redundant_typedef (decl)
- tree decl;
+is_redundant_typedef (tree decl)
{
if (TYPE_DECL_IS_STUB (decl))
return 1;
@@ -11863,12 +11991,102 @@ is_redundant_typedef (decl)
return 0;
}
+/* Returns the DIE for namespace NS or aborts.
+
+ Note that namespaces don't really have a lexical context, so there's no
+ need to pass in a context_die. They always go inside their containing
+ namespace, or comp_unit_die if none. */
+
+static dw_die_ref
+force_namespace_die (tree ns)
+{
+ dw_die_ref ns_die;
+
+ dwarf2out_decl (ns);
+ ns_die = lookup_decl_die (ns);
+ if (!ns_die)
+ abort();
+
+ return ns_die;
+}
+
+/* Force out any required namespaces to be able to output DECL,
+ and return the new context_die for it, if it's changed. */
+
+static dw_die_ref
+setup_namespace_context (tree thing, dw_die_ref context_die)
+{
+ tree context = DECL_P (thing) ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing);
+ if (context && TREE_CODE (context) == NAMESPACE_DECL)
+ /* Force out the namespace. */
+ context_die = force_namespace_die (context);
+
+ return context_die;
+}
+
+/* Emit a declaration DIE for THING (which is either a DECL or a tagged
+ type) within its namespace, if appropriate.
+
+ For compatibility with older debuggers, namespace DIEs only contain
+ declarations; all definitions are emitted at CU scope. */
+
+static void
+declare_in_namespace (tree thing, dw_die_ref context_die)
+{
+ dw_die_ref ns_context;
+
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+
+ ns_context = setup_namespace_context (thing, context_die);
+
+ if (ns_context != context_die)
+ {
+ if (DECL_P (thing))
+ gen_decl_die (thing, ns_context);
+ else
+ gen_type_die (thing, ns_context);
+ }
+}
+
+/* Generate a DIE for a namespace or namespace alias. */
+
+static void
+gen_namespace_die (tree decl)
+{
+ dw_die_ref context_die = setup_namespace_context (decl, comp_unit_die);
+
+ /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
+ they are an alias of. */
+ if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
+ {
+ /* Output a real namespace. */
+ dw_die_ref namespace_die
+ = new_die (DW_TAG_namespace, context_die, decl);
+ add_name_and_src_coords_attributes (namespace_die, decl);
+ equate_decl_number_to_die (decl, namespace_die);
+ }
+ else
+ {
+ /* Output a namespace alias. */
+
+ /* Force out the namespace we are an alias of, if necessary. */
+ dw_die_ref origin_die
+ = force_namespace_die (DECL_ABSTRACT_ORIGIN (decl));
+
+ /* Now create the namespace alias DIE. */
+ dw_die_ref namespace_die
+ = new_die (DW_TAG_imported_declaration, context_die, decl);
+ add_name_and_src_coords_attributes (namespace_die, decl);
+ add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
+ equate_decl_number_to_die (decl, namespace_die);
+ }
+}
+
/* Generate Dwarf debug information for a decl described by DECL. */
static void
-gen_decl_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_decl_die (tree decl, dw_die_ref context_die)
{
tree origin;
@@ -11882,7 +12100,7 @@ gen_decl_die (decl, context_die)
case CONST_DECL:
/* The individual enumerators of an enum type get output when we output
- the Dwarf representation of the relevant enum type itself. */
+ the Dwarf representation of the relevant enum type itself. */
break;
case FUNCTION_DECL:
@@ -11898,8 +12116,9 @@ gen_decl_die (decl, context_die)
/* If we're emitting an out-of-line copy of an inline function,
emit info for the abstract instance and set up to refer to it. */
- else if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
- && ! class_scope_p (context_die)
+ else if (cgraph_function_possibly_inlined_p (decl)
+ && ! DECL_ABSTRACT (decl)
+ && ! class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */
@@ -11924,6 +12143,9 @@ gen_decl_die (decl, context_die)
origin = decl_class_context (decl);
if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die);
+
+ /* And its containing namespace. */
+ declare_in_namespace (decl, context_die);
}
/* Now output a DIE to represent the function itself. */
@@ -11932,16 +12154,16 @@ gen_decl_die (decl, context_die)
case TYPE_DECL:
/* If we are in terse mode, don't generate any DIEs to represent any
- actual typedefs. */
+ actual typedefs. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
/* In the special case of a TYPE_DECL node representing the declaration
- of some type tag, if the given TYPE_DECL is marked as having been
- instantiated from some other (original) TYPE_DECL node (e.g. one which
- was generated within the original definition of an inline function) we
- have to generate a special (abbreviated) DW_TAG_structure_type,
- DW_TAG_union_type, or DW_TAG_enumeration_type DIE here. */
+ of some type tag, if the given TYPE_DECL is marked as having been
+ instantiated from some other (original) TYPE_DECL node (e.g. one which
+ was generated within the original definition of an inline function) we
+ have to generate a special (abbreviated) DW_TAG_structure_type,
+ DW_TAG_union_type, or DW_TAG_enumeration_type DIE here. */
if (TYPE_DECL_IS_STUB (decl) && decl_ultimate_origin (decl) != NULL_TREE)
{
gen_tagged_type_instantiation_die (TREE_TYPE (decl), context_die);
@@ -11962,12 +12184,12 @@ gen_decl_die (decl, context_die)
case VAR_DECL:
/* If we are in terse mode, don't generate any DIEs to represent any
- variable declarations or definitions. */
+ variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
/* Output any DIEs that are needed to specify the type of this data
- object. */
+ object. */
gen_type_die (TREE_TYPE (decl), context_die);
/* And its containing type. */
@@ -11975,10 +12197,13 @@ gen_decl_die (decl, context_die)
if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die);
+ /* And its containing namespace. */
+ declare_in_namespace (decl, context_die);
+
/* Now output the DIE to represent the data object itself. This gets
- complicated because of the possibility that the VAR_DECL really
- represents an inlined instance of a formal parameter for an inline
- function. */
+ complicated because of the possibility that the VAR_DECL really
+ represents an inlined instance of a formal parameter for an inline
+ function. */
origin = decl_ultimate_origin (decl);
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
gen_formal_parameter_die (decl, context_die);
@@ -12003,29 +12228,21 @@ gen_decl_die (decl, context_die)
break;
case NAMESPACE_DECL:
- /* Ignore for now. */
+ gen_namespace_die (decl);
break;
default:
+ if ((int)TREE_CODE (decl) > NUM_TREE_CODES)
+ /* Probably some frontend-internal decl. Assume we don't care. */
+ break;
abort ();
}
}
-
-static void
-mark_limbo_die_list (ptr)
- void *ptr ATTRIBUTE_UNUSED;
-{
- limbo_die_node *node;
- for (node = limbo_die_list; node; node = node->next)
- ggc_mark_tree (node->created_for);
-}
/* Add Ada "use" clause information for SGI Workshop debugger. */
void
-dwarf2out_add_library_unit_info (filename, context_list)
- const char *filename;
- const char *context_list;
+dwarf2out_add_library_unit_info (const char *filename, const char *context_list)
{
unsigned int file_index;
@@ -12048,8 +12265,7 @@ dwarf2out_add_library_unit_info (filename, context_list)
compilation proper has finished. */
static void
-dwarf2out_global_decl (decl)
- tree decl;
+dwarf2out_global_decl (tree decl)
{
/* Output DWARF2 information for file-scope tentative data object
declarations, file-scope (extern) function declarations (which had no
@@ -12062,8 +12278,7 @@ dwarf2out_global_decl (decl)
/* Write the debugging output for DECL. */
void
-dwarf2out_decl (decl)
- tree decl;
+dwarf2out_decl (tree decl)
{
dw_die_ref context_die = comp_unit_die;
@@ -12073,33 +12288,27 @@ dwarf2out_decl (decl)
return;
case FUNCTION_DECL:
- /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of a
- builtin function. Explicit programmer-supplied declarations of
- these same functions should NOT be ignored however. */
- if (DECL_EXTERNAL (decl) && DECL_BUILT_IN (decl))
- return;
-
/* What we would really like to do here is to filter out all mere
- file-scope declarations of file-scope functions which are never
- referenced later within this translation unit (and keep all of ones
- that *are* referenced later on) but we aren't clairvoyant, so we have
- no idea which functions will be referenced in the future (i.e. later
- on within the current translation unit). So here we just ignore all
- file-scope function declarations which are not also definitions. If
- and when the debugger needs to know something about these functions,
- it will have to hunt around and find the DWARF information associated
- with the definition of the function.
+ file-scope declarations of file-scope functions which are never
+ referenced later within this translation unit (and keep all of ones
+ that *are* referenced later on) but we aren't clairvoyant, so we have
+ no idea which functions will be referenced in the future (i.e. later
+ on within the current translation unit). So here we just ignore all
+ file-scope function declarations which are not also definitions. If
+ and when the debugger needs to know something about these functions,
+ it will have to hunt around and find the DWARF information associated
+ with the definition of the function.
We can't just check DECL_EXTERNAL to find out which FUNCTION_DECL
- nodes represent definitions and which ones represent mere
- declarations. We have to check DECL_INITIAL instead. That's because
- the C front-end supports some weird semantics for "extern inline"
- function definitions. These can get inlined within the current
- translation unit (an thus, we need to generate Dwarf info for their
- abstract instances so that the Dwarf info for the concrete inlined
- instances can have something to refer to) but the compiler never
- generates any out-of-lines instances of such things (despite the fact
- that they *are* definitions).
+ nodes represent definitions and which ones represent mere
+ declarations. We have to check DECL_INITIAL instead. That's because
+ the C front-end supports some weird semantics for "extern inline"
+ function definitions. These can get inlined within the current
+ translation unit (an thus, we need to generate Dwarf info for their
+ abstract instances so that the Dwarf info for the concrete inlined
+ instances can have something to refer to) but the compiler never
+ generates any out-of-lines instances of such things (despite the fact
+ that they *are* definitions).
The important point is that the C front-end marks these "extern
inline" functions as DECL_EXTERNAL, but we need to generate DWARF for
@@ -12120,33 +12329,40 @@ dwarf2out_decl (decl)
case VAR_DECL:
/* Ignore this VAR_DECL if it refers to a file-scope extern data object
- declaration and if the declaration was never even referenced from
- within this entire compilation unit. We suppress these DIEs in
- order to save space in the .debug section (by eliminating entries
- which are probably useless). Note that we must not suppress
- block-local extern declarations (whether used or not) because that
- would screw-up the debugger's name lookup mechanism and cause it to
- miss things which really ought to be in scope at a given point. */
+ declaration and if the declaration was never even referenced from
+ within this entire compilation unit. We suppress these DIEs in
+ order to save space in the .debug section (by eliminating entries
+ which are probably useless). Note that we must not suppress
+ block-local extern declarations (whether used or not) because that
+ would screw-up the debugger's name lookup mechanism and cause it to
+ miss things which really ought to be in scope at a given point. */
if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
return;
/* If we are in terse mode, don't generate any DIEs to represent any
- variable declarations or definitions. */
+ variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
break;
+ case NAMESPACE_DECL:
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+ if (lookup_decl_die (decl) != NULL)
+ return;
+ break;
+
case TYPE_DECL:
/* Don't emit stubs for types unless they are needed by other DIEs. */
if (TYPE_DECL_SUPPRESS_DEBUG (decl))
return;
/* Don't bother trying to generate any DIEs to represent any of the
- normal built-in types for the language we are compiling. */
+ normal built-in types for the language we are compiling. */
if (DECL_SOURCE_LINE (decl) == 0)
{
/* OK, we need to generate one for `bool' so GDB knows what type
- comparisons have. */
+ comparisons have. */
if ((get_AT_unsigned (comp_unit_die, DW_AT_language)
== DW_LANG_C_plus_plus)
&& TREE_CODE (TREE_TYPE (decl)) == BOOLEAN_TYPE
@@ -12178,9 +12394,8 @@ dwarf2out_decl (decl)
a lexical block. */
static void
-dwarf2out_begin_block (line, blocknum)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int blocknum;
+dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
+ unsigned int blocknum)
{
function_section (current_function_decl);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
@@ -12190,9 +12405,7 @@ dwarf2out_begin_block (line, blocknum)
lexical block. */
static void
-dwarf2out_end_block (line, blocknum)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int blocknum;
+dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
{
function_section (current_function_decl);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
@@ -12206,8 +12419,7 @@ dwarf2out_end_block (line, blocknum)
we may end up calling them anyway. */
static bool
-dwarf2out_ignore_block (block)
- tree block;
+dwarf2out_ignore_block (tree block)
{
tree decl;
@@ -12231,65 +12443,70 @@ dwarf2out_ignore_block (block)
all searches. */
static unsigned
-lookup_filename (file_name)
- const char *file_name;
+lookup_filename (const char *file_name)
{
- unsigned i;
-
- /* ??? Why isn't DECL_SOURCE_FILE left null instead. */
- if (strcmp (file_name, "<internal>") == 0
- || strcmp (file_name, "<built-in>") == 0)
- return 0;
+ size_t i, n;
+ char *save_file_name;
/* Check to see if the file name that was searched on the previous
call matches this file name. If so, return the index. */
- if (file_table.last_lookup_index != 0)
- if (0 == strcmp (file_name,
- file_table.table[file_table.last_lookup_index]))
- return file_table.last_lookup_index;
+ if (file_table_last_lookup_index != 0)
+ {
+ const char *last
+ = VARRAY_CHAR_PTR (file_table, file_table_last_lookup_index);
+ if (strcmp (file_name, last) == 0)
+ return file_table_last_lookup_index;
+ }
/* Didn't match the previous lookup, search the table */
- for (i = 1; i < file_table.in_use; i++)
- if (strcmp (file_name, file_table.table[i]) == 0)
+ n = VARRAY_ACTIVE_SIZE (file_table);
+ for (i = 1; i < n; i++)
+ if (strcmp (file_name, VARRAY_CHAR_PTR (file_table, i)) == 0)
{
- file_table.last_lookup_index = i;
+ file_table_last_lookup_index = i;
return i;
}
- /* Prepare to add a new table entry by making sure there is enough space in
- the table to do so. If not, expand the current table. */
- if (i == file_table.allocated)
- {
- file_table.allocated = i + FILE_TABLE_INCREMENT;
- file_table.table = (char **)
- xrealloc (file_table.table, file_table.allocated * sizeof (char *));
- }
-
/* Add the new entry to the end of the filename table. */
- file_table.table[i] = xstrdup (file_name);
- file_table.in_use = i + 1;
- file_table.last_lookup_index = i;
+ file_table_last_lookup_index = n;
+ save_file_name = (char *) ggc_strdup (file_name);
+ VARRAY_PUSH_CHAR_PTR (file_table, save_file_name);
+ VARRAY_PUSH_UINT (file_table_emitted, 0);
- if (DWARF2_ASM_LINE_DEBUG_INFO)
+ return i;
+}
+
+static int
+maybe_emit_file (int fileno)
+{
+ if (DWARF2_ASM_LINE_DEBUG_INFO && fileno > 0)
{
- fprintf (asm_out_file, "\t.file %u ", i);
- output_quoted_string (asm_out_file, file_name);
- fputc ('\n', asm_out_file);
+ if (!VARRAY_UINT (file_table_emitted, fileno))
+ {
+ VARRAY_UINT (file_table_emitted, fileno) = ++emitcount;
+ fprintf (asm_out_file, "\t.file %u ",
+ VARRAY_UINT (file_table_emitted, fileno));
+ output_quoted_string (asm_out_file,
+ VARRAY_CHAR_PTR (file_table, fileno));
+ fputc ('\n', asm_out_file);
+ }
+ return VARRAY_UINT (file_table_emitted, fileno);
}
-
- return i;
+ else
+ return fileno;
}
static void
-init_file_table ()
+init_file_table (void)
{
/* Allocate the initial hunk of the file_table. */
- file_table.table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
- file_table.allocated = FILE_TABLE_INCREMENT;
+ VARRAY_CHAR_PTR_INIT (file_table, 64, "file_table");
+ VARRAY_UINT_INIT (file_table_emitted, 64, "file_table_emitted");
/* Skip the first entry - file numbers begin at 1. */
- file_table.in_use = 1;
- file_table.last_lookup_index = 0;
+ VARRAY_PUSH_CHAR_PTR (file_table, NULL);
+ VARRAY_PUSH_UINT (file_table_emitted, 0);
+ file_table_last_lookup_index = 0;
}
/* Output a label to mark the beginning of a source code line entry
@@ -12297,11 +12514,10 @@ init_file_table ()
'line_info_table' for later output of the .debug_line section. */
static void
-dwarf2out_source_line (line, filename)
- unsigned int line;
- const char *filename;
+dwarf2out_source_line (unsigned int line, const char *filename)
{
- if (debug_info_level >= DINFO_LEVEL_NORMAL)
+ if (debug_info_level >= DINFO_LEVEL_NORMAL
+ && line != 0)
{
function_section (current_function_decl);
@@ -12314,6 +12530,8 @@ dwarf2out_source_line (line, filename)
{
unsigned file_num = lookup_filename (filename);
+ file_num = maybe_emit_file (file_num);
+
/* Emit the .loc directive understood by GNU as. */
fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line);
@@ -12327,7 +12545,7 @@ dwarf2out_source_line (line, filename)
else if (DECL_SECTION_NAME (current_function_decl))
{
dw_separate_line_info_ref line_info;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
+ (*targetm.asm_out.internal_label) (asm_out_file, SEPARATE_LINE_CODE_LABEL,
separate_line_info_table_in_use);
/* expand the line info table if necessary */
@@ -12336,10 +12554,14 @@ dwarf2out_source_line (line, filename)
{
separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
separate_line_info_table
- = (dw_separate_line_info_ref)
- xrealloc (separate_line_info_table,
- separate_line_info_table_allocated
- * sizeof (dw_separate_line_info_entry));
+ = ggc_realloc (separate_line_info_table,
+ separate_line_info_table_allocated
+ * sizeof (dw_separate_line_info_entry));
+ memset (separate_line_info_table
+ + separate_line_info_table_in_use,
+ 0,
+ (LINE_INFO_TABLE_INCREMENT
+ * sizeof (dw_separate_line_info_entry)));
}
/* Add the new entry at the end of the line_info_table. */
@@ -12353,7 +12575,7 @@ dwarf2out_source_line (line, filename)
{
dw_line_info_ref line_info;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
+ (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
line_info_table_in_use);
/* Expand the line info table if necessary. */
@@ -12361,10 +12583,11 @@ dwarf2out_source_line (line, filename)
{
line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
line_info_table
- = (dw_line_info_ref)
- xrealloc (line_info_table,
- (line_info_table_allocated
- * sizeof (dw_line_info_entry)));
+ = ggc_realloc (line_info_table,
+ (line_info_table_allocated
+ * sizeof (dw_line_info_entry)));
+ memset (line_info_table + line_info_table_in_use, 0,
+ LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
}
/* Add the new entry at the end of the line_info_table. */
@@ -12378,11 +12601,9 @@ dwarf2out_source_line (line, filename)
/* Record the beginning of a new source file. */
static void
-dwarf2out_start_source_file (lineno, filename)
- unsigned int lineno;
- const char *filename;
+dwarf2out_start_source_file (unsigned int lineno, const char *filename)
{
- if (flag_eliminate_dwarf2_dups && !is_main_source)
+ if (flag_eliminate_dwarf2_dups)
{
/* Record the beginning of the file for break_out_includes. */
dw_die_ref bincl_die;
@@ -12391,14 +12612,13 @@ dwarf2out_start_source_file (lineno, filename)
add_AT_string (bincl_die, DW_AT_name, filename);
}
- is_main_source = 0;
-
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
dw2_asm_output_data_uleb128 (lineno, "Included from line number %d",
lineno);
+ maybe_emit_file (lookup_filename (filename));
dw2_asm_output_data_uleb128 (lookup_filename (filename),
"Filename we just started");
}
@@ -12407,8 +12627,7 @@ dwarf2out_start_source_file (lineno, filename)
/* Record the end of a source file. */
static void
-dwarf2out_end_source_file (lineno)
- unsigned int lineno ATTRIBUTE_UNUSED;
+dwarf2out_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
{
if (flag_eliminate_dwarf2_dups)
/* Record the end of the file for break_out_includes. */
@@ -12426,9 +12645,8 @@ dwarf2out_end_source_file (lineno)
initial whitespace, #, whitespace, directive-name, whitespace part. */
static void
-dwarf2out_define (lineno, buffer)
- unsigned lineno ATTRIBUTE_UNUSED;
- const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED,
+ const char *buffer ATTRIBUTE_UNUSED)
{
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
@@ -12444,9 +12662,8 @@ dwarf2out_define (lineno, buffer)
initial whitespace, #, whitespace, directive-name, whitespace part. */
static void
-dwarf2out_undef (lineno, buffer)
- unsigned lineno ATTRIBUTE_UNUSED;
- const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
+ const char *buffer ATTRIBUTE_UNUSED)
{
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
@@ -12460,22 +12677,13 @@ dwarf2out_undef (lineno, buffer)
/* Set up for Dwarf output at the start of compilation. */
static void
-dwarf2out_init (main_input_filename)
- const char *main_input_filename;
+dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
{
init_file_table ();
- /* Remember the name of the primary input file. */
- primary_filename = main_input_filename;
-
- /* Add it to the file table first, under the assumption that we'll
- be emitting line number data for it first, which avoids having
- to add an initial DW_LNS_set_file. */
- lookup_filename (main_input_filename);
-
/* Allocate the initial hunk of the decl_die_table. */
- decl_die_table
- = (dw_die_ref *) xcalloc (DECL_DIE_TABLE_INCREMENT, sizeof (dw_die_ref));
+ decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT
+ * sizeof (dw_die_ref));
decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
decl_die_table_in_use = 0;
@@ -12483,17 +12691,15 @@ dwarf2out_init (main_input_filename)
VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
/* Allocate the initial hunk of the abbrev_die_table. */
- abbrev_die_table
- = (dw_die_ref *) xcalloc (ABBREV_DIE_TABLE_INCREMENT,
- sizeof (dw_die_ref));
+ abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT
+ * sizeof (dw_die_ref));
abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
abbrev_die_table_in_use = 1;
/* Allocate the initial hunk of the line_info_table. */
- line_info_table
- = (dw_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
- sizeof (dw_line_info_entry));
+ line_info_table = ggc_alloc_cleared (LINE_INFO_TABLE_INCREMENT
+ * sizeof (dw_line_info_entry));
line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
@@ -12503,16 +12709,14 @@ dwarf2out_init (main_input_filename)
value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
will (typically) be a relative pathname and that this pathname should be
taken as being relative to the directory from which the compiler was
- invoked when the given (base) source file was compiled. */
- comp_unit_die = gen_compile_unit_die (main_input_filename);
- is_main_source = 1;
+ invoked when the given (base) source file was compiled. We will fill
+ in this value in dwarf2out_finish. */
+ comp_unit_die = gen_compile_unit_die (NULL);
VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
- ggc_add_root (&limbo_die_list, 1, 1, mark_limbo_die_list);
-
ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
DEBUG_ABBREV_SECTION_LABEL, 0);
@@ -12549,54 +12753,255 @@ dwarf2out_init (main_input_filename)
}
}
-/* Allocate a string in .debug_str hash table. */
-
-static hashnode
-indirect_string_alloc (tab)
- hash_table *tab ATTRIBUTE_UNUSED;
-{
- struct indirect_string_node *node;
-
- node = xmalloc (sizeof (struct indirect_string_node));
- node->refcount = 0;
- node->form = 0;
- node->label = NULL;
-
- return (hashnode) node;
-}
-
/* A helper function for dwarf2out_finish called through
ht_forall. Emit one queued .debug_str string. */
static int
-output_indirect_string (pfile, h, v)
- struct cpp_reader *pfile ATTRIBUTE_UNUSED;
- hashnode h;
- const PTR v ATTRIBUTE_UNUSED;
+output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
{
- struct indirect_string_node *node = (struct indirect_string_node *) h;
+ struct indirect_string_node *node = (struct indirect_string_node *) *h;
if (node->form == DW_FORM_strp)
{
named_section_flags (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS);
ASM_OUTPUT_LABEL (asm_out_file, node->label);
- assemble_string ((const char *) HT_STR (&node->id),
- HT_LEN (&node->id) + 1);
+ assemble_string (node->str, strlen (node->str) + 1);
}
return 1;
}
+
+
+/* Clear the marks for a die and its children.
+ Be cool if the mark isn't set. */
+
+static void
+prune_unmark_dies (dw_die_ref die)
+{
+ dw_die_ref c;
+ die->die_mark = 0;
+ for (c = die->die_child; c; c = c->die_sib)
+ prune_unmark_dies (c);
+}
+
+
+/* Given DIE that we're marking as used, find any other dies
+ it references as attributes and mark them as used. */
+
+static void
+prune_unused_types_walk_attribs (dw_die_ref die)
+{
+ dw_attr_ref a;
+
+ for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
+ {
+ if (a->dw_attr_val.val_class == dw_val_class_die_ref)
+ {
+ /* A reference to another DIE.
+ Make sure that it will get emitted. */
+ prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
+ }
+ else if (a->dw_attr == DW_AT_decl_file)
+ {
+ /* A reference to a file. Make sure the file name is emitted. */
+ a->dw_attr_val.v.val_unsigned =
+ maybe_emit_file (a->dw_attr_val.v.val_unsigned);
+ }
+ }
+}
+
+
+/* Mark DIE as being used. If DOKIDS is true, then walk down
+ to DIE's children. */
+
+static void
+prune_unused_types_mark (dw_die_ref die, int dokids)
+{
+ dw_die_ref c;
+
+ if (die->die_mark == 0)
+ {
+ /* We haven't done this node yet. Mark it as used. */
+ die->die_mark = 1;
+
+ /* We also have to mark its parents as used.
+ (But we don't want to mark our parents' kids due to this.) */
+ if (die->die_parent)
+ prune_unused_types_mark (die->die_parent, 0);
+
+ /* Mark any referenced nodes. */
+ prune_unused_types_walk_attribs (die);
+
+ /* If this node is a specification,
+ also mark the definition, if it exists. */
+ if (get_AT_flag (die, DW_AT_declaration) && die->die_definition)
+ prune_unused_types_mark (die->die_definition, 1);
+ }
+
+ if (dokids && die->die_mark != 2)
+ {
+ /* We need to walk the children, but haven't done so yet.
+ Remember that we've walked the kids. */
+ die->die_mark = 2;
+
+ /* Walk them. */
+ for (c = die->die_child; c; c = c->die_sib)
+ {
+ /* If this is an array type, we need to make sure our
+ kids get marked, even if they're types. */
+ if (die->die_tag == DW_TAG_array_type)
+ prune_unused_types_mark (c, 1);
+ else
+ prune_unused_types_walk (c);
+ }
+ }
+}
+
+
+/* Walk the tree DIE and mark types that we actually use. */
+
+static void
+prune_unused_types_walk (dw_die_ref die)
+{
+ dw_die_ref c;
+
+ /* Don't do anything if this node is already marked. */
+ if (die->die_mark)
+ return;
+
+ switch (die->die_tag) {
+ case DW_TAG_const_type:
+ case DW_TAG_packed_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_typedef:
+ case DW_TAG_array_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ case DW_TAG_friend:
+ case DW_TAG_variant_part:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_string_type:
+ case DW_TAG_set_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_file_type:
+ /* It's a type node --- don't mark it. */
+ return;
+
+ default:
+ /* Mark everything else. */
+ break;
+ }
+
+ die->die_mark = 1;
+
+ /* Now, mark any dies referenced from here. */
+ prune_unused_types_walk_attribs (die);
+
+ /* Mark children. */
+ for (c = die->die_child; c; c = c->die_sib)
+ prune_unused_types_walk (c);
+}
+
+
+/* Remove from the tree DIE any dies that aren't marked. */
+
+static void
+prune_unused_types_prune (dw_die_ref die)
+{
+ dw_die_ref c, p, n;
+ if (!die->die_mark)
+ abort();
+
+ p = NULL;
+ for (c = die->die_child; c; c = n)
+ {
+ n = c->die_sib;
+ if (c->die_mark)
+ {
+ prune_unused_types_prune (c);
+ p = c;
+ }
+ else
+ {
+ if (p)
+ p->die_sib = n;
+ else
+ die->die_child = n;
+ free_die (c);
+ }
+ }
+}
+
+
+/* Remove dies representing declarations that we never use. */
+
+static void
+prune_unused_types (void)
+{
+ unsigned int i;
+ limbo_die_node *node;
+
+ /* Clear all the marks. */
+ prune_unmark_dies (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unmark_dies (node->die);
+
+ /* Set the mark on nodes that are actually used. */
+ prune_unused_types_walk (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unused_types_walk (node->die);
+
+ /* Also set the mark on nodes referenced from the
+ pubname_table or arange_table. */
+ for (i = 0; i < pubname_table_in_use; i++)
+ prune_unused_types_mark (pubname_table[i].die, 1);
+ for (i = 0; i < arange_table_in_use; i++)
+ prune_unused_types_mark (arange_table[i], 1);
+
+ /* Get rid of nodes that aren't marked. */
+ prune_unused_types_prune (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unused_types_prune (node->die);
+
+ /* Leave the marks clear. */
+ prune_unmark_dies (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unmark_dies (node->die);
+}
+
/* Output stuff that dwarf requires at the end of every file,
and generate the DWARF-2 debugging info. */
static void
-dwarf2out_finish (input_filename)
- const char *input_filename ATTRIBUTE_UNUSED;
+dwarf2out_finish (const char *filename)
{
limbo_die_node *node, *next_node;
dw_die_ref die = 0;
+ /* Add the name for the main input file now. We delayed this from
+ dwarf2out_init to avoid complications with PCH. */
+ add_name_attribute (comp_unit_die, filename);
+ if (filename[0] != DIR_SEPARATOR)
+ add_comp_dir_attribute (comp_unit_die);
+ else if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL)
+ {
+ size_t i;
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
+ if (VARRAY_CHAR_PTR (file_table, i)[0] != DIR_SEPARATOR
+ /* Don't add cwd for <built-in>. */
+ && VARRAY_CHAR_PTR (file_table, i)[0] != '<')
+ {
+ add_comp_dir_attribute (comp_unit_die);
+ break;
+ }
+ }
+
/* Traverse the limbo die list, and add parent/child links. The only
dies without parents that should be here are concrete instances of
inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
@@ -12648,8 +13053,6 @@ dwarf2out_finish (input_filename)
else
abort ();
}
-
- free (node);
}
limbo_die_list = NULL;
@@ -12662,6 +13065,9 @@ dwarf2out_finish (input_filename)
we'll see the end of an include file before the beginning. */
reverse_all_dies (comp_unit_die);
+ if (flag_eliminate_unused_debug_types)
+ prune_unused_types ();
+
/* Generate separate CUs for each of the include files we've seen.
They will go into limbo_die_list. */
if (flag_eliminate_dwarf2_dups)
@@ -12675,7 +13081,7 @@ dwarf2out_finish (input_filename)
/* Output a terminator label for the .text section. */
text_section ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
/* Output the source line correspondence table. We must do this
even if there is no line information. Otherwise, on an empty
@@ -12765,7 +13171,7 @@ dwarf2out_finish (input_filename)
/* If we emitted any DW_FORM_strp form attribute, output the string
table too. */
if (debug_str_hash)
- ht_forall (debug_str_hash, output_indirect_string, NULL);
+ htab_traverse (debug_str_hash, output_indirect_string, NULL);
}
#else
OpenPOWER on IntegriCloud