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 <al...@redhat.com>
Date: Thu Apr 30 10:10:27 2015 -0700
Adjust non dwarf debugging backends for the debug-early infrastructure.
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. */