Commit ef76d03b by Jim Wilson

(dwarf2out_frame_debug): Handle IOR.

(struct limbo_die_struct): Define.
(TYPE_DECL_IS_STUB): Call decl_ultimate_origin if DECL_ABTRACT_ORIGIN
is set.
(limbo_die_count): Delete.
(libmo_die_list): Define.
(new_die): Add die to limbo_die_list instead of incrementing
limbo_die_count.
(add_AT_location_description): Renamed from add_location_attribute.
New parameter attr_kind.
(add_location_or_const_value_attribute, gen_subprogram_die,
add_bound_info): Change call to add_AT_location_description.
(add_bound_info): Add call to contains_placeholder_p.  Ignore
MAX_EXPR and VAR_DECL.
(add_subscript_info): Ignore the index type if it is an unnamed
integral type.
(scope_die_for): Move check for function-local tags after code setting
containing_scope, and add check for non-NULL containing_scope
(add_type_attribute): If unnamed type, use TREE_TYPE instead.
(gen_enumeration_type_die, gen_struct_or_union_type_die): Call
add_child_die if die_parent is NULL.
(gen_subprogram_die): Ifdef out DW_AT_static_link code.
(decls_for_scope): Delete decrement of limbo_die_count.
(dwarf2out_finish): Add code to traverse the limbo_die_list, and
call add_child_die if die_parent is NULL.  Delete limbo_die_count code.

From-SVN: r14248
parent babae559
...@@ -850,6 +850,14 @@ dwarf2out_frame_debug (insn) ...@@ -850,6 +850,14 @@ dwarf2out_frame_debug (insn)
cfa_temp_value = INTVAL (src); cfa_temp_value = INTVAL (src);
break; break;
case IOR:
assert (GET_CODE (XEXP (src, 0)) == REG
&& REGNO (XEXP (src, 0)) == cfa_temp_reg);
assert (REGNO (dest) == cfa_temp_reg);
assert (GET_CODE (XEXP (src, 1)) == CONST_INT);
cfa_temp_value |= INTVAL (XEXP (src, 1));
break;
default: default:
abort (); abort ();
} }
...@@ -1630,6 +1638,14 @@ typedef struct pubname_struct ...@@ -1630,6 +1638,14 @@ typedef struct pubname_struct
} }
pubname_entry; pubname_entry;
/* The limbo die list structure. */
typedef struct limbo_die_struct
{
dw_die_ref die;
struct limbo_die_struct *next;
}
limbo_die_node;
/* How to start an assembler comment. */ /* How to start an assembler comment. */
#ifndef ASM_COMMENT_START #ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#" #define ASM_COMMENT_START ";#"
...@@ -1649,7 +1665,12 @@ pubname_entry; ...@@ -1649,7 +1665,12 @@ pubname_entry;
(DECL_NAME (decl) == NULL_TREE \ (DECL_NAME (decl) == NULL_TREE \
|| (DECL_ARTIFICIAL (decl) \ || (DECL_ARTIFICIAL (decl) \
&& is_tagged_type (TREE_TYPE (decl)) \ && is_tagged_type (TREE_TYPE (decl)) \
&& decl == TYPE_STUB_DECL (TREE_TYPE (decl)))) && ((decl == TYPE_STUB_DECL (TREE_TYPE (decl))) \
/* This is necessary for stub decls that \
appear in nested inline functions. */ \
|| (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE \
&& (decl_ultimate_origin (decl) \
== TYPE_STUB_DECL (TREE_TYPE (decl)))))))
/* Information concerning the compilation unit's programming /* Information concerning the compilation unit's programming
language, and compiler version. */ language, and compiler version. */
...@@ -1705,8 +1726,8 @@ static unsigned long next_die_offset; ...@@ -1705,8 +1726,8 @@ static unsigned long next_die_offset;
/* Record the root of the DIE's built for the current compilation unit. */ /* Record the root of the DIE's built for the current compilation unit. */
static dw_die_ref comp_unit_die; static dw_die_ref comp_unit_die;
/* The number of DIEs with a NULL parent waiting to be relocated. */ /* A list of DIEs with a NULL parent waiting to be relocated. */
static int limbo_die_count; static limbo_die_node *limbo_die_list = 0;
/* Pointer to an array of filenames referenced by this compilation unit. */ /* Pointer to an array of filenames referenced by this compilation unit. */
static char **file_table; static char **file_table;
...@@ -1977,7 +1998,8 @@ static tree field_type PROTO((tree)); ...@@ -1977,7 +1998,8 @@ static tree field_type PROTO((tree));
static unsigned simple_type_align_in_bits PROTO((tree)); static unsigned simple_type_align_in_bits PROTO((tree));
static unsigned simple_type_size_in_bits PROTO((tree)); static unsigned simple_type_size_in_bits PROTO((tree));
static unsigned field_byte_offset PROTO((tree)); static unsigned field_byte_offset PROTO((tree));
static void add_location_attribute PROTO((dw_die_ref, rtx)); static void add_AT_location_description PROTO((dw_die_ref,
enum dwarf_attribute, rtx));
static void add_data_member_location_attribute PROTO((dw_die_ref, tree)); static void add_data_member_location_attribute PROTO((dw_die_ref, tree));
static void add_const_value_attribute PROTO((dw_die_ref, rtx)); static void add_const_value_attribute PROTO((dw_die_ref, rtx));
static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree)); static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
...@@ -3608,7 +3630,14 @@ new_die (tag_value, parent_die) ...@@ -3608,7 +3630,14 @@ new_die (tag_value, parent_die)
if (parent_die != NULL) if (parent_die != NULL)
add_child_die (parent_die, die); add_child_die (parent_die, die);
else else
++limbo_die_count; {
limbo_die_node *limbo_node;
limbo_node = (limbo_die_node *) xmalloc (sizeof (limbo_die_node));
limbo_node->die = die;
limbo_node->next = limbo_die_list;
limbo_die_list = limbo_node;
}
return die; return die;
} }
...@@ -6097,14 +6126,16 @@ field_byte_offset (decl) ...@@ -6097,14 +6126,16 @@ field_byte_offset (decl)
/* The following routines define various Dwarf attributes and any data /* The following routines define various Dwarf attributes and any data
associated with them. */ associated with them. */
/* Add a location description attribute value to a DIE.
/* Output the form of location attributes suitable for whole variables and This emits location attributes suitable for whole variables and
whole parameters. Note that the location attributes for struct fields are whole parameters. Note that the location attributes for struct fields are
generated by the routine `data_member_location_attribute' below. */ generated by the routine `data_member_location_attribute' below. */
static void static void
add_location_attribute (die, rtl) add_AT_location_description (die, attr_kind, rtl)
dw_die_ref die; dw_die_ref die;
enum dwarf_attribute attr_kind;
register rtx rtl; register rtx rtl;
{ {
dw_loc_descr_ref loc_descr = NULL; dw_loc_descr_ref loc_descr = NULL;
...@@ -6138,7 +6169,7 @@ add_location_attribute (die, rtl) ...@@ -6138,7 +6169,7 @@ add_location_attribute (die, rtl)
loc_descr = loc_descriptor (gen_rtx (REG, word_mode, 0)); loc_descr = loc_descriptor (gen_rtx (REG, word_mode, 0));
#endif #endif
add_AT_loc (die, DW_AT_location, loc_descr); add_AT_loc (die, attr_kind, loc_descr);
} }
/* Attach the specialized form of location attribute used for data /* Attach the specialized form of location attribute used for data
...@@ -6429,7 +6460,7 @@ add_location_or_const_value_attribute (die, decl) ...@@ -6429,7 +6460,7 @@ add_location_or_const_value_attribute (die, decl)
case MEM: case MEM:
case REG: case REG:
case SUBREG: case SUBREG:
add_location_attribute (die, rtl); add_AT_location_description (die, DW_AT_location, rtl);
break; break;
default: default:
...@@ -6459,6 +6490,13 @@ add_bound_info (subrange_die, bound_attr, bound) ...@@ -6459,6 +6490,13 @@ add_bound_info (subrange_die, bound_attr, bound)
register tree bound; register tree bound;
{ {
register unsigned bound_value = 0; register unsigned bound_value = 0;
/* If this is an Ada unconstrained array type, then don't emit any debug
info because the array bounds are unknown. They are parameterized when
the type is instantiated. */
if (contains_placeholder_p (bound))
return;
switch (TREE_CODE (bound)) switch (TREE_CODE (bound))
{ {
case ERROR_MARK: case ERROR_MARK:
...@@ -6510,13 +6548,20 @@ add_bound_info (subrange_die, bound_attr, bound) ...@@ -6510,13 +6548,20 @@ add_bound_info (subrange_die, bound_attr, bound)
register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx); register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
add_AT_flag (decl_die, DW_AT_artificial, 1); add_AT_flag (decl_die, DW_AT_artificial, 1);
add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
add_location_attribute (decl_die, SAVE_EXPR_RTL (bound)); add_AT_location_description (decl_die, DW_AT_location,
SAVE_EXPR_RTL (bound));
add_AT_die_ref (subrange_die, bound_attr, decl_die); add_AT_die_ref (subrange_die, bound_attr, decl_die);
} }
/* Else leave out the attribute. */ /* Else leave out the attribute. */
break; break;
case MAX_EXPR:
case VAR_DECL:
/* ??? These types of bounds can be created by the Ada front end,
and it isn't clear how to emit debug info for them. */
break;
default: default:
abort (); abort ();
} }
...@@ -6567,8 +6612,19 @@ add_subscript_info (type_die, type) ...@@ -6567,8 +6612,19 @@ add_subscript_info (type_die, type)
/* define the index type. */ /* define the index type. */
if (TREE_TYPE (domain)) if (TREE_TYPE (domain))
add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0, {
type_die); /* ??? This is probably an Ada unnamed subrange type. Ignore the
TREE_TYPE field. We can't emit debug info for this
because it is an unnamed integral type. */
if (TREE_CODE (domain) == INTEGER_TYPE
&& TYPE_NAME (domain) == NULL_TREE
&& TREE_CODE (TREE_TYPE (domain)) == INTEGER_TYPE
&& TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE)
;
else
add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
type_die);
}
add_bound_info (subrange_die, DW_AT_lower_bound, lower); add_bound_info (subrange_die, DW_AT_lower_bound, lower);
add_bound_info (subrange_die, DW_AT_upper_bound, upper); add_bound_info (subrange_die, DW_AT_upper_bound, upper);
...@@ -6818,12 +6874,6 @@ scope_die_for (t, context_die) ...@@ -6818,12 +6874,6 @@ scope_die_for (t, context_die)
register tree containing_scope; register tree containing_scope;
register unsigned long i; register unsigned long i;
/* Function-local tags and functions get stuck in limbo until they are
fixed up by decls_for_scope. */
if (context_die == NULL
&& (TREE_CODE (t) == FUNCTION_DECL || is_tagged_type (t)))
return NULL;
/* Walk back up the declaration tree looking for a place to define /* Walk back up the declaration tree looking for a place to define
this type. */ this type. */
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
...@@ -6833,6 +6883,12 @@ scope_die_for (t, context_die) ...@@ -6833,6 +6883,12 @@ scope_die_for (t, context_die)
else else
containing_scope = DECL_CONTEXT (t); containing_scope = DECL_CONTEXT (t);
/* Function-local tags and functions get stuck in limbo until they are
fixed up by decls_for_scope. */
if (context_die == NULL && containing_scope != NULL_TREE
&& (TREE_CODE (t) == FUNCTION_DECL || is_tagged_type (t)))
return NULL;
if (containing_scope == NULL_TREE) if (containing_scope == NULL_TREE)
scope_die = comp_unit_die; scope_die = comp_unit_die;
else else
...@@ -6877,8 +6933,10 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die) ...@@ -6877,8 +6933,10 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
register enum tree_code code = TREE_CODE (type); register enum tree_code code = TREE_CODE (type);
register dw_die_ref type_die = NULL; register dw_die_ref type_die = NULL;
/* If this type is an unnamed subtype of an integral or floating-point /* ??? If this type is an unnamed subrange type of an integral or
type, use the inner type. */ floating-point type, use the inner type. This is because we have no
support for unnamed types in base_type_die. This can happen if this is
an Ada subrange type. Correct solution is emit a subrange type die. */
if ((code == INTEGER_TYPE || code == REAL_TYPE) if ((code == INTEGER_TYPE || code == REAL_TYPE)
&& TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0) && TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0)
type = TREE_TYPE (type), code = TREE_CODE (type); type = TREE_TYPE (type), code = TREE_CODE (type);
...@@ -7177,6 +7235,11 @@ gen_enumeration_type_die (type, context_die) ...@@ -7177,6 +7235,11 @@ gen_enumeration_type_die (type, context_die)
if (type_tag (type)) if (type_tag (type))
add_src_coords_attributes (type_die, TYPE_STUB_DECL (type)); add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
/* If the first reference to this type was as the return type of an
inline function, then it may not have a parent. Fix this now. */
if (type_die->die_parent == NULL)
add_child_die (scope_die_for (type, context_die), type_die);
for (link = TYPE_FIELDS (type); for (link = TYPE_FIELDS (type);
link != NULL; link = TREE_CHAIN (link)) link != NULL; link = TREE_CHAIN (link))
{ {
...@@ -7486,9 +7549,13 @@ gen_subprogram_die (decl, context_die) ...@@ -7486,9 +7549,13 @@ gen_subprogram_die (decl, context_die)
= frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx; = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg)); add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
#if 0
/* ??? This fails for nested inline functions, because context_display
is not part of the state saved/restored for inline functions. */
if (current_function_needs_context) if (current_function_needs_context)
add_AT_loc (subr_die, DW_AT_static_link, add_AT_location_description (subr_die, DW_AT_static_link,
loc_descriptor (lookup_static_chain (decl))); lookup_static_chain (decl));
#endif
} }
/* Now output descriptions of the arguments for this function. This gets /* Now output descriptions of the arguments for this function. This gets
...@@ -8028,6 +8095,11 @@ gen_struct_or_union_type_die (type, context_die) ...@@ -8028,6 +8095,11 @@ gen_struct_or_union_type_die (type, context_die)
if (type_tag (type)) if (type_tag (type))
add_src_coords_attributes (type_die, TYPE_STUB_DECL (type)); add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
/* If the first reference to this type was as the return type of an
inline function, then it may not have a parent. Fix this now. */
if (type_die->die_parent == NULL)
add_child_die (scope_die, type_die);
push_decl_scope (type); push_decl_scope (type);
gen_member_die (type, type_die); gen_member_die (type, type_die);
pop_decl_scope (); pop_decl_scope ();
...@@ -8397,10 +8469,7 @@ decls_for_scope (stmt, context_die, depth) ...@@ -8397,10 +8469,7 @@ decls_for_scope (stmt, context_die, depth)
die = NULL; die = NULL;
if (die != NULL && die->die_parent == NULL) if (die != NULL && die->die_parent == NULL)
{ add_child_die (context_die, die);
add_child_die (context_die, die);
--limbo_die_count;
}
else else
gen_decl_die (decl, context_die); gen_decl_die (decl, context_die);
} }
...@@ -8503,7 +8572,7 @@ gen_decl_die (decl, context_die) ...@@ -8503,7 +8572,7 @@ gen_decl_die (decl, context_die)
having been instantiated from some other (original) TYPE_DECL node having been instantiated from some other (original) TYPE_DECL node
(e.g. one which was generated within the original definition of an (e.g. one which was generated within the original definition of an
inline function) we have to generate a special (abbreviated) inline function) we have to generate a special (abbreviated)
DW_TAG_structure_type, DW_TAG_union_type, or DW_TAG_enumeration-type DW_TAG_structure_type, DW_TAG_union_type, or DW_TAG_enumeration_type
DIE here. */ DIE here. */
if (TYPE_DECL_IS_STUB (decl) && DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE) if (TYPE_DECL_IS_STUB (decl) && DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE)
{ {
...@@ -8968,6 +9037,33 @@ dwarf2out_init (asm_out_file, main_input_filename) ...@@ -8968,6 +9037,33 @@ dwarf2out_init (asm_out_file, main_input_filename)
void void
dwarf2out_finish () dwarf2out_finish ()
{ {
limbo_die_node *node, *next_node;
dw_die_ref die;
dw_attr_ref a;
/* 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.
For concrete instances, we can get the parent die from the abstract
instance. */
for (node = limbo_die_list; node; node = next_node)
{
next_node = node->next;
die = node->die;
if (die->die_parent == NULL)
{
a = get_AT (die, DW_AT_abstract_origin);
if (a)
add_child_die (a->dw_attr_val.v.val_die_ref->die_parent, die);
else if (die == comp_unit_die)
;
else
abort ();
}
free (node);
}
/* Traverse the DIE tree and add sibling attributes to those DIE's /* Traverse the DIE tree and add sibling attributes to those DIE's
that have children. */ that have children. */
add_sibling_attributes (comp_unit_die); add_sibling_attributes (comp_unit_die);
...@@ -9042,8 +9138,5 @@ dwarf2out_finish () ...@@ -9042,8 +9138,5 @@ dwarf2out_finish ()
ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION); ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION);
output_aranges (); output_aranges ();
} }
/* The only DIE we should have with a parent of NULL is comp_unit_die. */
assert (limbo_die_count == 1);
} }
#endif /* DWARF2_DEBUGGING_INFO */ #endif /* DWARF2_DEBUGGING_INFO */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment