aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2008-10-05 21:29:32 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2008-10-05 23:29:32 +0200
commitd19c0f4b4cdf4bdffa313283207aab6d2518f34c (patch)
treed5227fd86e64dffe3a143d3c68ad3f1e06dab6a5
parentebb479cd4d397e829eed460bd7ac9040204f8b5a (diff)
downloadgcc-d19c0f4b4cdf4bdffa313283207aab6d2518f34c.zip
gcc-d19c0f4b4cdf4bdffa313283207aab6d2518f34c.tar.gz
gcc-d19c0f4b4cdf4bdffa313283207aab6d2518f34c.tar.bz2
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
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-gimplify.c35
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/dwarf2out.c118
-rw-r--r--gcc/print-tree.c6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C35
-rw-r--r--gcc/tree.c2
-rw-r--r--gcc/tree.def11
-rw-r--r--gcc/tree.h5
11 files changed, 204 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71eaead..c58932c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+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>
* doc/gimple.texi: Fix some typos, wrap some long lines,
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index acb766f..eeeb239 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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>
PR c++/37719
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 243b1c6..a1542b9 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -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;
enum tree_code code = TREE_CODE (*expr_p);
enum gimplify_status ret;
+ tree block = NULL;
+ VEC(gimple, heap) *bind_expr_stack = NULL;
if (STATEMENT_CODE_P (code))
{
@@ -574,8 +576,37 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
break;
case USING_STMT:
- /* Just ignore for now. Eventually we will want to pass this on to
- the debugger. */
+ /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
+ 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;
ret = GS_ALL_DONE;
break;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index a04d731..0da373c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3484,7 +3484,6 @@ do_using_directive (tree name_space)
if (!toplevel_bindings_p ())
{
push_using_directive (name_space);
- context = current_scope ();
}
else
{
@@ -3492,12 +3491,12 @@ do_using_directive (tree name_space)
add_using_namespace (current_namespace, name_space, 0);
if (current_namespace != global_namespace)
context = current_namespace;
- }
- /* Emit debugging info. */
- if (!processing_template_decl)
- (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
- context, false);
+ /* Emit debugging info. */
+ if (!processing_template_decl)
+ (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
+ context, false);
+ }
}
/* Deal with a using-directive seen by the parser. Currently we only
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e39e687..37bf21f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4489,6 +4489,8 @@ static bool dwarf2out_ignore_block (const_tree);
static void dwarf2out_global_decl (tree);
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_1 (tree, tree, tree,
+ dw_die_ref);
static void dwarf2out_abstract_function (tree);
static void dwarf2out_var_location (rtx);
static void dwarf2out_begin_function (tree);
@@ -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)
&& !(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
gen_decl_die (decl, context_die);
}
@@ -15309,6 +15314,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break;
case NAMESPACE_DECL:
+ case IMPORTED_DECL:
gen_namespace_die (decl);
break;
@@ -15343,44 +15349,20 @@ dwarf2out_type_decl (tree decl, int local)
}
/* 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. */
-
+ NAME is non-NULL name in the lexical block if the decl has been renamed.
+ LEXICAL_BLOCK is the lexical block (which TREE_CODE is a BLOCK)
+ that DECL belongs to.
+ LEXICAL_BLOCK_DIE is the DIE of LEXICAL_BLOCK. */
static void
-dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
- bool child)
+dwarf2out_imported_module_or_decl_1 (tree decl,
+ 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;
+ 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 (is_base_type (TREE_TYPE (decl)))
@@ -15398,6 +15380,19 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
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
{
at_import_die = lookup_decl_die (decl);
@@ -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)
- 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
- 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);
add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file));
add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line);
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);
}
+/* 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. */
void
@@ -15519,6 +15560,7 @@ dwarf2out_decl (tree decl)
break;
case NAMESPACE_DECL:
+ case IMPORTED_DECL:
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
if (lookup_decl_die (decl) != NULL)
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 16ba392..fb9f126 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -926,6 +926,12 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
case TARGET_OPTION_NODE:
cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node));
break;
+ case IMPORTED_DECL:
+ fprintf (file, " imported declaration");
+ print_node_brief (file, "associated declaration",
+ IMPORTED_DECL_ASSOCIATED_DECL (node),
+ indent + 4);
+ break;
default:
if (EXCEPTIONAL_CLASS_P (node))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index df7ba0b..3edb676 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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>
PR fortran/35680
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C
new file mode 100644
index 0000000..7b25233
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C
@@ -0,0 +1,35 @@
+// 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;
+}
+
diff --git a/gcc/tree.c b/gcc/tree.c
index 4b178d5..33ab8b7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -343,6 +343,8 @@ init_ttree (void)
tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1;
tree_contains_struct[TYPE_DECL][TS_TYPE_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 ();
}
diff --git a/gcc/tree.def b/gcc/tree.def
index ef103cd..bde59b7 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -371,6 +371,17 @@ DEFTREECODE (MEMORY_PARTITION_TAG, "memory_partition_tag", tcc_declaration, 0)
_DECLs, providing a hierarchy of names. */
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
can't be looked up, but it's close enough. */
DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\
diff --git a/gcc/tree.h b/gcc/tree.h
index 4c046c2..85704e6 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3334,6 +3334,11 @@ struct tree_function_decl GTY(())
#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
(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_decl_non_common common;