aboutsummaryrefslogtreecommitdiff
path: root/gcc/passes.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/passes.c')
-rw-r--r--gcc/passes.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/passes.c b/gcc/passes.c
index 1ba56bd..720e647 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -288,6 +288,56 @@ rest_of_decl_compilation (tree decl,
else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
&& TREE_STATIC (decl))
varpool_node::get_create (decl);
+
+ /* Generate early debug for global variables. Any local variables will
+ be handled by either handling reachable functions from
+ finalize_compilation_unit (and by consequence, locally scoped
+ symbols), or by rest_of_type_compilation below.
+
+ Also, pick up function prototypes, which will be mostly ignored
+ by the different early_global_decl() hooks, but will at least be
+ used by Go's hijack of the debug_hooks to implement
+ -fdump-go-spec. */
+ if (!in_lto_p
+ && (TREE_CODE (decl) != FUNCTION_DECL
+ /* This will pick up function prototypes with no bodies,
+ which are not visible in finalize_compilation_unit()
+ while iterating with FOR_EACH_*_FUNCTION through the
+ symbol table. */
+ || !DECL_SAVED_TREE (decl))
+
+ /* We need to check both decl_function_context and
+ current_function_decl here to make sure local extern
+ declarations end up with the correct context.
+
+ For local extern declarations, decl_function_context is
+ empty, but current_function_decl is set to the function where
+ the extern was declared . Without the check for
+ !current_function_decl below, the local extern ends up
+ incorrectly with a top-level context.
+
+ For example:
+
+ namespace S
+ {
+ int
+ f()
+ {
+ {
+ int i = 42;
+ {
+ extern int i; // Local extern declaration.
+ return i;
+ }
+ }
+ }
+ }
+ */
+ && !decl_function_context (decl)
+ && !current_function_decl
+
+ && !decl_type_context (decl))
+ (*debug_hooks->early_global_decl) (decl);
}
/* Called after finishing a record, union or enumeral type. */