diff options
author | Matt Austern <austern@apple.com> | 2004-03-12 17:09:03 +0000 |
---|---|---|
committer | Matt Austern <austern@gcc.gnu.org> | 2004-03-12 17:09:03 +0000 |
commit | 4746cf844723522037d0f0688f2189edd706e7b7 (patch) | |
tree | caa8a2f6e25f2a2ca455a215f64f01003c8ba7c4 /gcc/cp | |
parent | cd33cf6e2f13de407e2e308f10f77b52dad6c3de (diff) | |
download | gcc-4746cf844723522037d0f0688f2189edd706e7b7.zip gcc-4746cf844723522037d0f0688f2189edd706e7b7.tar.gz gcc-4746cf844723522037d0f0688f2189edd706e7b7.tar.bz2 |
Enabled linkonce support for Darwin.
* target.h (struct gcc_target): New target hook, unwind_label.
* target-def.h (TARGET_ASM_EMIT_UNWIND_LABEL): New hook.
* output.h (default_emit_unwind_label): New function.
* default.h (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): New macro.
(TARGET_USES_WEAK_UNWIND_INFO): New target macro.
(TARGET_SUPPORTS_HIDDEN): New target macro.
* dwarf2out.c (struct dw_fde_struct): Add field for function decl
that corresponds to this FDE.
(FRAME_BEGIN_LABEL): Allow target to override default label.
(output_call_frame_info): If FDEs are linknonce, then use extra
indirection for FDE encoding, output a label for each FDE, and
output an empty label for each function without an FDE.
(dwarf2out_begin_prologue): Set up decl field when creating an FDE.
* varasm.c (globalize_decl): Call ASM_MAKE_LABEL_LINKONCE for
decls with DECL_ONE_ONLY set, if that macro is defined.
(make_decl_one_only): Don't use DECL_COMMON if we're compiling
for a SUPPORTS_ONE_ONLY target.
* config/darwin-protos.h (darwin_unique_section): Declare.
(darwin_asm_named_section): Likewise.
(darwin_section_type_flags): Likewise.
(darwin_non_lazy_pcrel): Likewise.
(darwin_emit_unwind_label): Likewise.
(darwin_make_decl_one_only): Likewise.
* config/darwin.c (machopic_finish): Get rid of tweak that
eliminate stubs for symbols that are defined.
(darwin_encode_section_info): Don't treat weak functions as defined.
(darwin_make_decl_one_only): Define.
(darwin_asm_named_section): Likewise.
(darwin_section_type_flags): Likewise.
(darwin_unique_section): Likewise.
(darwin_emit_unwind_label): Likewise.
(darwin_non_lazy_pcrel): Likewise.
(darwin_asm_output_dwarf_delta): Difference between two labels is
local only if both labels are local.
* config/darwin.h (MAKE_DECL_ONE_ONLY): Define.
(ASM_MAKE_LABEL_LINKONCE): Likewise.
(TARGET_SUPPORTS_HIDDEN): Likewise.
(TARGET_USES_WEAK_UNWIND_INFO): Likewise.
(TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): Likewise.
(FRAME_BEGIN_LABEL): Likewise.
(ASM_DECLARE_OBJECT_NAME): Make references to weak symbols indirect.
(ASM_DECLARE_FUNCTION_NAME): Likewise.
(darwin_eh_frame_section): Give __eh_frame section the coalesced flag.
(TARGET_ASM_UNIQUE_SECTION): Define.
(EH_FRAME_SECTION_NAME): Define.
(EH_FRAME_SECTION_ATTR): Likewise.
(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Likewise.
(TARGET_ASM_NAMED_SECTION): Likewise.
(TARGET_SECTION_TYPE_FLAGS): Likewise.
* doc/tm.texi: Document TARGET_USES_WEAK_UNWIND_INFO,
TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY, TARGET_SUPPORTS_HIDDEN,
TARGET_ASM_EMIT_UNWIND_LABEL.
* cp/decl2.c (maybe_make_one_only): Look at
TARGET_EXPLICIT_INSTANTIATION_ONE_ONLY when deciding whether
to make an explicit instantiation weak.
* cp/method.c (use_thunk): Make sure we call comdat_linkage
when appropriate.
* cp/pt.c (do_type_instantiation): On systems where weak symbols
don't go in a static archive's TOC, explicit instantiation of a
class must imply *explicit* instantiation of its memeber.
From-SVN: r79394
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 21 | ||||
-rw-r--r-- | gcc/cp/method.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 55 |
4 files changed, 68 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e543c5c..fc34864 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2004-03-12 Matt Austern <austern@apple.com> + + * decl2.c (maybe_make_one_only): Look at + TARGET_EXPLICIT_INSTANTIATION_ONE_ONLY when deciding whether + to make an explicit instantiation weak. + * method.c (use_thunk): Make sure we call comdat_linkage + when appropriate. + * pt.c (do_type_instantiation): On systems where weak symbols + don't go in a static archive's TOC, explicit instantiation of a + class must imply *explicit* instantiation of its memeber. + 2004-03-11 Kazu Hirata <kazu@cs.umass.edu> * call.c, cp-tree.h, pt.c: Fix comment typos. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 9d8043a..7310d09 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1399,7 +1399,9 @@ comdat_linkage (tree decl) /* For win32 we also want to put explicit instantiations in linkonce sections, so that they will be merged with implicit - instantiations; otherwise we get duplicate symbol errors. */ + instantiations; otherwise we get duplicate symbol errors. + For Darwin we do not want explicit instantiations to be + linkonce. */ void maybe_make_one_only (tree decl) @@ -1418,13 +1420,18 @@ maybe_make_one_only (tree decl) to for variables so that cp_finish_decl will update their linkage, because their DECL_INITIAL may not have been set properly yet. */ - make_decl_one_only (decl); - - if (TREE_CODE (decl) == VAR_DECL) + if (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY + || (! DECL_EXPLICIT_INSTANTIATION (decl) + && ! DECL_TEMPLATE_SPECIALIZATION (decl))) { - DECL_COMDAT (decl) = 1; - /* Mark it needed so we don't forget to emit it. */ - mark_referenced (DECL_ASSEMBLER_NAME (decl)); + make_decl_one_only (decl); + + if (TREE_CODE (decl) == VAR_DECL) + { + DECL_COMDAT (decl) = 1; + /* Mark it needed so we don't forget to emit it. */ + mark_referenced (DECL_ASSEMBLER_NAME (decl)); + } } } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index bb34d82..10dfaca 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -390,6 +390,8 @@ use_thunk (tree thunk_fndecl, bool emit_p) rewrite. */ TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function); DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function); + if (flag_weak && TREE_PUBLIC (thunk_fndecl)) + comdat_linkage (thunk_fndecl); if (flag_syntax_only) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c619dc6..45fa012 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10661,6 +10661,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) int extern_p = 0; int nomem_p = 0; int static_p = 0; + int previous_instantiation_extern_p = 0; if (TREE_CODE (t) == TYPE_DECL) t = TREE_TYPE (t); @@ -10722,11 +10723,16 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) No program shall explicitly instantiate any template more than once. - If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation - was `extern'. If EXTERN_P then the second is. If -frepo, chances - are we already got marked as an explicit instantiation because of the - repo file. All these cases are OK. */ - if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository + If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit + instantiation was `extern'. If EXTERN_P then the second is. + If -frepo, chances are we already got marked as an explicit + instantiation because of the repo file. All these cases are + OK. */ + + previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t); + + if (!previous_instantiation_extern_p && !extern_p + && !flag_use_repository && (complain & tf_error)) pedwarn ("duplicate explicit instantiation of `%#T'", t); @@ -10743,6 +10749,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) { tree tmp; + int explicitly_instantiate_members = 0; /* In contrast to implicit instantiation, where only the declarations, and not the definitions, of members are @@ -10761,26 +10768,46 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) *explicit* instantiations or not. We choose to be generous, and not set DECL_EXPLICIT_INSTANTIATION. Therefore, we allow the explicit instantiation of a class where some of the members - have no definition in the current translation unit. */ + have no definition in the current translation unit. Exception: + on some targets (e.g. Darwin), weak symbols do not get put in + a static archive's TOC. The problematic case is if we're doing + a non-extern explicit instantiation of an extern template: we + have to put member functions in the TOC in that case, or we'll + get unresolved symbols at link time. */ + + explicitly_instantiate_members = + TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY + && previous_instantiation_extern_p && ! extern_p + && ! TYPE_FOR_JAVA (t); if (! static_p) for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp, /*defer_ok=*/1); + if (explicitly_instantiate_members) + do_decl_instantiation (tmp, NULL_TREE); + else + { + mark_decl_instantiated (tmp, extern_p); + repo_template_instantiated (tmp, extern_p); + if (! extern_p) + instantiate_decl (tmp, /*defer_ok=*/1); + } } for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp, /*defer_ok=*/1); + if (explicitly_instantiate_members) + do_decl_instantiation (tmp, NULL_TREE); + else + { + mark_decl_instantiated (tmp, extern_p); + repo_template_instantiated (tmp, extern_p); + if (! extern_p) + instantiate_decl (tmp, /*defer_ok=*/1); + } } if (CLASSTYPE_NESTED_UTDS (t)) |