Commit 0fd0752e by Jason Merrill Committed by Jason Merrill

dwarf2out.c (modified_type_die): Use scope_die_for.

	* dwarf2out.c (modified_type_die): Use scope_die_for.
	(gen_type_die_with_usage, dwarf2out_finish): Likewise.
	(uses_local_type_r, uses_local_type): New.
	(scope_die_for): Keep a type that uses a local type in local scope.
	Use get_context_die for namespace and type scope.

From-SVN: r187106
parent 63aaf27c
2012-05-03 Jason Merrill <jason@redhat.com> 2012-05-03 Jason Merrill <jason@redhat.com>
* dwarf2out.c (modified_type_die): Use scope_die_for.
(gen_type_die_with_usage, dwarf2out_finish): Likewise.
(uses_local_type_r, uses_local_type): New.
(scope_die_for): Keep a type that uses a local type in local scope.
Use get_context_die for namespace and type scope.
2012-05-03 Jason Merrill <jason@redhat.com>
* config/i386/i386.c (ix86_code_end): Set DECL_IGNORED_P on the * config/i386/i386.c (ix86_code_end): Set DECL_IGNORED_P on the
pc thunk. pc thunk.
* dwarf2out.c (output_aranges): Skip DECL_IGNORED_P functions. * dwarf2out.c (output_aranges): Skip DECL_IGNORED_P functions.
......
...@@ -9021,6 +9021,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, ...@@ -9021,6 +9021,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
tree item_type = NULL; tree item_type = NULL;
tree qualified_type; tree qualified_type;
tree name, low, high; tree name, low, high;
dw_die_ref mod_scope;
if (code == ERROR_MARK) if (code == ERROR_MARK)
return NULL; return NULL;
...@@ -9081,6 +9082,8 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, ...@@ -9081,6 +9082,8 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
/* Else cv-qualified version of named type; fall through. */ /* Else cv-qualified version of named type; fall through. */
} }
mod_scope = scope_die_for (type, context_die);
if (is_const_type if (is_const_type
/* If both is_const_type and is_volatile_type, prefer the path /* If both is_const_type and is_volatile_type, prefer the path
which leads to a qualified type. */ which leads to a qualified type. */
...@@ -9088,17 +9091,17 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, ...@@ -9088,17 +9091,17 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
|| get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE || get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE
|| get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE)) || get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE))
{ {
mod_type_die = new_die (DW_TAG_const_type, comp_unit_die (), type); mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
sub_die = modified_type_die (type, 0, is_volatile_type, context_die); sub_die = modified_type_die (type, 0, is_volatile_type, context_die);
} }
else if (is_volatile_type) else if (is_volatile_type)
{ {
mod_type_die = new_die (DW_TAG_volatile_type, comp_unit_die (), type); mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
sub_die = modified_type_die (type, is_const_type, 0, context_die); sub_die = modified_type_die (type, is_const_type, 0, context_die);
} }
else if (code == POINTER_TYPE) else if (code == POINTER_TYPE)
{ {
mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die (), type); mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, add_AT_unsigned (mod_type_die, DW_AT_byte_size,
simple_type_size_in_bits (type) / BITS_PER_UNIT); simple_type_size_in_bits (type) / BITS_PER_UNIT);
item_type = TREE_TYPE (type); item_type = TREE_TYPE (type);
...@@ -9109,10 +9112,10 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, ...@@ -9109,10 +9112,10 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
else if (code == REFERENCE_TYPE) else if (code == REFERENCE_TYPE)
{ {
if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
mod_type_die = new_die (DW_TAG_rvalue_reference_type, comp_unit_die (), mod_type_die = new_die (DW_TAG_rvalue_reference_type, mod_scope,
type); type);
else else
mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die (), type); mod_type_die = new_die (DW_TAG_reference_type, mod_scope, type);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, add_AT_unsigned (mod_type_die, DW_AT_byte_size,
simple_type_size_in_bits (type) / BITS_PER_UNIT); simple_type_size_in_bits (type) / BITS_PER_UNIT);
item_type = TREE_TYPE (type); item_type = TREE_TYPE (type);
...@@ -15301,10 +15304,36 @@ pop_decl_scope (void) ...@@ -15301,10 +15304,36 @@ pop_decl_scope (void)
VEC_pop (tree, decl_scope_table); VEC_pop (tree, decl_scope_table);
} }
/* walk_tree helper function for uses_local_type, below. */
static tree
uses_local_type_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
if (!TYPE_P (*tp))
*walk_subtrees = 0;
else
{
tree name = TYPE_NAME (*tp);
if (name && DECL_P (name) && decl_function_context (name))
return *tp;
}
return NULL_TREE;
}
/* If TYPE involves a function-local type (including a local typedef to a
non-local type), returns that type; otherwise returns NULL_TREE. */
static tree
uses_local_type (tree type)
{
tree used = walk_tree_without_duplicates (&type, uses_local_type_r, NULL);
return used;
}
/* Return the DIE for the scope that immediately contains this type. /* Return the DIE for the scope that immediately contains this type.
Non-named types get global scope. Named types nested in other Non-named types that do not involve a function-local type get global
types get their containing scope if it's open, or global scope scope. Named types nested in namespaces or other types get their
otherwise. All other types (i.e. function-local named types) get containing scope. All other types (i.e. function-local named types) get
the current active scope. */ the current active scope. */
static dw_die_ref static dw_die_ref
...@@ -15312,18 +15341,24 @@ scope_die_for (tree t, dw_die_ref context_die) ...@@ -15312,18 +15341,24 @@ scope_die_for (tree t, dw_die_ref context_die)
{ {
dw_die_ref scope_die = NULL; dw_die_ref scope_die = NULL;
tree containing_scope; tree containing_scope;
int i;
/* Non-types always go in the current scope. */ /* Non-types always go in the current scope. */
gcc_assert (TYPE_P (t)); gcc_assert (TYPE_P (t));
containing_scope = TYPE_CONTEXT (t); /* Use the scope of the typedef, rather than the scope of the type
it refers to. */
if (TYPE_NAME (t) && DECL_P (TYPE_NAME (t)))
containing_scope = DECL_CONTEXT (TYPE_NAME (t));
else
containing_scope = TYPE_CONTEXT (t);
/* Use the containing namespace if it was passed in (for a declaration). */ /* Use the containing namespace if there is one. */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL) if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
{ {
if (context_die == lookup_decl_die (containing_scope)) if (context_die == lookup_decl_die (containing_scope))
/* OK */; /* OK */;
else if (debug_info_level > DINFO_LEVEL_TERSE)
context_die = get_context_die (containing_scope);
else else
containing_scope = NULL_TREE; containing_scope = NULL_TREE;
} }
...@@ -15335,30 +15370,25 @@ scope_die_for (tree t, dw_die_ref context_die) ...@@ -15335,30 +15370,25 @@ scope_die_for (tree t, dw_die_ref context_die)
containing_scope = NULL_TREE; containing_scope = NULL_TREE;
if (SCOPE_FILE_SCOPE_P (containing_scope)) if (SCOPE_FILE_SCOPE_P (containing_scope))
scope_die = comp_unit_die (); {
/* If T uses a local type keep it local as well, to avoid references
to function-local DIEs from outside the function. */
if (current_function_decl && uses_local_type (t))
scope_die = context_die;
else
scope_die = comp_unit_die ();
}
else if (TYPE_P (containing_scope)) else if (TYPE_P (containing_scope))
{ {
/* For types, we can just look up the appropriate DIE. But /* For types, we can just look up the appropriate DIE. */
first we check to see if we're in the middle of emitting it if (debug_info_level > DINFO_LEVEL_TERSE)
so we know where the new DIE should go. */ scope_die = get_context_die (containing_scope);
for (i = VEC_length (tree, decl_scope_table) - 1; i >= 0; --i) else
if (VEC_index (tree, decl_scope_table, i) == containing_scope)
break;
if (i < 0)
{ {
gcc_assert (debug_info_level <= DINFO_LEVEL_TERSE scope_die = lookup_type_die_strip_naming_typedef (containing_scope);
|| TREE_ASM_WRITTEN (containing_scope));
/*We are not in the middle of emitting the type
CONTAINING_SCOPE. Let's see if it's emitted already. */
scope_die = lookup_type_die (containing_scope);
/* If none of the current dies are suitable, we get file scope. */
if (scope_die == NULL) if (scope_die == NULL)
scope_die = comp_unit_die (); scope_die = comp_unit_die ();
} }
else
scope_die = lookup_type_die_strip_naming_typedef (containing_scope);
} }
else else
scope_die = context_die; scope_die = context_die;
...@@ -18154,12 +18184,8 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, ...@@ -18154,12 +18184,8 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
/* Prevent broken recursion; we can't hand off to the same type. */ /* Prevent broken recursion; we can't hand off to the same type. */
gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type); gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
/* Use the DIE of the containing namespace as the parent DIE of /* Give typedefs the right scope. */
the type description DIE we want to generate. */ context_die = scope_die_for (type, context_die);
if (DECL_FILE_SCOPE_P (TYPE_NAME (type))
|| (DECL_CONTEXT (TYPE_NAME (type))
&& TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL))
context_die = get_context_die (DECL_CONTEXT (TYPE_NAME (type)));
TREE_ASM_WRITTEN (type) = 1; TREE_ASM_WRITTEN (type) = 1;
...@@ -21782,16 +21808,15 @@ dwarf2out_finish (const char *filename) ...@@ -21782,16 +21808,15 @@ dwarf2out_finish (const char *filename)
inlined and optimized out. In that case we are lost and inlined and optimized out. In that case we are lost and
assign the empty child. This should not be big issue as assign the empty child. This should not be big issue as
the function is likely unreachable too. */ the function is likely unreachable too. */
tree context = NULL_TREE;
gcc_assert (node->created_for); gcc_assert (node->created_for);
if (DECL_P (node->created_for)) if (DECL_P (node->created_for))
context = DECL_CONTEXT (node->created_for); origin = get_context_die (DECL_CONTEXT (node->created_for));
else if (TYPE_P (node->created_for)) else if (TYPE_P (node->created_for))
context = TYPE_CONTEXT (node->created_for); origin = scope_die_for (node->created_for, comp_unit_die ());
else
origin = comp_unit_die ();
origin = get_context_die (context);
add_child_die (origin, die); add_child_die (origin, die);
} }
} }
......
2012-05-03 Jason Merrill <jason@redhat.com> 2012-05-03 Jason Merrill <jason@redhat.com>
* g++.dg/debug/dwarf2/namespace-2.C: New.
* g++.dg/debug/dwarf2/localclass3.C: New.
2012-05-03 Jason Merrill <jason@redhat.com>
* g++.dg/debug/dwarf2/thunk1.C: New. * g++.dg/debug/dwarf2/thunk1.C: New.
2012-05-03 Paolo Carlini <paolo.carlini@oracle.com> 2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
......
// Test that the A* pointer_type is also within the debug info for f.
// Currently GCC emits it immediately before A, which is simple to test for.
// { dg-options "-g -dA" }
void f()
{
struct A { int i; } *ap;
ap->i = 42;
}
// { dg-final { scan-assembler "DW_TAG_pointer_type.\[^)\]*. DW_TAG_structure_type" } }
// Test that we define A inside the namespace rather than declaring it
// there and then defining it at CU scope.
// { dg-options "-g -dA" }
// { dg-final { scan-assembler-not "DW_AT_declaration" } }
namespace N {
struct A;
}
struct N::A { } a;
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