@@ -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;
@@ -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)
@@ -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 *);
@@ -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))
@@ -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
@@ -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