diff mbox

[debug-early] document new world and fix non-dwarf debugging backends

Message ID 554266CB.4040800@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez April 30, 2015, 5:30 p.m. UTC
This patch adjusts the non-dwarf debugging back-ends to work in the new 
world.

Particularly interesting is dbxout, which was generating specific debug 
information for constants not written to memory.  For example, the 
following in C++:

	const int invisible = 0xC0FFEE;

The new infrastructure never sees `invisible' because it doesn't make it 
to the symbol table, especially by the time late_global_decl runs.  What 
I did for this case was to handle it through the early_global_decl() 
hook, which does see `invisible', though it lacks location information. 
  However, since we don't need location information to represent this 
corner case, everything works fine and the pr23205-2.C stabs regression 
is fixed.

I have also updated the documentation for the hooks to reflect reality.

Committed to branch.

Down to 3 sets of individual regressions in the testsuite.  Yay.

Aldy
commit bb51ad83395536cc6efc151b6fe3f1fa0616d7a4
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Thu Apr 30 10:10:27 2015 -0700

    Adjust non dwarf debugging backends for the debug-early infrastructure.
diff mbox

Patch

diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 0c9a327..9f555c3 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -1346,24 +1346,65 @@  dbxout_function_decl (tree decl)
 
 #endif /* DBX_DEBUGGING_INFO  */
 
+/* Return true if a variable is really a constant and not written in
+   memory.  */
+
+static bool
+decl_is_really_constant (tree decl)
+{
+  return ((TREE_CODE (decl) == VAR_DECL
+	   || TREE_CODE (decl) == RESULT_DECL)
+	  && !DECL_EXTERNAL (decl)
+	  && TREE_STATIC (decl)
+	  && TREE_READONLY (decl)
+	  && DECL_INITIAL (decl) != 0
+	  && tree_fits_shwi_p (DECL_INITIAL (decl))
+	  && ! TREE_ASM_WRITTEN (decl)
+	  && (DECL_FILE_SCOPE_P (decl)
+	      || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK
+	      || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
+	  && TREE_PUBLIC (decl) == 0);
+}
+
+/* Wrapper for dbxout_symbol that temporarily sets TREE_USED on the
+   DECL.  */
+
+static void
+dbxout_symbol_used (tree decl)
+{
+  int saved_tree_used = TREE_USED (decl);
+  TREE_USED (decl) = 1;
+  dbxout_symbol (decl, 0);
+  TREE_USED (decl) = saved_tree_used;
+}
+
+/* Output early debug information for a global DECL.  Called from
+   rest_of_decl_compilation during parsing.  */
+
 static void
-dbxout_early_global_decl (tree decl ATTRIBUTE_UNUSED)
+dbxout_early_global_decl (tree decl)
 {
-  /* NYI for non-dwarf.  */
+  /* True constant values may not appear in the symbol table, so they
+     will be missed by the late_global_decl hook.  Handle these cases
+     now, since early_global_decl will get unoptimized symbols early
+     enough-- and besides, true constants don't need location
+     information, so it's ok to handle them earlier.  */
+  if (decl_is_really_constant (decl))
+    dbxout_symbol_used (decl);
 }
 
-/* Debug information for a global DECL.  Called from toplev.c after
-   compilation proper has finished.  */
+/* Output late debug information for a global DECL after location
+   information is available.  */
+
 static void
-dbxout_late_global_decl (tree decl)
+dbxout_late_global_decl (tree decl ATTRIBUTE_UNUSED)
 {
-  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
-    {
-      int saved_tree_used = TREE_USED (decl);
-      TREE_USED (decl) = 1;
-      dbxout_symbol (decl, 0);
-      TREE_USED (decl) = saved_tree_used;
-    }
+  if (TREE_CODE (decl) == VAR_DECL
+      && !DECL_EXTERNAL (decl)
+      /* Read-only constants were handled in
+	 dbxout_early_global_decl.  */
+      && !decl_is_really_constant (decl))
+    dbxout_symbol_used (decl);
 }
 
 /* This is just a function-type adapter; dbxout_symbol does exactly
@@ -2904,14 +2945,7 @@  dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
 	 and not written in memory, inform the debugger.
 
 	 ??? Why do we skip emitting the type and location in this case?  */
-      if (TREE_STATIC (decl) && TREE_READONLY (decl)
-	  && DECL_INITIAL (decl) != 0
-	  && tree_fits_shwi_p (DECL_INITIAL (decl))
-	  && ! TREE_ASM_WRITTEN (decl)
-	  && (DECL_FILE_SCOPE_P (decl)
-	      || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK
-	      || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
-	  && TREE_PUBLIC (decl) == 0)
+      if (decl_is_really_constant (decl))
 	{
 	  /* The sun4 assembler does not grok this.  */
 
diff --git a/gcc/debug.h b/gcc/debug.h
index 528ef3f..c360e5c 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -92,17 +92,37 @@  struct gcc_debug_hooks
   /* Debug information for a function DECL.  This might include the
      function name (a symbol), its parameters, and the block that
      makes up the function's body, and the local variables of the
-     function.  */
+     function.
+
+     This is only called for FUNCTION_DECLs.  It is part of the late
+     debug pass and is called from rest_of_handle_final.
+
+     Location information is available at this point.
+
+     See the documentation for early_global_decl and late_global_decl
+     for other entry points into the debugging back-ends for DECLs.  */
   void (* function_decl) (tree decl);
 
-  /* Debug information for a global DECL.  Called from the parser after
-     the parsing process has finished.  */
+  /* Debug information for a global DECL.  Called from the parser
+     after the parsing process has finished.
+
+     Location information is not available at this point, but it is a
+     good probe point to get access to symbols before they get
+     optimized away.
+
+     This hook may be called on VAR_DECLs or FUNCTION_DECLs.  It is up
+     to the hook to use what it needs.  */
   void (* early_global_decl) (tree decl);
 
   /* Augment debug information generated by early_global_decl with
      more complete debug info (if applicable).  Called from toplev.c
      after the compilation proper has finished and cgraph information
-     is available.  */
+     is available.
+
+     Location information is available at this point.
+
+     This hook may be called on VAR_DECLs or FUNCTION_DECLs.  It is up
+     to the hook to use what it needs.  */
   void (* late_global_decl) (tree decl);
 
   /* Debug information for a type DECL.  Called from toplev.c after
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index be9c82e..1226f5b 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -1432,17 +1432,20 @@  sdbout_reg_parms (tree parms)
       }
 }
 
+/* Output early debug information for a global DECL.  Called from
+   rest_of_decl_compilation during parsing.  */
+
 static void
 sdbout_early_global_decl (tree decl ATTRIBUTE_UNUSED)
 {
   /* NYI for non-dwarf.  */
 }
 
-/* Output debug information for a global DECL.  Called from toplev.c
-   after compilation proper has finished.  */
+/* Output late debug information for a global DECL after location
+   information is available.  */
 
 static void
-sdbout_late_global_decl (tree decl)
+sdbout_late_global_decl (tree decl ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (decl) == VAR_DECL
       && !DECL_EXTERNAL (decl)
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index e18c5c3..7d70c1f 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -200,7 +200,7 @@  const struct gcc_debug_hooks vmsdbg_debug_hooks
    vmsdbgout_end_epilogue,
    vmsdbgout_begin_function,
    vmsdbgout_end_function,
-   vmsdbgout_decl,
+   vmsdbgout_function_decl,
    vmsdbgout_early_global_decl,
    vmsdbgout_late_global_decl,
    vmsdbgout_type_decl,		  /* type_decl */
@@ -1515,7 +1515,7 @@  vmsdbgout_undef (unsigned int lineno, const char *buffer)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_decl (tree decl)
+vmsdbgout_function_decl (tree decl)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.function_decl) (decl);
@@ -1526,7 +1526,8 @@  vmsdbgout_decl (tree decl)
 static void
 vmsdbgout_early_global_decl (tree decl)
 {
-  /* NYI for non-dwarf.  */
+  if (write_symbols == VMS_AND_DWARF2_DEBUG)
+    (*dwarf2_debug_hooks.early_global_decl) (decl);
 }
 
 /* Not implemented in VMS Debug.  */