diff options
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index da9c2b73166..cc4317aa7b4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-dump.h" #include "intl.h" #include "gimple.h" +#include "pointer-set.h" extern cpp_reader *parse_in; @@ -3288,27 +3289,60 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) /* Java requires that we be able to reference a local address for a method, and not be confused by PLT entries. If hidden aliases are - supported, emit one for each java function that we've emitted. */ + supported, collect and return all the functions for which we should + emit a hidden alias. */ -static void -build_java_method_aliases (void) +static struct pointer_set_t * +collect_candidates_for_java_method_aliases (void) { struct cgraph_node *node; + struct pointer_set_t *candidates = NULL; #ifndef HAVE_GAS_HIDDEN - return; + return candidates; #endif for (node = cgraph_nodes; node ; node = node->next) { tree fndecl = node->decl; - if (TREE_ASM_WRITTEN (fndecl) - && DECL_CONTEXT (fndecl) + if (DECL_CONTEXT (fndecl) && TYPE_P (DECL_CONTEXT (fndecl)) && TYPE_FOR_JAVA (DECL_CONTEXT (fndecl)) && TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl)) { + if (candidates == NULL) + candidates = pointer_set_create (); + pointer_set_insert (candidates, fndecl); + } + } + + return candidates; +} + + +/* Java requires that we be able to reference a local address for a + method, and not be confused by PLT entries. If hidden aliases are + supported, emit one for each java function that we've emitted. + CANDIDATES is the set of FUNCTION_DECLs that were gathered + by collect_candidates_for_java_method_aliases. */ + +static void +build_java_method_aliases (struct pointer_set_t *candidates) +{ + struct cgraph_node *node; + +#ifndef HAVE_GAS_HIDDEN + return; +#endif + + for (node = cgraph_nodes; node ; node = node->next) + { + tree fndecl = node->decl; + + if (TREE_ASM_WRITTEN (fndecl) + && pointer_set_contains (candidates, fndecl)) + { /* Mangle the name in a predictable way; we need to reference this from a java compiled object file. */ tree oid, nid, alias; @@ -3379,6 +3413,7 @@ cp_write_global_declarations (void) unsigned ssdf_count = 0; int retries = 0; tree decl; + struct pointer_set_t *candidates; locus = input_location; at_eof = 1; @@ -3676,6 +3711,9 @@ cp_write_global_declarations (void) linkage now. */ pop_lang_context (); + /* Collect candidates for Java hidden aliases. */ + candidates = collect_candidates_for_java_method_aliases (); + cgraph_finalize_compilation_unit (); /* Now, issue warnings about static, but not defined, functions, @@ -3690,7 +3728,11 @@ cp_write_global_declarations (void) } /* Generate hidden aliases for Java. */ - build_java_method_aliases (); + if (candidates) + { + build_java_method_aliases (candidates); + pointer_set_destroy (candidates); + } finish_repo (); |