aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMatt Austern <austern@apple.com>2004-03-12 17:09:03 +0000
committerMatt Austern <austern@gcc.gnu.org>2004-03-12 17:09:03 +0000
commit4746cf844723522037d0f0688f2189edd706e7b7 (patch)
treecaa8a2f6e25f2a2ca455a215f64f01003c8ba7c4 /gcc/cp
parentcd33cf6e2f13de407e2e308f10f77b52dad6c3de (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/decl2.c21
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/pt.c55
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))