aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c92
1 files changed, 87 insertions, 5 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 901fbff5279..476f6ebf794 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -498,6 +498,8 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN);
#endif
+
+ targetm.init_dwarf_reg_sizes_extra (address);
}
/* Convert a DWARF call frame info. operation to its string name */
@@ -5039,9 +5041,15 @@ add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
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 = (struct indirect_string_node *)
+ ggc_alloc_cleared (sizeof (struct indirect_string_node));
+ node->str = ggc_strdup (str);
+ *slot = node;
+ }
+ else
+ node = (struct indirect_string_node *) *slot;
+
node->refcount++;
attr.dw_attr = attr_kind;
@@ -8811,6 +8819,32 @@ is_based_loc (rtx rtl)
&& GET_CODE (XEXP (rtl, 1)) == CONST_INT)));
}
+/* Return a descriptor that describes the concatenation of N locations
+ used to form the address of a memory location. */
+
+static dw_loc_descr_ref
+concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode)
+{
+ unsigned int i;
+ dw_loc_descr_ref cc_loc_result = NULL;
+ unsigned int n = XVECLEN (concatn, 0);
+
+ for (i = 0; i < n; ++i)
+ {
+ dw_loc_descr_ref ref;
+ rtx x = XVECEXP (concatn, 0, i);
+
+ ref = mem_loc_descriptor (x, mode);
+ if (ref == NULL)
+ return NULL;
+
+ add_loc_descr (&cc_loc_result, ref);
+ add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
+ }
+
+ return cc_loc_result;
+}
+
/* The following routine converts the RTL for a variable or parameter
(resident in memory) into an equivalent Dwarf representation of a
mechanism for getting the address of that same variable onto the top of a
@@ -9006,6 +9040,10 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode)
mem_loc_result = int_loc_descriptor (INTVAL (rtl));
break;
+ case CONCATN:
+ mem_loc_result = concatn_mem_loc_descriptor (rtl, mode);
+ break;
+
default:
gcc_unreachable ();
}
@@ -11221,10 +11259,17 @@ type_tag (tree type)
involved. */
else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& ! DECL_IGNORED_P (TYPE_NAME (type)))
- t = DECL_NAME (TYPE_NAME (type));
+ {
+ /* We want to be extra verbose. Don't call dwarf_name if
+ DECL_NAME isn't set. The default hook for decl_printable_name
+ doesn't like that, and in this context it's correct to return
+ 0, instead of "<anonymous>" or the like. */
+ if (DECL_NAME (TYPE_NAME (type)))
+ name = lang_hooks.dwarf_name (TYPE_NAME (type), 2);
+ }
/* Now get the name as a string, or invent one. */
- if (t != 0)
+ if (!name && t != 0)
name = IDENTIFIER_POINTER (t);
}
@@ -12188,6 +12233,36 @@ add_call_src_coords_attributes (tree stmt, dw_die_ref die)
add_AT_unsigned (die, DW_AT_call_line, s.line);
}
+
+/* If STMT's abstract origin is a function declaration and STMT's
+ first subblock's abstract origin is the function's outermost block,
+ then we're looking at the main entry point. */
+static bool
+is_inlined_entry_point (tree stmt)
+{
+ tree decl, block;
+
+ if (!stmt || TREE_CODE (stmt) != BLOCK)
+ return false;
+
+ decl = block_ultimate_origin (stmt);
+
+ if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+ return false;
+
+ block = BLOCK_SUBBLOCKS (stmt);
+
+ if (block)
+ {
+ if (TREE_CODE (block) != BLOCK)
+ return false;
+
+ block = block_ultimate_origin (block);
+ }
+
+ return block == DECL_INITIAL (decl);
+}
+
/* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
Add low_pc and high_pc attributes to the DIE for a block STMT. */
@@ -12200,6 +12275,13 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
{
tree chain;
+ if (is_inlined_entry_point (stmt))
+ {
+ ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
+ BLOCK_NUMBER (stmt));
+ add_AT_lbl_id (die, DW_AT_entry_pc, label);
+ }
+
add_AT_range_list (die, DW_AT_ranges, add_ranges (stmt));
chain = BLOCK_FRAGMENT_CHAIN (stmt);