Commit 273dbe67 by Jason Merrill

x

From-SVN: r13088
parent 27a2c2b5
...@@ -16,4 +16,4 @@ INSTALL_LIBGCC = install-multilib ...@@ -16,4 +16,4 @@ INSTALL_LIBGCC = install-multilib
# For svr4 we build crtbegin.o and crtend.o which serve to add begin and # For svr4 we build crtbegin.o and crtend.o which serve to add begin and
# end labels to the .ctors and .dtors section when we link using gcc. # end labels to the .ctors and .dtors section when we link using gcc.
EXTRA_PARTS=crtbegin.o crtend.o EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o
...@@ -413,11 +413,6 @@ static char *primary_filename; ...@@ -413,11 +413,6 @@ static char *primary_filename;
assigns numbers to the blocks in the same way. */ assigns numbers to the blocks in the same way. */
static unsigned next_block_number = 2; static unsigned next_block_number = 2;
/* Non-zero if we are performing the file-scope finalization pass and if we
should force out Dwarf descriptions of any and all file-scope tagged types
which are still incomplete types. */
static int finalizing = 0;
/* A pointer to the base of a list of references to DIE's that describe /* A pointer to the base of a list of references to DIE's that describe
types. The table is indexed by TYPE_UID() which is a unique number, types. The table is indexed by TYPE_UID() which is a unique number,
indentifying each type. */ indentifying each type. */
...@@ -6062,7 +6057,7 @@ add_name_and_src_coords_attributes (die, decl) ...@@ -6062,7 +6057,7 @@ add_name_and_src_coords_attributes (die, decl)
{ {
register tree decl_name; register tree decl_name;
register unsigned file_index; register unsigned file_index;
if (decl_function_context (decl) == NULL_TREE) if (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
decl_name = DECL_ASSEMBLER_NAME (decl); decl_name = DECL_ASSEMBLER_NAME (decl);
else else
decl_name = DECL_NAME (decl); decl_name = DECL_NAME (decl);
...@@ -6366,17 +6361,15 @@ gen_inlined_union_type_die (type, context_die) ...@@ -6366,17 +6361,15 @@ gen_inlined_union_type_die (type, context_die)
/* Generate a DIE to represent an enumeration type. Note that these DIEs /* Generate a DIE to represent an enumeration type. Note that these DIEs
include all of the information about the enumeration values also. Each include all of the information about the enumeration values also. Each
enumerated type name/value is listed as a child of the enumerated type DIE */ enumerated type name/value is listed as a child of the enumerated type
DIE. */
static void static void
gen_enumeration_type_die (type, is_complete, context_die) gen_enumeration_type_die (type, context_die)
register tree type; register tree type;
register unsigned is_complete;
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref type_die; register dw_die_ref type_die = lookup_type_die (type);
register dw_die_ref enum_die;
register tree link;
type_die = lookup_type_die (type);
if (type_die == NULL) if (type_die == NULL)
{ {
type_die = new_die (DW_TAG_enumeration_type, type_die = new_die (DW_TAG_enumeration_type,
...@@ -6384,25 +6377,30 @@ gen_enumeration_type_die (type, is_complete, context_die) ...@@ -6384,25 +6377,30 @@ gen_enumeration_type_die (type, is_complete, context_die)
equate_type_number_to_die (type, type_die); equate_type_number_to_die (type, type_die);
add_name_attribute (type_die, type_tag (type)); add_name_attribute (type_die, type_tag (type));
} }
if (is_complete) else if (! TYPE_SIZE (type))
return;
else
remove_AT (type_die, DW_AT_declaration);
/* Handle a GNU C/C++ extension, i.e. incomplete enum types. If the
given enum type is incomplete, do not generate the DW_AT_byte_size
attribute or the DW_AT_element_list attribute. */
if (TYPE_SIZE (type))
{ {
/* Handle a GNU C/C++ extension, i.e. incomplete enum types. If the register tree link;
given enum type is incomplete, do not generate the DW_AT_byte_size add_byte_size_attribute (type_die, type);
attribute or the DW_AT_element_list attribute. */ for (link = TYPE_FIELDS (type);
if (TYPE_SIZE (type)) link != NULL; link = TREE_CHAIN (link))
{ {
add_byte_size_attribute (type_die, type); register dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die);
for (link = TYPE_FIELDS (type); add_name_attribute (enum_die,
link != NULL; link = TREE_CHAIN (link)) IDENTIFIER_POINTER (TREE_PURPOSE (link)));
{ add_AT_unsigned (enum_die, DW_AT_const_value,
enum_die = new_die (DW_TAG_enumerator, type_die);
add_name_attribute (enum_die,
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
add_AT_unsigned (enum_die, DW_AT_const_value,
(unsigned) TREE_INT_CST_LOW (TREE_VALUE (link))); (unsigned) TREE_INT_CST_LOW (TREE_VALUE (link)));
}
} }
} }
else
add_AT_flag (type_die, DW_AT_declaration, 1);
} }
...@@ -6610,15 +6608,15 @@ gen_subprogram_die (decl, context_die) ...@@ -6610,15 +6608,15 @@ gen_subprogram_die (decl, context_die)
{ {
subr_die = new_die (DW_TAG_subprogram, subr_die = new_die (DW_TAG_subprogram,
scope_die_for (decl, context_die)); scope_die_for (decl, context_die));
if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) if (TREE_PUBLIC (decl))
{ add_AT_flag (subr_die, DW_AT_external, 1);
add_AT_flag (subr_die, DW_AT_external, 1);
}
add_name_and_src_coords_attributes (subr_die, decl); add_name_and_src_coords_attributes (subr_die, decl);
type = TREE_TYPE (decl); type = TREE_TYPE (decl);
add_prototyped_attribute (subr_die, type); add_prototyped_attribute (subr_die, type);
add_type_attribute (subr_die, TREE_TYPE (type), 0, 0, context_die); add_type_attribute (subr_die, TREE_TYPE (type), 0, 0, context_die);
add_pure_or_virtual_attribute (subr_die, decl); add_pure_or_virtual_attribute (subr_die, decl);
if (DECL_ARTIFICIAL (decl))
add_AT_flag (subr_die, DW_AT_artificial, 1);
/* The first time we see a member function, it is in the context of /* The first time we see a member function, it is in the context of
the class to which it belongs. We make sure of this by emitting the class to which it belongs. We make sure of this by emitting
...@@ -6822,10 +6820,10 @@ gen_variable_die (decl, context_die) ...@@ -6822,10 +6820,10 @@ gen_variable_die (decl, context_die)
add_type_attribute (var_die, TREE_TYPE (decl), add_type_attribute (var_die, TREE_TYPE (decl),
TREE_READONLY (decl), TREE_READONLY (decl),
TREE_THIS_VOLATILE (decl), context_die); TREE_THIS_VOLATILE (decl), context_die);
if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) if (TREE_PUBLIC (decl))
{ add_AT_flag (var_die, DW_AT_external, 1);
add_AT_flag (var_die, DW_AT_external, 1); if (DECL_ARTIFICIAL (decl))
} add_AT_flag (var_die, DW_AT_artificial, 1);
} }
if (DECL_ABSTRACT (decl)) if (DECL_ABSTRACT (decl))
{ {
...@@ -6953,6 +6951,8 @@ gen_field_die (decl, context_die) ...@@ -6953,6 +6951,8 @@ gen_field_die (decl, context_die)
add_bit_offset_attribute (decl_die, decl); add_bit_offset_attribute (decl_die, decl);
} }
add_data_member_location_attribute (decl_die, decl); add_data_member_location_attribute (decl_die, decl);
if (DECL_ARTIFICIAL (decl))
add_AT_flag (decl_die, DW_AT_artificial, 1);
} }
#if 0 #if 0
...@@ -6965,7 +6965,8 @@ gen_pointer_type_die (type, context_die) ...@@ -6965,7 +6965,8 @@ gen_pointer_type_die (type, context_die)
register tree type; register tree type;
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref ptr_die = new_die (DW_TAG_pointer_type, context_die); register dw_die_ref ptr_die = new_die
(DW_TAG_pointer_type, scope_die_for (type, context_die));
equate_type_number_to_die (type, ptr_die); equate_type_number_to_die (type, ptr_die);
add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
...@@ -6980,7 +6981,8 @@ gen_reference_type_die (type, context_die) ...@@ -6980,7 +6981,8 @@ gen_reference_type_die (type, context_die)
register tree type; register tree type;
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref ref_die = new_die (DW_TAG_reference_type, context_die); register dw_die_ref ref_die = new_die
(DW_TAG_reference_type, scope_die_for (type, context_die));
equate_type_number_to_die (type, ref_die); equate_type_number_to_die (type, ref_die);
add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
...@@ -6994,7 +6996,7 @@ gen_ptr_to_mbr_type_die (type, context_die) ...@@ -6994,7 +6996,7 @@ gen_ptr_to_mbr_type_die (type, context_die)
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref ptr_die = new_die register dw_die_ref ptr_die = new_die
(DW_TAG_ptr_to_member_type, context_die); (DW_TAG_ptr_to_member_type, scope_die_for (type, context_die));
equate_type_number_to_die (type, ptr_die); equate_type_number_to_die (type, ptr_die);
add_AT_die_ref (ptr_die, DW_AT_containing_type, add_AT_die_ref (ptr_die, DW_AT_containing_type,
lookup_type_die (TYPE_OFFSET_BASETYPE (type))); lookup_type_die (TYPE_OFFSET_BASETYPE (type)));
...@@ -7133,40 +7135,42 @@ gen_member_die (type, context_die) ...@@ -7133,40 +7135,42 @@ gen_member_die (type, context_die)
/* Generate a DIE for a structure or union type. */ /* Generate a DIE for a structure or union type. */
static void static void
gen_struct_or_union_type_die (type, is_complete, context_die) gen_struct_or_union_type_die (type, context_die)
register tree type; register tree type;
register unsigned is_complete;
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref type_die; register dw_die_ref type_die = lookup_type_die (type);
type_die = lookup_type_die (type);
if (type_die == NULL) if (type_die && ! TYPE_SIZE (type))
return;
else if (! type_die
|| (TYPE_CONTEXT (type)
&& TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't'))
/* First occurrence of type or toplevel definition of nested class. */
{ {
register dw_die_ref old_die = type_die;
type_die = new_die (TREE_CODE (type) == RECORD_TYPE type_die = new_die (TREE_CODE (type) == RECORD_TYPE
? DW_TAG_structure_type : DW_TAG_union_type, ? DW_TAG_structure_type : DW_TAG_union_type,
scope_die_for (type, context_die)); scope_die_for (type, context_die));
equate_type_number_to_die (type, type_die); equate_type_number_to_die (type, type_die);
add_name_attribute (type_die, type_tag (type)); add_name_attribute (type_die, type_tag (type));
if (old_die)
add_AT_die_ref (type_die, DW_AT_specification, old_die);
} }
else if (is_complete)
remove_AT (type_die, DW_AT_declaration);
else else
return; remove_AT (type_die, DW_AT_declaration);
/* If this type has been completed, then give it a byte_size attribute and /* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */ then give a list of members. */
if (is_complete) if (TYPE_SIZE (type))
{ {
/* Prevent infinite recursion in cases where the type of some member of /* 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; TREE_ASM_WRITTEN (type) = 1;
if (TYPE_SIZE (type)) add_byte_size_attribute (type_die, type);
{ push_decl_scope (type);
add_byte_size_attribute (type_die, type); gen_member_die (type, type_die);
push_decl_scope (type); pop_decl_scope ();
gen_member_die (type, type_die);
pop_decl_scope ();
}
} }
else else
add_AT_flag (type_die, DW_AT_declaration, 1); add_AT_flag (type_die, DW_AT_declaration, 1);
...@@ -7179,7 +7183,8 @@ gen_subroutine_type_die (type, context_die) ...@@ -7179,7 +7183,8 @@ gen_subroutine_type_die (type, context_die)
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register tree return_type = TREE_TYPE (type); register tree return_type = TREE_TYPE (type);
register dw_die_ref subr_die = new_die (DW_TAG_subroutine_type, context_die); register dw_die_ref subr_die = new_die
(DW_TAG_subroutine_type, scope_die_for (type, context_die));
equate_type_number_to_die (type, subr_die); equate_type_number_to_die (type, subr_die);
add_prototyped_attribute (subr_die, type); add_prototyped_attribute (subr_die, type);
add_type_attribute (subr_die, return_type, 0, 0, context_die); add_type_attribute (subr_die, return_type, 0, 0, context_die);
...@@ -7219,7 +7224,6 @@ gen_type_die (type, context_die) ...@@ -7219,7 +7224,6 @@ gen_type_die (type, context_die)
register tree type; register tree type;
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register unsigned is_complete;
if (type == 0 || type == error_mark_node) if (type == 0 || type == error_mark_node)
{ {
return; return;
...@@ -7296,48 +7300,14 @@ gen_type_die (type, context_die) ...@@ -7296,48 +7300,14 @@ gen_type_die (type, context_die)
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
case QUAL_UNION_TYPE: case QUAL_UNION_TYPE:
/* For a function-scope tagged type, we can always go ahead and output
a Dwarf description of this type right now, even if the type in
question is still incomplete, because if this local type *was* ever
completed anywhere within its scope, that complete definition would
already have been attached to this RECORD_TYPE, UNION_TYPE,
QUAL_UNION_TYPE or ENUMERAL_TYPE node by the time we reach this
point. That's true because of the way the front-end does its
processing of file-scope declarations (of functions and class types)
within which other types might be nested. The C and C++ front-ends
always gobble up such "local scope" things en-mass before they try
to output *any* debugging information for any of the stuff contained
inside them and thus, we get the benefit here of what is (in effect)
a pre-resolution of forward references to tagged types in local
scopes. Note however that for file-scope tagged types we cannot
assume that such pre-resolution of forward references has taken
place. A given file-scope tagged type may appear to be incomplete
when we reach this point, but it may yet be given a full definition
(at file-scope) later on during compilation. In order to avoid
generating a premature (and possibly incorrect) set of Dwarf DIEs
for such (as yet incomplete) file-scope tagged types, we generate
nothing at all for as-yet incomplete file-scope tagged types here
unless we are making our special "finalization" pass for file-scope
things at the very end of compilation. At that time, we will
certainly know as much about each file-scope tagged type as we are
ever going to know, so at that point in time, we can safely generate
correct Dwarf descriptions for these file-scope tagged types. */
is_complete = TYPE_SIZE (type) != 0
|| (TYPE_CONTEXT (type) != NULL
&& TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) != 't')
|| finalizing;
if (TREE_CODE (type) == ENUMERAL_TYPE) if (TREE_CODE (type) == ENUMERAL_TYPE)
{ gen_enumeration_type_die (type, context_die);
gen_enumeration_type_die (type, is_complete, context_die);
}
else else
{ gen_struct_or_union_type_die (type, context_die);
gen_struct_or_union_type_die (type, is_complete, context_die);
}
/* Don't set TREE_ASM_WRITTEN on an incomplete struct; we want to fix /* Don't set TREE_ASM_WRITTEN on an incomplete struct; we want to fix
it up if it is ever completed. */ it up if it is ever completed. */
if (! is_complete) if (TYPE_SIZE (type) == NULL_TREE)
return; return;
break; break;
...@@ -7743,7 +7713,7 @@ dwarfout_file_scope_decl (decl, set_finalizing) ...@@ -7743,7 +7713,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
out-of-lines instances of such things (despite the fact that they out-of-lines instances of such things (despite the fact that they
*are* definitions). The important point is that the C front-end *are* definitions). The important point is that the C front-end
marks these "extern inline" functions as DECL_EXTERNAL, but we need marks these "extern inline" functions as DECL_EXTERNAL, but we need
to generate DWARf for them anyway. Note that the C++ front-end also to generate DWARF for them anyway. Note that the C++ front-end also
plays some similar games for inline function definitions appearing plays some similar games for inline function definitions appearing
within include files which also contain within include files which also contain
`#pragma interface' pragmas. */ `#pragma interface' pragmas. */
...@@ -7811,7 +7781,6 @@ dwarfout_file_scope_decl (decl, set_finalizing) ...@@ -7811,7 +7781,6 @@ dwarfout_file_scope_decl (decl, set_finalizing)
return; return;
} }
finalizing = set_finalizing;
gen_decl_die (decl, comp_unit_die); gen_decl_die (decl, comp_unit_die);
if (TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == FUNCTION_DECL
......
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