Commit 777ad4c2 by Jason Merrill Committed by Jason Merrill

dwarf2out.c (scope_die_for): Only handle types.

        * dwarf2out.c (scope_die_for): Only handle types.  Only search for
        containing types.
        (decl_scope_table): Just an array of trees now.
        (push_decl_scope): Simplify.
        (dwarf2out_init): Adjust.
        (local_scope_p): New fn.
        (gen_inlined_enumeration_type_die): Don't call scope_die_for.
        (gen_inlined_union_type_die, gen_inlined_structure_type_die): Likewise.
        (gen_typedef_die): Likewise.
        (gen_lexical_block_die): Don't call push/pop_decl_scope.
        (gen_inlined_subroutine_die): Likewise.
        (gen_abstract_function): Set current_function_decl temporarily.
        (gen_subprogram_die): Don't check DECL_ABSTRACT to set declaration.
        Handle block extern declarations.  Don't call push/pop_decl_scope.
        (gen_decl_die): Fix logic for block externs.

From-SVN: r30733
parent d9465687
1999-11-30 Jason Merrill <jason@casey.cygnus.com>
* dwarf2out.c (scope_die_for): Only handle types. Only search for
containing types.
(decl_scope_table): Just an array of trees now.
(push_decl_scope): Simplify.
(dwarf2out_init): Adjust.
(local_scope_p): New fn.
(gen_inlined_enumeration_type_die): Don't call scope_die_for.
(gen_inlined_union_type_die, gen_inlined_structure_type_die): Likewise.
(gen_typedef_die): Likewise.
(gen_lexical_block_die): Don't call push/pop_decl_scope.
(gen_inlined_subroutine_die): Likewise.
(gen_abstract_function): Set current_function_decl temporarily.
(gen_subprogram_die): Don't check DECL_ABSTRACT to set declaration.
Handle block extern declarations. Don't call push/pop_decl_scope.
(gen_decl_die): Fix logic for block externs.
1999-11-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 1999-11-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* calls.c (special_function_p): Remove `realloc' and add `strdup' * calls.c (special_function_p): Remove `realloc' and add `strdup'
......
...@@ -2227,23 +2227,12 @@ static unsigned decl_die_table_in_use; ...@@ -2227,23 +2227,12 @@ static unsigned decl_die_table_in_use;
decl_die_table. */ decl_die_table. */
#define DECL_DIE_TABLE_INCREMENT 256 #define DECL_DIE_TABLE_INCREMENT 256
/* Structure used for the decl_scope table. scope is the current declaration
scope, and previous is the entry that is the parent of this scope. This
is usually but not always the immediately preceeding entry. */
typedef struct decl_scope_struct
{
tree scope;
int previous;
}
decl_scope_node;
/* A pointer to the base of a table of references to declaration /* A pointer to the base of a table of references to declaration
scopes. This table is a display which tracks the nesting scopes. This table is a display which tracks the nesting
of declaration scopes at the current scope and containing of declaration scopes at the current scope and containing
scopes. This table is used to find the proper place to scopes. This table is used to find the proper place to
define type declaration DIE's. */ define type declaration DIE's. */
static decl_scope_node *decl_scope_table; static tree *decl_scope_table;
/* Number of elements currently allocated for the decl_scope_table. */ /* Number of elements currently allocated for the decl_scope_table. */
static int decl_scope_table_allocated; static int decl_scope_table_allocated;
...@@ -7589,34 +7578,28 @@ push_decl_scope (scope) ...@@ -7589,34 +7578,28 @@ push_decl_scope (scope)
{ {
decl_scope_table_allocated += DECL_SCOPE_TABLE_INCREMENT; decl_scope_table_allocated += DECL_SCOPE_TABLE_INCREMENT;
decl_scope_table decl_scope_table
= (decl_scope_node *) xrealloc (decl_scope_table, = (tree *) xrealloc (decl_scope_table,
(decl_scope_table_allocated decl_scope_table_allocated * sizeof (tree));
* sizeof (decl_scope_node)));
} }
decl_scope_table[decl_scope_depth].scope = scope; decl_scope_table[decl_scope_depth] = scope;
/* If we're starting to emit a global class while we're in the middle
of emitting a function, we need to find the proper .previous. */
if (AGGREGATE_TYPE_P (scope))
{
tree containing_scope = TYPE_CONTEXT (scope);
int i;
for (i = decl_scope_depth - 1; i >= 0; --i)
if (decl_scope_table[i].scope == containing_scope)
break;
decl_scope_table[decl_scope_depth].previous = i;
}
else
decl_scope_table[decl_scope_depth].previous = decl_scope_depth - 1;
decl_scope_depth++; decl_scope_depth++;
} }
/* Return the DIE for the scope that immediately contains this declaration. */ /* Pop a declaration scope. */
static inline void
pop_decl_scope ()
{
if (decl_scope_depth <= 0)
abort ();
--decl_scope_depth;
}
/* Return the DIE for the scope that immediately contains this type.
Non-named types get global scope. Named types nested in other
types get their containing scope if it's open, or global scope
otherwise. All other types (i.e. function-local named types) get
the current active scope. */
static dw_die_ref static dw_die_ref
scope_die_for (t, context_die) scope_die_for (t, context_die)
...@@ -7627,14 +7610,11 @@ scope_die_for (t, context_die) ...@@ -7627,14 +7610,11 @@ scope_die_for (t, context_die)
register tree containing_scope; register tree containing_scope;
register int i; register int i;
/* Walk back up the declaration tree looking for a place to define /* Non-types always go in the current scope. */
this type. */ if (! TYPE_P (t))
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') abort ();
containing_scope = TYPE_CONTEXT (t);
else if (TREE_CODE (t) == FUNCTION_DECL && DECL_VINDEX (t)) containing_scope = TYPE_CONTEXT (t);
containing_scope = decl_class_context (t);
else
containing_scope = DECL_CONTEXT (t);
/* Ignore namespaces for the moment. */ /* Ignore namespaces for the moment. */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL) if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
...@@ -7646,34 +7626,20 @@ scope_die_for (t, context_die) ...@@ -7646,34 +7626,20 @@ scope_die_for (t, context_die)
if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE) if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE)
containing_scope = NULL_TREE; containing_scope = NULL_TREE;
/* 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 if (TYPE_P (containing_scope) || DECL_P (containing_scope)) else if (TYPE_P (containing_scope))
{ {
/* For types and decls, we can just look up the appropriate DIE. But /* For types, we can just look up the appropriate DIE. But
first we check to see if we're in the middle of emitting it so we first we check to see if we're in the middle of emitting it
know where the new DIE should go. */ so we know where the new DIE should go. */
for (i = decl_scope_depth - 1; i >= 0; --i) for (i = decl_scope_depth - 1; i >= 0; --i)
if (decl_scope_table[i].scope == containing_scope) if (decl_scope_table[i] == containing_scope)
break; break;
if (i < 0) if (i < 0)
{ {
/* Function-local tags and functions get stuck in limbo
until they are fixed up by decls_for_scope. */
if (TREE_CODE (containing_scope) == FUNCTION_DECL
&& (TREE_CODE (t) == FUNCTION_DECL || is_tagged_type (t)))
return NULL;
if (! TYPE_P (containing_scope))
abort ();
if (debug_info_level > DINFO_LEVEL_TERSE if (debug_info_level > DINFO_LEVEL_TERSE
&& !TREE_ASM_WRITTEN (containing_scope)) && !TREE_ASM_WRITTEN (containing_scope))
abort (); abort ();
...@@ -7682,56 +7648,25 @@ scope_die_for (t, context_die) ...@@ -7682,56 +7648,25 @@ scope_die_for (t, context_die)
scope_die = comp_unit_die; scope_die = comp_unit_die;
} }
else else
{ scope_die = lookup_type_die (containing_scope);
if (TYPE_P (containing_scope))
scope_die = lookup_type_die (containing_scope);
else
scope_die = lookup_decl_die (containing_scope);
}
} }
else else
{ scope_die = context_die;
/* Something that we can't just look up the DIE for, such as a
BLOCK. */
for (i = decl_scope_depth - 1, scope_die = context_die;
i >= 0 && decl_scope_table[i].scope != containing_scope;
(scope_die = scope_die->die_parent,
i = decl_scope_table[i].previous))
;
/* ??? Integrate_decl_tree does not handle BLOCK_TYPE_TAGS, nor
does it try to handle types defined by TYPE_DECLs. Such types
thus have an incorrect TYPE_CONTEXT, which points to the block
they were originally defined in, instead of the current block
created by function inlining. We try to detect that here and
work around it. */
if (i < 0 && scope_die == comp_unit_die
&& TREE_CODE (containing_scope) == BLOCK
&& is_tagged_type (t)
&& (block_ultimate_origin (decl_scope_table[decl_scope_depth - 1].scope)
== containing_scope))
{
scope_die = context_die;
/* Since the checks below are no longer applicable. */
i = 0;
}
if (i < 0)
abort ();
}
return scope_die; return scope_die;
} }
/* Pop a declaration scope. */ /* Returns nonzero iff CONTEXT_DIE is internal to a function. */
static inline void
pop_decl_scope () static inline int
local_scope_p (context_die)
dw_die_ref context_die;
{ {
if (decl_scope_depth <= 0) for (; context_die; context_die = context_die->die_parent)
abort (); if (context_die->die_tag == DW_TAG_inlined_subroutine
--decl_scope_depth; || context_die->die_tag == DW_TAG_subprogram)
return 1;
return 0;
} }
/* Many forms of DIEs require a "type description" attribute. This /* Many forms of DIEs require a "type description" attribute. This
...@@ -7981,7 +7916,7 @@ gen_inlined_enumeration_type_die (type, context_die) ...@@ -7981,7 +7916,7 @@ gen_inlined_enumeration_type_die (type, context_die)
register dw_die_ref context_die; register dw_die_ref context_die;
{ {
register dw_die_ref type_die = new_die (DW_TAG_enumeration_type, register dw_die_ref type_die = new_die (DW_TAG_enumeration_type,
scope_die_for (type, context_die)); context_die);
/* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
be incomplete and such types are not marked. */ be incomplete and such types are not marked. */
add_abstract_origin_attribute (type_die, type); add_abstract_origin_attribute (type_die, type);
...@@ -7994,8 +7929,8 @@ gen_inlined_structure_type_die (type, context_die) ...@@ -7994,8 +7929,8 @@ gen_inlined_structure_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 type_die = new_die (DW_TAG_structure_type, register dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die);
scope_die_for (type, context_die));
/* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
be incomplete and such types are not marked. */ be incomplete and such types are not marked. */
add_abstract_origin_attribute (type_die, type); add_abstract_origin_attribute (type_die, type);
...@@ -8008,8 +7943,8 @@ gen_inlined_union_type_die (type, context_die) ...@@ -8008,8 +7943,8 @@ gen_inlined_union_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 type_die = new_die (DW_TAG_union_type, register dw_die_ref type_die = new_die (DW_TAG_union_type, context_die);
scope_die_for (type, context_die));
/* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
be incomplete and such types are not marked. */ be incomplete and such types are not marked. */
add_abstract_origin_attribute (type_die, type); add_abstract_origin_attribute (type_die, type);
...@@ -8247,14 +8182,20 @@ gen_abstract_function (decl) ...@@ -8247,14 +8182,20 @@ gen_abstract_function (decl)
tree decl; tree decl;
{ {
register dw_die_ref old_die = lookup_decl_die (decl); register dw_die_ref old_die = lookup_decl_die (decl);
tree save_fn;
if (old_die && get_AT_unsigned (old_die, DW_AT_inline)) if (old_die && get_AT_unsigned (old_die, DW_AT_inline))
/* We've already generated the abstract instance. */ /* We've already generated the abstract instance. */
return; return;
save_fn = current_function_decl;
current_function_decl = decl;
set_decl_abstract_flags (decl, 1); set_decl_abstract_flags (decl, 1);
dwarf2out_decl (decl); dwarf2out_decl (decl);
set_decl_abstract_flags (decl, 0); set_decl_abstract_flags (decl, 0);
current_function_decl = save_fn;
} }
/* Generate a DIE to represent a declared function (either file-scope or /* Generate a DIE to represent a declared function (either file-scope or
...@@ -8273,7 +8214,7 @@ gen_subprogram_die (decl, context_die) ...@@ -8273,7 +8214,7 @@ gen_subprogram_die (decl, context_die)
register tree outer_scope; register tree outer_scope;
register dw_die_ref old_die = lookup_decl_die (decl); register dw_die_ref old_die = lookup_decl_die (decl);
register int declaration register int declaration
= ((current_function_decl != decl && ! DECL_ABSTRACT (decl)) = (current_function_decl != decl
|| (context_die || (context_die
&& (context_die->die_tag == DW_TAG_structure_type && (context_die->die_tag == DW_TAG_structure_type
|| context_die->die_tag == DW_TAG_union_type))); || context_die->die_tag == DW_TAG_union_type)));
...@@ -8287,7 +8228,7 @@ gen_subprogram_die (decl, context_die) ...@@ -8287,7 +8228,7 @@ gen_subprogram_die (decl, context_die)
if (origin != NULL) if (origin != NULL)
{ {
if (declaration) if (declaration && ! local_scope_p (context_die))
abort (); abort ();
subr_die = new_die (DW_TAG_subprogram, context_die); subr_die = new_die (DW_TAG_subprogram, context_die);
...@@ -8355,15 +8296,7 @@ gen_subprogram_die (decl, context_die) ...@@ -8355,15 +8296,7 @@ gen_subprogram_die (decl, context_die)
} }
else else
{ {
register dw_die_ref scope_die; subr_die = new_die (DW_TAG_subprogram, context_die);
if (DECL_CONTEXT (decl))
scope_die = scope_die_for (decl, context_die);
else
/* Don't put block extern declarations under comp_unit_die. */
scope_die = context_die;
subr_die = new_die (DW_TAG_subprogram, scope_die);
if (TREE_PUBLIC (decl)) if (TREE_PUBLIC (decl))
add_AT_flag (subr_die, DW_AT_external, 1); add_AT_flag (subr_die, DW_AT_external, 1);
...@@ -8388,13 +8321,14 @@ gen_subprogram_die (decl, context_die) ...@@ -8388,13 +8321,14 @@ gen_subprogram_die (decl, context_die)
if (declaration) if (declaration)
{ {
add_AT_flag (subr_die, DW_AT_declaration, 1); if (! origin)
add_AT_flag (subr_die, DW_AT_declaration, 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
the class first. The next time is the definition, which is the class first. The next time is the definition, which is
handled above. The two may come from the same source text. */ handled above. The two may come from the same source text. */
if (DECL_CONTEXT (decl)) if (DECL_CONTEXT (decl) || DECL_ABSTRACT (decl))
equate_decl_number_to_die (decl, subr_die); equate_decl_number_to_die (decl, subr_die);
} }
else if (DECL_ABSTRACT (decl)) else if (DECL_ABSTRACT (decl))
...@@ -8461,7 +8395,6 @@ gen_subprogram_die (decl, context_die) ...@@ -8461,7 +8395,6 @@ gen_subprogram_die (decl, context_die)
FUNCTION_TYPE. If the chain of type nodes hanging off of this FUNCTION_TYPE. If the chain of type nodes hanging off of this
FUNCTION_TYPE node ends with a void_type_node then there should *not* be FUNCTION_TYPE node ends with a void_type_node then there should *not* be
an ellipsis at the end. */ an ellipsis at the end. */
push_decl_scope (decl);
/* In the case where we are describing a mere function declaration, all we /* In the case where we are describing a mere function declaration, all we
need to do here (and all we *can* do here) is to describe the *types* of need to do here (and all we *can* do here) is to describe the *types* of
...@@ -8541,8 +8474,6 @@ gen_subprogram_die (decl, context_die) ...@@ -8541,8 +8474,6 @@ gen_subprogram_die (decl, context_die)
} }
#endif #endif
} }
pop_decl_scope ();
} }
/* Generate a DIE to represent a declared data object. */ /* Generate a DIE to represent a declared data object. */
...@@ -8690,9 +8621,7 @@ gen_lexical_block_die (stmt, context_die, depth) ...@@ -8690,9 +8621,7 @@ gen_lexical_block_die (stmt, context_die, depth)
add_AT_lbl_id (stmt_die, DW_AT_high_pc, label); add_AT_lbl_id (stmt_die, DW_AT_high_pc, label);
} }
push_decl_scope (stmt);
decls_for_scope (stmt, stmt_die, depth); decls_for_scope (stmt, stmt_die, depth);
pop_decl_scope ();
} }
/* Generate a DIE for an inlined subprogram. */ /* Generate a DIE for an inlined subprogram. */
...@@ -8719,9 +8648,7 @@ gen_inlined_subroutine_die (stmt, context_die, depth) ...@@ -8719,9 +8648,7 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
add_AT_lbl_id (subr_die, DW_AT_low_pc, label); add_AT_lbl_id (subr_die, DW_AT_low_pc, label);
ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, next_block_number); ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, next_block_number);
add_AT_lbl_id (subr_die, DW_AT_high_pc, label); add_AT_lbl_id (subr_die, DW_AT_high_pc, label);
push_decl_scope (decl);
decls_for_scope (stmt, subr_die, depth); decls_for_scope (stmt, subr_die, depth);
pop_decl_scope ();
current_function_has_inlines = 1; current_function_has_inlines = 1;
} }
} }
...@@ -9072,7 +8999,7 @@ gen_typedef_die (decl, context_die) ...@@ -9072,7 +8999,7 @@ gen_typedef_die (decl, context_die)
return; return;
TREE_ASM_WRITTEN (decl) = 1; TREE_ASM_WRITTEN (decl) = 1;
type_die = new_die (DW_TAG_typedef, scope_die_for (decl, context_die)); type_die = new_die (DW_TAG_typedef, context_die);
origin = decl_ultimate_origin (decl); origin = decl_ultimate_origin (decl);
if (origin != NULL) if (origin != NULL)
add_abstract_origin_attribute (type_die, origin); add_abstract_origin_attribute (type_die, origin);
...@@ -9195,7 +9122,7 @@ gen_type_die (type, context_die) ...@@ -9195,7 +9122,7 @@ gen_type_die (type, context_die)
written out yet, writing it out will cover this one, too. written out yet, writing it out will cover this one, too.
This does not apply to instantiations of member class templates; This does not apply to instantiations of member class templates;
they need to be added to the containing class as they are they need to be added to the containing class as they are
generated. FIXME: This breaks the idea of combining type decls generated. FIXME: This hurts the idea of combining type decls
from multiple TUs, since we can't predict what set of template from multiple TUs, since we can't predict what set of template
instantiations we'll get. */ instantiations we'll get. */
if (TYPE_CONTEXT (type) if (TYPE_CONTEXT (type)
...@@ -9474,7 +9401,7 @@ gen_decl_die (decl, context_die) ...@@ -9474,7 +9401,7 @@ gen_decl_die (decl, context_die)
/* Don't output any DIEs to represent mere function declarations, /* Don't output any DIEs to represent mere function declarations,
unless they are class members or explicit block externs. */ unless they are class members or explicit block externs. */
if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE
&& (current_function_decl == NULL_TREE || ! DECL_ARTIFICIAL (decl))) && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
break; break;
/* Emit info for the abstract instance first, if we haven't yet. */ /* Emit info for the abstract instance first, if we haven't yet. */
...@@ -9983,8 +9910,7 @@ dwarf2out_init (asm_out_file, main_input_filename) ...@@ -9983,8 +9910,7 @@ dwarf2out_init (asm_out_file, main_input_filename)
/* Allocate the initial hunk of the decl_scope_table. */ /* Allocate the initial hunk of the decl_scope_table. */
decl_scope_table decl_scope_table
= (decl_scope_node *) xcalloc (DECL_SCOPE_TABLE_INCREMENT, = (tree *) xcalloc (DECL_SCOPE_TABLE_INCREMENT, sizeof (tree));
sizeof (decl_scope_node));
decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT; decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
decl_scope_depth = 0; decl_scope_depth = 0;
......
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