Commit d19c0f4b by Dodji Seketeli Committed by Dodji Seketeli

re PR debug/37410 (DW_TAG_imported_module is not in its DW_TAG_lexical_block)

2008-09-30  Dodji Seketeli  <dodji@redhat.com>
gcc/ChangeLog:

	PR c++/37410
	* dwarf2out.c (dwarf2out_imported_module_or_decl): Split this
	  function in two, making it call a new and reusable
	  dwarf2out_imported_module_or_decl() that takes the containing
	  BLOCK of the declaration in argument.
	  (dwarf2out_imported_module_or_decl_real): New function.
	  (decls_for_scope, gen_decl_die, dwarf2out_decl): Take
	  IMPORTED_DECL in account.
	* tree.def: Added IMPORTED_DECL node type.
	* tree.h: Added accessors for IMPORTED_DECL nodes.
	* tree.c (init_ttree): Initialise IMPORTED_DECL node type.

gcc/cp/ChangeLog:

	PR c++/37410
	* cp-gimplify.c (cp_gimplify_expr): For each USING_STMT
	  make sure an IMPORTED_DECL node is added to the BLOCK_VARS list
	  of the innermost containing BLOCK.

gcc/testsuite/ChangeLog:

	PR c++/37410
	* g++.dg/debug/dwarf2/imported-module.C: New test.

From-SVN: r140895
parent ebb479cd
2008-10-05 Dodji Seketeli <dodji@redhat.com>
PR c++/37410
* dwarf2out.c (dwarf2out_imported_module_or_decl): Split this
function in two, making it call a new and reusable
dwarf2out_imported_module_or_decl() that takes the containing
BLOCK of the declaration in argument.
(dwarf2out_imported_module_or_decl_real): New function.
(decls_for_scope, gen_decl_die, dwarf2out_decl): Take
IMPORTED_DECL in account.
* tree.def: Added IMPORTED_DECL node type.
* tree.h: Added accessors for IMPORTED_DECL nodes.
* tree.c (init_ttree): Initialise IMPORTED_DECL node type.
2008-10-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> 2008-10-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/gimple.texi: Fix some typos, wrap some long lines, * doc/gimple.texi: Fix some typos, wrap some long lines,
......
2008-10-05 Dodji Seketeli <dodji@redhat.com>
PR c++/37410
* cp-gimplify.c (cp_gimplify_expr): For each USING_STMT
make sure an IMPORTED_DECL node is added to the BLOCK_VARS list
of the innermost containing BLOCK.
2008-10-03 Paolo Carlini <paolo.carlini@oracle.com> 2008-10-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/37719 PR c++/37719
......
...@@ -508,6 +508,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) ...@@ -508,6 +508,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
int saved_stmts_are_full_exprs_p = 0; int saved_stmts_are_full_exprs_p = 0;
enum tree_code code = TREE_CODE (*expr_p); enum tree_code code = TREE_CODE (*expr_p);
enum gimplify_status ret; enum gimplify_status ret;
tree block = NULL;
VEC(gimple, heap) *bind_expr_stack = NULL;
if (STATEMENT_CODE_P (code)) if (STATEMENT_CODE_P (code))
{ {
...@@ -574,8 +576,37 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) ...@@ -574,8 +576,37 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
break; break;
case USING_STMT: case USING_STMT:
/* Just ignore for now. Eventually we will want to pass this on to /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
the debugger. */ BLOCK, and append an IMPORTED_DECL to its
BLOCK_VARS chained list. */
bind_expr_stack = gimple_bind_expr_stack ();
if (bind_expr_stack)
{
int i;
for (i = VEC_length (gimple, bind_expr_stack) - 1; i >= 0; i--)
if ((block = gimple_bind_block (VEC_index (gimple,
bind_expr_stack,
i))))
break;
}
if (block)
{
tree using_directive;
gcc_assert (TREE_OPERAND (*expr_p,0)
&& NAMESPACE_DECL_CHECK (TREE_OPERAND (*expr_p, 0)));
using_directive = make_node (IMPORTED_DECL);
TREE_TYPE (using_directive) = void_type_node;
IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
= TREE_OPERAND (*expr_p, 0);
DECL_NAME (using_directive)
= DECL_NAME (TREE_OPERAND (*expr_p, 0));
TREE_CHAIN (using_directive) = BLOCK_VARS (block);
BLOCK_VARS (block) = using_directive;
}
/* The USING_STMT won't appear in GIMPLE. */
*expr_p = NULL; *expr_p = NULL;
ret = GS_ALL_DONE; ret = GS_ALL_DONE;
break; break;
......
...@@ -3484,7 +3484,6 @@ do_using_directive (tree name_space) ...@@ -3484,7 +3484,6 @@ do_using_directive (tree name_space)
if (!toplevel_bindings_p ()) if (!toplevel_bindings_p ())
{ {
push_using_directive (name_space); push_using_directive (name_space);
context = current_scope ();
} }
else else
{ {
...@@ -3492,12 +3491,12 @@ do_using_directive (tree name_space) ...@@ -3492,12 +3491,12 @@ do_using_directive (tree name_space)
add_using_namespace (current_namespace, name_space, 0); add_using_namespace (current_namespace, name_space, 0);
if (current_namespace != global_namespace) if (current_namespace != global_namespace)
context = current_namespace; context = current_namespace;
}
/* Emit debugging info. */ /* Emit debugging info. */
if (!processing_template_decl) if (!processing_template_decl)
(*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE, (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
context, false); context, false);
}
} }
/* Deal with a using-directive seen by the parser. Currently we only /* Deal with a using-directive seen by the parser. Currently we only
......
...@@ -4489,6 +4489,8 @@ static bool dwarf2out_ignore_block (const_tree); ...@@ -4489,6 +4489,8 @@ static bool dwarf2out_ignore_block (const_tree);
static void dwarf2out_global_decl (tree); static void dwarf2out_global_decl (tree);
static void dwarf2out_type_decl (tree, int); static void dwarf2out_type_decl (tree, int);
static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool); static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool);
static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
dw_die_ref);
static void dwarf2out_abstract_function (tree); static void dwarf2out_abstract_function (tree);
static void dwarf2out_var_location (rtx); static void dwarf2out_var_location (rtx);
static void dwarf2out_begin_function (tree); static void dwarf2out_begin_function (tree);
...@@ -14918,6 +14920,9 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth) ...@@ -14918,6 +14920,9 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& !(is_fortran () && TREE_PUBLIC (decl))) && !(is_fortran () && TREE_PUBLIC (decl)))
; ;
else if (TREE_CODE (decl) == IMPORTED_DECL)
dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
stmt, context_die);
else else
gen_decl_die (decl, context_die); gen_decl_die (decl, context_die);
} }
...@@ -15309,6 +15314,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15309,6 +15314,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
case IMPORTED_DECL:
gen_namespace_die (decl); gen_namespace_die (decl);
break; break;
...@@ -15343,44 +15349,20 @@ dwarf2out_type_decl (tree decl, int local) ...@@ -15343,44 +15349,20 @@ dwarf2out_type_decl (tree decl, int local)
} }
/* Output debug information for imported module or decl DECL. /* Output debug information for imported module or decl DECL.
NAME is non-NULL name in context if the decl has been renamed. NAME is non-NULL name in the lexical block if the decl has been renamed.
CHILD is true if decl is one of the renamed decls as part of LEXICAL_BLOCK is the lexical block (which TREE_CODE is a BLOCK)
importing whole module. */ that DECL belongs to.
LEXICAL_BLOCK_DIE is the DIE of LEXICAL_BLOCK. */
static void static void
dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, dwarf2out_imported_module_or_decl_1 (tree decl,
bool child) tree name,
tree lexical_block,
dw_die_ref lexical_block_die)
{ {
dw_die_ref imported_die, at_import_die;
dw_die_ref scope_die;
expanded_location xloc; expanded_location xloc;
dw_die_ref imported_die = NULL;
dw_die_ref at_import_die;
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
gcc_assert (decl);
/* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
We need decl DIE for reference and scope die. First, get DIE for the decl
itself. */
/* Get the scope die for decl context. Use comp_unit_die for global module
or decl. If die is not found for non globals, force new die. */
if (context
&& TYPE_P (context)
&& !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
return;
scope_die = get_context_die (context);
if (child)
{
gcc_assert (scope_die->die_child);
gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module);
gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL);
scope_die = scope_die->die_child;
}
/* For TYPE_DECL or CONST_DECL, lookup TREE_TYPE. */
if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL) if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
{ {
if (is_base_type (TREE_TYPE (decl))) if (is_base_type (TREE_TYPE (decl)))
...@@ -15398,6 +15380,19 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, ...@@ -15398,6 +15380,19 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
gcc_assert (at_import_die); gcc_assert (at_import_die);
} }
} }
else if (TREE_CODE (decl) == IMPORTED_DECL)
{
tree imported_ns_decl;
/* IMPORTED_DECL nodes that are not imported namespace are just not
supported yet. */
gcc_assert (DECL_INITIAL (decl)
&& TREE_CODE (DECL_INITIAL (decl)) == NAMESPACE_DECL);
imported_ns_decl = DECL_INITIAL (decl);
at_import_die = lookup_decl_die (imported_ns_decl);
if (!at_import_die)
at_import_die = force_decl_die (imported_ns_decl);
gcc_assert (at_import_die);
}
else else
{ {
at_import_die = lookup_decl_die (decl); at_import_die = lookup_decl_die (decl);
...@@ -15421,20 +15416,66 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, ...@@ -15421,20 +15416,66 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
} }
} }
/* OK, now we have DIEs for decl as well as scope. Emit imported die. */
if (TREE_CODE (decl) == NAMESPACE_DECL) if (TREE_CODE (decl) == NAMESPACE_DECL)
imported_die = new_die (DW_TAG_imported_module, scope_die, context); imported_die = new_die (DW_TAG_imported_module,
lexical_block_die,
lexical_block);
else else
imported_die = new_die (DW_TAG_imported_declaration, scope_die, context); imported_die = new_die (DW_TAG_imported_declaration,
lexical_block_die,
lexical_block);
xloc = expand_location (input_location); xloc = expand_location (input_location);
add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file)); add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file));
add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line); add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line);
if (name) if (name)
add_AT_string (imported_die, DW_AT_name, IDENTIFIER_POINTER (name)); add_AT_string (imported_die, DW_AT_name,
IDENTIFIER_POINTER (name));
add_AT_die_ref (imported_die, DW_AT_import, at_import_die); add_AT_die_ref (imported_die, DW_AT_import, at_import_die);
} }
/* Output debug information for imported module or decl DECL.
NAME is non-NULL name in context if the decl has been renamed.
CHILD is true if decl is one of the renamed decls as part of
importing whole module. */
static void
dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
bool child)
{
/* dw_die_ref at_import_die; */
dw_die_ref scope_die;
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
gcc_assert (decl);
/* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
We need decl DIE for reference and scope die. First, get DIE for the decl
itself. */
/* Get the scope die for decl context. Use comp_unit_die for global module
or decl. If die is not found for non globals, force new die. */
if (context
&& TYPE_P (context)
&& !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
return;
scope_die = get_context_die (context);
if (child)
{
gcc_assert (scope_die->die_child);
gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module);
gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL);
scope_die = scope_die->die_child;
}
/* OK, now we have DIEs for decl as well as scope. Emit imported die. */
dwarf2out_imported_module_or_decl_1 (decl, name, context, scope_die);
}
/* Write the debugging output for DECL. */ /* Write the debugging output for DECL. */
void void
...@@ -15519,6 +15560,7 @@ dwarf2out_decl (tree decl) ...@@ -15519,6 +15560,7 @@ dwarf2out_decl (tree decl)
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
case IMPORTED_DECL:
if (debug_info_level <= DINFO_LEVEL_TERSE) if (debug_info_level <= DINFO_LEVEL_TERSE)
return; return;
if (lookup_decl_die (decl) != NULL) if (lookup_decl_die (decl) != NULL)
......
...@@ -926,6 +926,12 @@ print_node (FILE *file, const char *prefix, tree node, int indent) ...@@ -926,6 +926,12 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
case TARGET_OPTION_NODE: case TARGET_OPTION_NODE:
cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node)); cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node));
break; break;
case IMPORTED_DECL:
fprintf (file, " imported declaration");
print_node_brief (file, "associated declaration",
IMPORTED_DECL_ASSOCIATED_DECL (node),
indent + 4);
break;
default: default:
if (EXCEPTIONAL_CLASS_P (node)) if (EXCEPTIONAL_CLASS_P (node))
......
2008-10-05 Dodji Seketeli <dodji@redhat.com>
PR c++/37410
* g++.dg/debug/dwarf2/imported-module.C: New test.
2008-10-05 Paul Thomas <pault@gcc.gnu.org> 2008-10-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35680 PR fortran/35680
......
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin: PR debug/37410
// { dg-do compile }
namespace A1
{
int aaa = 1;
};
namespace A2
{
int aaa = 2;
};
int
foo (void)
{
int x;
{
int block_create;
using namespace A1;
block_create = aaa; /* break1 */
}
{
int block_create;
using namespace A2;
block_create = aaa; /* break2 */
}
return x = 0;
}
...@@ -343,6 +343,8 @@ init_ttree (void) ...@@ -343,6 +343,8 @@ init_ttree (void)
tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1; tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1;
tree_contains_struct[TYPE_DECL][TS_TYPE_DECL] = 1; tree_contains_struct[TYPE_DECL][TS_TYPE_DECL] = 1;
tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL] = 1; tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL] = 1;
tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL] = 1;
tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON] = 1;
lang_hooks.init_ts (); lang_hooks.init_ts ();
} }
......
...@@ -371,6 +371,17 @@ DEFTREECODE (MEMORY_PARTITION_TAG, "memory_partition_tag", tcc_declaration, 0) ...@@ -371,6 +371,17 @@ DEFTREECODE (MEMORY_PARTITION_TAG, "memory_partition_tag", tcc_declaration, 0)
_DECLs, providing a hierarchy of names. */ _DECLs, providing a hierarchy of names. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0) DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0)
/* A declaration import.
The C++ FE uses this to represent a using-directive; eg:
"using namespace foo".
But it could be used to represent any declaration import construct.
Whenever a declaration import appears in a lexical block, the BLOCK node
representing that lexical block in GIMPLE will contain an IMPORTED_DECL
node, linked via BLOCK_VARS accessor of the said BLOCK.
For a given NODE which code is IMPORTED_DECL,
IMPORTED_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration. */
DEFTREECODE (IMPORTED_DECL, "imported_decl", tcc_declaration, 0)
/* A translation unit. This is not technically a declaration, since it /* A translation unit. This is not technically a declaration, since it
can't be looked up, but it's close enough. */ can't be looked up, but it's close enough. */
DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\ DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\
......
...@@ -3334,6 +3334,11 @@ struct tree_function_decl GTY(()) ...@@ -3334,6 +3334,11 @@ struct tree_function_decl GTY(())
#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \ #define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
(TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_2) (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_2)
/* Getter of the imported declaration associated to the
IMPORTED_DECL node. */
#define IMPORTED_DECL_ASSOCIATED_DECL(NODE) \
(DECL_INITIAL (IMPORTED_DECL_CHECK (NODE)))
struct tree_type_decl GTY(()) struct tree_type_decl GTY(())
{ {
struct tree_decl_non_common common; struct tree_decl_non_common common;
......
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