]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR debug/37410 (DW_TAG_imported_module is not in its DW_TAG_lexical_block)
authorDodji Seketeli <dodji@redhat.com>
Sun, 5 Oct 2008 21:29:32 +0000 (21:29 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Sun, 5 Oct 2008 21:29:32 +0000 (23:29 +0200)
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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/cp/name-lookup.c
gcc/dwarf2out.c
gcc/print-tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C [new file with mode: 0644]
gcc/tree.c
gcc/tree.def
gcc/tree.h

index 71eaead3463480abb6ad58a2baa09eba8b20935f..c58932c9e27d78e67a87bb3672844de1bb17d017 100644 (file)
@@ -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,
index acb766f7124e45936d3cff513741cf52d5f98638..eeeb239b720202636c122c40ed2444b0792cf87c 100644 (file)
@@ -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
index 243b1c61bfb28ce0f827959b25e23cdd2b6dacd5..a1542b9f80423aaadbf502f7f4333f77f327fbf6 100644 (file)
@@ -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;
index a04d7312216c5bfbe8a94246a8460715eb162f81..0da373ce2a69fecc3febd0b7018f0a0b41ab5372 100644 (file)
@@ -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
index e39e687edbbe44cadb89a5009188f132b6ec093c..37bf21f07a2e9760ae616572e628d9c2acdef8c5 100644 (file)
@@ -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)
index 16ba3929fabd548d15e8be27c174ccac597e3665..fb9f12692c6f881b069a5322c62ef06528bb3b1d 100644 (file)
@@ -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))
index df7ba0b1e96269df616eb7aec9b6f91a0a152fa1..3edb676dcc817dd4799883339d52079a58e694ff 100644 (file)
@@ -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 (file)
index 0000000..7b25233
--- /dev/null
@@ -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;
+}
+
index 4b178d5073f733acb38cc89d876aa88e02f6c860..33ab8b7078bda38c3c5978034b7688ae4efc0ba1 100644 (file)
@@ -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 ();
 }
index ef103cdba502397ceeed143287aead87c03bc253..bde59b7016ce5589de1c6a8f3c7a39239da7e8e4 100644 (file)
@@ -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",\
index 4c046c29d645289397bdb34fda464bf99246ac90..85704e690949cdabc187cab4fdbe75dadac5360f 100644 (file)
@@ -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;