diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c index b9780258549076c64c9679b1dcacbfd057f9eb17..ea4cd13d0bf6463eb2be145c3548b5d2462b8814 100644 --- a/gcc/config/i386/winnt-d.c +++ b/gcc/config/i386/winnt-d.c @@ -78,4 +78,9 @@ winnt_d_register_target_info (void) #undef TARGET_D_MINFO_END_NAME #define TARGET_D_MINFO_END_NAME "__stop_minfo" +/* Define TARGET_D_TEMPLATES_ALWAYS_COMDAT for Windows targets. */ + +#undef TARGET_D_TEMPLATES_ALWAYS_COMDAT +#define TARGET_D_TEMPLATES_ALWAYS_COMDAT true + struct gcc_targetdm targetdm = TARGETDM_INITIALIZER; diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def index aa6bf55e6e691b45dc510f3ea5383479e8f920fe..67647515cf274975e788e9110ec58f126b47096e 100644 --- a/gcc/d/d-target.def +++ b/gcc/d/d-target.def @@ -104,5 +104,13 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with\n\ bool, (unsigned int *link_system, unsigned int *link_windows), hook_bool_uintp_uintp_false) +/* True if instantiations are always COMDAT if they have external linkage. */ +DEFHOOKPOD +(d_templates_always_comdat, + "This flag is true if instantiated functions and variables are always COMDAT\n\ +if they have external linkage. If this flag is false, then instantiated\n\ +decls will be emitted as weak symbols. The default is @code{false}.", + bool, false) + /* Close the 'struct gcc_targetdm' definition. */ HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index c1b6f27514936d5aa0ca016df54f4d014325ae15..bb731a60541dbd92e16019abbc32d1e38072e0d0 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -631,7 +631,6 @@ extern void d_finish_decl (tree); extern tree make_thunk (FuncDeclaration *, int); extern tree start_function (FuncDeclaration *); extern void finish_function (tree); -extern void mark_needed (tree); extern tree get_vtable_decl (ClassDeclaration *); extern tree build_new_class_expr (ClassReferenceExp *); extern tree aggregate_initializer_decl (AggregateDeclaration *); diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 8948e40e9027e8fb010d10c32ebfdafa49881474..7d1378255bd7b92b282ee49c80a3f81ef210d0cd 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "symtab-thunks.h" #include "d-tree.h" +#include "d-target.h" /* Return identifier for the external mangled name of DECL. */ @@ -1960,8 +1961,8 @@ finish_function (tree old_context) /* Mark DECL, which is a VAR_DECL or FUNCTION_DECL as a symbol that must be emitted in this, output module. */ -void -mark_needed (tree decl) +static void +d_mark_needed (tree decl) { TREE_USED (decl) = 1; @@ -2380,6 +2381,18 @@ set_linkage_for_decl (tree decl) if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) return d_comdat_linkage (decl); + /* If all instantiations must go in COMDAT, give them that linkage. + This also applies to other extern declarations, so that it is possible + for them to override template declarations. */ + if (targetdm.d_templates_always_comdat) + { + /* Make sure that instantiations are not removed. */ + if (flag_weak_templates && DECL_INSTANTIATED (decl)) + d_mark_needed (decl); + + return d_comdat_linkage (decl); + } + /* Instantiated variables and functions need to be overridable by any other symbol with the same name, so give them weak linkage. */ if (DECL_INSTANTIATED (decl)) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 97c8eebcd6f71ce6bae33407a35699d16a612c02..823f85ba9abbaf360b5964e9294801eb72ccf689 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10850,6 +10850,12 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with @code{extern(Windows)} linkage. @end deftypefn +@deftypevr {D Target Hook} bool TARGET_D_TEMPLATES_ALWAYS_COMDAT +This flag is true if instantiated functions and variables are always COMDAT +if they have external linkage. If this flag is false, then instantiated +decls will be emitted as weak symbols. The default is @code{false}. +@end deftypevr + @node Named Address Spaces @section Adding support for named address spaces @cindex named address spaces diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index e2d49ee9f5788dd0dfce1147a63b615f2788eabd..2321a5fc4e02562b6a55e6f3f1afa2e3aee3f4e8 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7369,6 +7369,8 @@ floating-point support; they are not included in this mechanism. @hook TARGET_D_HAS_STDCALL_CONVENTION +@hook TARGET_D_TEMPLATES_ALWAYS_COMDAT + @node Named Address Spaces @section Adding support for named address spaces @cindex named address spaces