+ * c/c-decl.c (write_global_declarations_1): Call global_decl() + with early=true.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 4 Sep 2014 16:38:21 +0000 (16:38 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Thu, 4 Sep 2014 16:38:21 +0000 (16:38 +0000)
+       * c/c-decl.c (write_global_declarations_1): Call global_decl()
+       with early=true.
+       (write_global_declarations_2): Call global_decl() with
+       early=false.
+       * dbxout.c (dbxout_global_decl): New argument.
+       * debug.c (do_nothing_debug_hooks): Use debug_nothing_tree_bool
+       for global_decl hook.
+       (debug_nothing_tree_bool): New.
+       (struct gcc_debug_hooks): New argument to global_decl.
+       * dwarf2out.c (output_die): Add misc debugging information.
+       (gen_variable_die): Do not reparent children.
+       (dwarf2out_global_decl): Add new documentation.  Add EARLY
+       argument.
+       (dwarf2out_decl): Make sure we don't generate new DIEs if we
+       already have a DIE.
+       * cp/name-lookup.c (do_namespace_alias): New argument to
+       global_decl debug hook.
+       * fortran/trans-decl.c (gfc_emit_parameter_debug_info): Same.
+       * godump.c (go_global_decl): Same.
+       * lto/lto-lang.c (lto_write_globals): Same.
+       * sdbout.c (sdbout_global_decl): Same.
+       * toplev.c (emit_debug_global_declarations): Same.
+       * vmsdbgout.c (vmsdbgout_global_decl): Same.
+       * tree.c (free_lang_data_in_decl): Do not call
+       dwarf2out_early_decl from here.

From-SVN: r214911

14 files changed:
gcc/ChangeLog.debug-early
gcc/c/c-decl.c
gcc/cp/name-lookup.c
gcc/dbxout.c
gcc/debug.c
gcc/debug.h
gcc/dwarf2out.c
gcc/fortran/trans-decl.c
gcc/godump.c
gcc/lto/lto-lang.c
gcc/sdbout.c
gcc/toplev.c
gcc/tree.c
gcc/vmsdbgout.c

index df571a47fde2b9df07e1b12612e04655b7030899..980b65513fa9cf217b06de24b64af9535077f839 100644 (file)
@@ -1,3 +1,31 @@
+2014-09-03  Aldy Hernandez  <aldyh@redhat.com>
+
+       * c/c-decl.c (write_global_declarations_1): Call global_decl()
+       with early=true.
+       (write_global_declarations_2): Call global_decl() with
+       early=false.
+       * dbxout.c (dbxout_global_decl): New argument.
+       * debug.c (do_nothing_debug_hooks): Use debug_nothing_tree_bool
+       for global_decl hook.
+       (debug_nothing_tree_bool): New.
+       (struct gcc_debug_hooks): New argument to global_decl.
+       * dwarf2out.c (output_die): Add misc debugging information.
+       (gen_variable_die): Do not reparent children.
+       (dwarf2out_global_decl): Add new documentation.  Add EARLY
+       argument.
+       (dwarf2out_decl): Make sure we don't generate new DIEs if we
+       already have a DIE.
+       * cp/name-lookup.c (do_namespace_alias): New argument to
+       global_decl debug hook.
+       * fortran/trans-decl.c (gfc_emit_parameter_debug_info): Same.
+       * godump.c (go_global_decl): Same.
+       * lto/lto-lang.c (lto_write_globals): Same.
+       * sdbout.c (sdbout_global_decl): Same.
+       * toplev.c (emit_debug_global_declarations): Same.
+       * vmsdbgout.c (vmsdbgout_global_decl): Same.
+       * tree.c (free_lang_data_in_decl): Do not call
+       dwarf2out_early_decl from here.
+
 2014-08-26  Aldy Hernandez  <aldyh@redhat.com>
 
        * dwarf2out.c (struct die_struct): Add dumped_early field.
index b4995a67733c6c74cdba559cced0e43a774559b9..1e09404dd55ea72f16fea943908ebffe39b3b14a 100644 (file)
@@ -10308,7 +10308,10 @@ c_write_global_declarations_1 (tree globals)
   while (reconsider);
 
   for (decl = globals; decl; decl = DECL_CHAIN (decl))
-    check_global_declaration_1 (decl);
+    {
+      check_global_declaration_1 (decl);
+      debug_hooks->global_decl (decl, /*early=*/true);
+    }
 }
 
 /* A subroutine of c_write_global_declarations Emit debug information for each
@@ -10320,7 +10323,7 @@ c_write_global_declarations_2 (tree globals)
   tree decl;
 
   for (decl = globals; decl ; decl = DECL_CHAIN (decl))
-    debug_hooks->global_decl (decl);
+    debug_hooks->global_decl (decl, /*early=*/false);
 }
 
 /* Callback to collect a source_ref from a DECL.  */
index ebcbb5c5580f4933a7252d76a70a83de943a6f36..45b3b999325932f84343388e82de4e66ea586240 100644 (file)
@@ -3859,7 +3859,7 @@ do_namespace_alias (tree alias, tree name_space)
 
   /* Emit debug info for namespace alias.  */
   if (!building_stmt_list_p ())
-    (*debug_hooks->global_decl) (alias);
+    (*debug_hooks->global_decl) (alias, /*early=*/false);
 }
 
 /* Like pushdecl, only it places X in the current namespace,
index d856bddc115d8fa4f3bdb1d0bbece8a587ba0dfd..208cec91b8e0252dfc3a984dfa625e8726cc326e 100644 (file)
@@ -325,7 +325,7 @@ static int dbxout_symbol_location (tree, tree, const char *, rtx);
 static void dbxout_symbol_name (tree, const char *, int);
 static void dbxout_common_name (tree, const char *, stab_code_type);
 static const char *dbxout_common_check (tree, int *);
-static void dbxout_global_decl (tree);
+static void dbxout_global_decl (tree, bool);
 static void dbxout_type_decl (tree, int);
 static void dbxout_handle_pch (unsigned);
 static void debug_free_queue (void);
@@ -1320,7 +1320,7 @@ dbxout_function_decl (tree decl)
 /* Debug information for a global DECL.  Called from toplev.c after
    compilation proper has finished.  */
 static void
-dbxout_global_decl (tree decl)
+dbxout_global_decl (tree decl, bool early ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
index dba068cc24adc88b1072324c019df2b498b862c7..b5818de3a3b1d086918c281b60f1a4358f26319a 100644 (file)
@@ -43,7 +43,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
   debug_nothing_tree,                   /* begin_function */
   debug_nothing_int,                    /* end_function */
   debug_nothing_tree,                   /* function_decl */
-  debug_nothing_tree,                   /* global_decl */
+  debug_nothing_tree_bool,              /* global_decl */
   debug_nothing_tree_int,               /* type_decl */
   debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
@@ -70,6 +70,12 @@ debug_nothing_tree (tree decl ATTRIBUTE_UNUSED)
 {
 }
 
+void
+debug_nothing_tree_bool (tree decl ATTRIBUTE_UNUSED,
+                        bool early ATTRIBUTE_UNUSED)
+{
+}
+
 void
 debug_nothing_tree_tree (tree t1 ATTRIBUTE_UNUSED,
                         tree t2 ATTRIBUTE_UNUSED)
index 28bc2104b1b911b49514f581fb12368789cebba8..944051524437b987c7c94fdf08f4e938825d9a5f 100644 (file)
@@ -93,8 +93,11 @@ struct gcc_debug_hooks
   void (* function_decl) (tree decl);
 
   /* Debug information for a global DECL.  Called from toplev.c after
-     compilation proper has finished.  */
-  void (* global_decl) (tree decl);
+     compilation proper has finished.  EARLY is true if global_decl()
+     is being called early on in the compilation process (i.e., before
+     cgraph information is available and before code is
+     generated).  */
+  void (* global_decl) (tree decl, bool early);
 
   /* Debug information for a type DECL.  Called from toplev.c after
      compilation proper, also from various language front ends to
@@ -156,6 +159,7 @@ extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *,
 extern void debug_nothing_int (unsigned int);
 extern void debug_nothing_int_int (unsigned int, unsigned int);
 extern void debug_nothing_tree (tree);
+extern void debug_nothing_tree_bool (tree, bool);
 extern void debug_nothing_tree_tree (tree, tree);
 extern void debug_nothing_tree_int (tree, int);
 extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
index c4952e7f132896b055e2d9fe86d233514a6f0362..918f26177eee4350dcb1c61ded25a179aa7016ca 100644 (file)
@@ -2430,7 +2430,7 @@ static void dwarf2out_function_decl (tree);
 static void dwarf2out_begin_block (unsigned, unsigned);
 static void dwarf2out_end_block (unsigned, unsigned);
 static bool dwarf2out_ignore_block (const_tree);
-static void dwarf2out_global_decl (tree);
+static void dwarf2out_global_decl (tree, bool);
 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,
@@ -8711,10 +8711,11 @@ output_die (dw_die_ref die)
   if (! die->comdat_type_p && die->die_id.die_symbol)
     output_die_symbol (die);
 
-  dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s (parent DIE=%#lx))",
+  dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s (parent DIE=%#lx) early=%d)",
                               (unsigned long)die->die_offset,
                               dwarf_tag_name (die->die_tag),
-                              die->die_parent ? die->die_parent->die_offset : 0);
+                              die->die_parent ? die->die_parent->die_offset : 0,
+                              die->dumped_early);
 
   FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
     {
@@ -19009,13 +19010,11 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
   if (old_die && !declaration && !local_scope_p (context_die))
     return;
 
-  /* When DIEs are created early, the context is the compilation unit.
-     Adjust the context when we know what it is the second time
-     around.  */
+  /* If a DIE was dumped early, it still needs location info.  Skip to
+     the part where we fill the location bits.  */
   if (old_die && old_die->dumped_early)
     {
-      if (old_die->die_parent != context_die)
-       reparent_child (old_die, context_die);
+      gcc_assert (old_die->die_parent == context_die);
       var_die = old_die;
       old_die = NULL;
       goto gen_variable_die_location;
@@ -20818,12 +20817,29 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
   return NULL;
 }
 \f
-/* Output debug information for global decl DECL.  Called from toplev.c after
-   compilation proper has finished.  */
+/* Output debug information for global decl DECL.  Called from
+   toplev.c after compilation proper has finished.
+
+   dwarf2out_decl() will be called twice on each global symbol: once
+   immediately after parsing (EARLY=true), and once after the full
+   compilation has finished (EARLY=false).  There are checks in
+   dwarf2out_decl() to make sure that if we have a DECL DIE upon
+   entry, that the previously created DIE is reused.  No new DECL DIEs
+   should be created when EARLY=false.
+
+   The second time dwarf2out_decl() is called (or for that matter, the
+   second time any DECL DIE is seen throughout dwarf2out), only
+   information not previously available (e.g. location) is tacked onto
+   the early dumped DIE.  That's the plan anyhow ;-).  */
 
 static void
-dwarf2out_global_decl (tree decl)
+dwarf2out_global_decl (tree decl, bool early)
 {
+  if (early)
+    {
+      dwarf2out_early_decl (decl);
+      return;
+    }
   /* Output DWARF2 information for file-scope tentative data object
      declarations, file-scope (extern) function declarations (which
      had no corresponding body) and file-scope tagged type declarations
@@ -21019,6 +21035,19 @@ dwarf2out_decl (tree decl)
 {
   dw_die_ref context_die = comp_unit_die ();
 
+#ifdef ENABLE_CHECKING
+  /* Save some info so we can later determine if we erroneously
+     created a DIE for something we had already created a DIE for.
+     We should always be reusing DIEs created early.  */
+  dw_die_ref early_die = NULL;
+  if (decl_die_table)
+    {
+      early_die = lookup_decl_die (decl);
+      if (early_die && !early_die->dumped_early)
+       early_die = NULL;
+    }
+#endif
+
   switch (TREE_CODE (decl))
     {
     case ERROR_MARK:
@@ -21144,6 +21173,11 @@ dwarf2out_decl (tree decl)
   dw_die_ref die = lookup_decl_die (decl);
   if (die)
     check_die (die, 0);
+#ifdef ENABLE_CHECKING
+  /* If we early created a DIE, make sure it didn't get re-created by
+     mistake.  */
+  gcc_assert (!early_die || early_die == die);
+#endif
   return die;
 }
 
index 6afa6f3b6963ac3e65993290a9f628b6e74f8edd..38e6f990e68576e0db7bdbdad23e74c958642df0 100644 (file)
@@ -4693,7 +4693,7 @@ gfc_emit_parameter_debug_info (gfc_symbol *sym)
                                              TREE_TYPE (decl),
                                              sym->attr.dimension,
                                              false, false);
-  debug_hooks->global_decl (decl);
+  debug_hooks->global_decl (decl, /*early=*/false);
 }
 
 
index 7566f4d3effae89f779644e559aabcc80ba13ee4..01f8410ccd7cdb1f3f76dc435ce2210691f8eec8 100644 (file)
@@ -496,9 +496,9 @@ go_function_decl (tree decl)
 /* A global variable decl.  */
 
 static void
-go_global_decl (tree decl)
+go_global_decl (tree decl, bool early)
 {
-  real_debug_hooks->global_decl (decl);
+  real_debug_hooks->global_decl (decl, early);
   go_decl (decl);
 }
 
index 9e8524acac2dbe267ff90168b129386d4d747cf7..1f39949c811ffad759f30bd3580c6ca30853d431 100644 (file)
@@ -1093,7 +1093,7 @@ lto_write_globals (void)
   varpool_node *vnode;
   FOR_EACH_DEFINED_VARIABLE (vnode)
     if (!decl_function_context (vnode->decl))
-      debug_hooks->global_decl (vnode->decl);
+      debug_hooks->global_decl (vnode->decl, /*early=*/false);
 }
 
 static tree
index 7b6f4573e05b6b036f7121f68182da841f0d3064..d81b184c415be14c240b619075f1c1a483fa3a66 100644 (file)
@@ -119,7 +119,7 @@ static void sdbout_begin_block              (unsigned int, unsigned int);
 static void sdbout_end_block           (unsigned int, unsigned int);
 static void sdbout_source_line         (unsigned int, const char *, int, bool);
 static void sdbout_end_epilogue                (unsigned int, const char *);
-static void sdbout_global_decl         (tree);
+static void sdbout_global_decl         (tree, bool);
 static void sdbout_begin_prologue      (unsigned int, const char *);
 static void sdbout_end_prologue                (unsigned int, const char *);
 static void sdbout_begin_function      (tree);
@@ -142,7 +142,6 @@ static void sdbout_field_types              (tree);
 static void sdbout_one_type            (tree);
 static void sdbout_parms               (tree);
 static void sdbout_reg_parms           (tree);
-static void sdbout_global_decl         (tree);
 
 /* Random macros describing parts of SDB data.  */
 
@@ -1422,7 +1421,7 @@ sdbout_reg_parms (tree parms)
    after compilation proper has finished.  */
 
 static void
-sdbout_global_decl (tree decl)
+sdbout_global_decl (tree decl, bool early ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (decl) == VAR_DECL
       && !DECL_EXTERNAL (decl)
index 492a7ef58e5234e9df90b71597f20a7d5177986a..ceefa1bf6e916c81af32aa3a3aa331cfb113efea 100644 (file)
@@ -532,7 +532,7 @@ emit_debug_global_declarations (tree *vec, int len)
 
   timevar_push (TV_SYMOUT);
   for (i = 0; i < len; i++)
-    debug_hooks->global_decl (vec[i]);
+    debug_hooks->global_decl (vec[i], /*early=*/false);
   timevar_pop (TV_SYMOUT);
 }
 
index afc8e3d9559dd328b414d851fe3defcca7fd1703..8e9876ef4ed61e1c538a726e901890376f8f8559 100644 (file)
@@ -5032,10 +5032,6 @@ free_lang_data_in_decl (tree decl)
 {
   gcc_assert (DECL_P (decl));
 
-  /* Early dumping of DECLs before we lose language data.  */
-  if (debug_info_level > DINFO_LEVEL_NONE)
-    dwarf2out_early_decl (decl);
-
   /* Give the FE a chance to remove its own data first.  */
   lang_hooks.free_lang_data (decl);
 
index 463a4182622a7aef0f8366b54b56dfff790df0da..2ad9e9b5c14ce33b3adc9df6cec61228e51c63ef 100644 (file)
@@ -163,7 +163,7 @@ static void vmsdbgout_begin_epilogue (unsigned int, const char *);
 static void vmsdbgout_end_epilogue (unsigned int, const char *);
 static void vmsdbgout_begin_function (tree);
 static void vmsdbgout_decl (tree);
-static void vmsdbgout_global_decl (tree);
+static void vmsdbgout_global_decl (tree, bool);
 static void vmsdbgout_type_decl (tree, int);
 static void vmsdbgout_abstract_function (tree);
 
@@ -1510,10 +1510,10 @@ vmsdbgout_decl (tree decl)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_global_decl (tree decl)
+vmsdbgout_global_decl (tree decl, bool early)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
-    (*dwarf2_debug_hooks.global_decl) (decl);
+    (*dwarf2_debug_hooks.global_decl) (decl, early);
 }
 
 /* Not implemented in VMS Debug.  */