* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@79394
138bc75d-0d04-0410-961f-
82ee72b054a4
+2004-03-12 Matt Austern <austern@apple.com>
+
+ * 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.
+
2004-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (expand_builtin_mathfn): Add pow10* to the
extern void machopic_select_rtx_section (enum machine_mode, rtx,
unsigned HOST_WIDE_INT);
+extern void darwin_unique_section (tree decl, int reloc);
+extern void darwin_asm_named_section (const char *, unsigned int);
+extern unsigned int darwin_section_type_flags (tree, const char *, int);
+extern void darwin_non_lazy_pcrel (FILE *, rtx);
+
+extern void darwin_emit_unwind_label(FILE *, tree, int);
+
extern void darwin_pragma_ignore (struct cpp_reader *);
extern void darwin_pragma_options (struct cpp_reader *);
extern void darwin_pragma_unused (struct cpp_reader *);
extern void darwin_file_end (void);
+extern void darwin_make_decl_one_only (tree decl);
+
/* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o. */
extern void const_section (void);
extern void const_data_section (void);
if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !DECL_EXTERNAL (decl)
+ && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
&& ((TREE_STATIC (decl)
&& (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
|| (DECL_INITIAL (decl)
}
void
+darwin_make_decl_one_only (tree decl)
+{
+ static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
+ static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
+
+ const char *sec = TREE_CODE (decl) == FUNCTION_DECL
+ ? text_section
+ : data_section;
+ TREE_PUBLIC (decl) = 1;
+ DECL_ONE_ONLY (decl) = 1;
+ DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
+}
+
+void
machopic_select_section (tree exp, int reloc,
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
default_globalize_label (stream, name);
}
+void
+darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ fprintf (asm_out_file, ".section %s\n", name);
+}
+
+unsigned int
+darwin_section_type_flags (tree decl, const char *name, int reloc)
+{
+ unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+ /* Weak or linkonce variables live in a writable section. */
+ if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
+ && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
+ flags |= SECTION_WRITE;
+
+ return flags;
+}
+
+void
+darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
+{
+ /* Darwin does not use unique sections. However, the target's
+ unique_section hook is called for linkonce symbols. We need
+ to set an appropriate section for such symbols. */
+ if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
+ darwin_make_decl_one_only (decl);
+}
+
+/* Emit a label for an FDE, making it global and/or weak if appropriate.
+ The third parameter is nonzero if this is just a placeholder for an
+ FDE that we are omitting. */
+void
+darwin_emit_unwind_label(FILE *file, tree decl, int empty)
+{
+ tree id = DECL_ASSEMBLER_NAME (decl)
+ ? DECL_ASSEMBLER_NAME (decl)
+ : DECL_NAME (decl);
+
+ const char *prefix = "_";
+ const int prefix_len = 1;
+
+ const char *base = IDENTIFIER_POINTER (id);
+ unsigned int base_len = IDENTIFIER_LENGTH (id);
+
+ const char *suffix = ".eh";
+ unsigned int suffix_len = 3;
+
+ int need_quotes = name_needs_quotes (base);
+ int quotes_len = need_quotes ? 2 : 0;
+
+ char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
+ lab[0] = '\0';
+
+ if (need_quotes)
+ strcat(lab, "\"");
+ strcat(lab, prefix);
+ strcat(lab, base);
+ strcat(lab, suffix);
+ if (need_quotes)
+ strcat(lab, "\"");
+
+ if (TREE_PUBLIC (decl))
+ fprintf (file, "%s %s\n",
+ (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
+ ? ".globl"
+ : ".private_extern"),
+ lab);
+
+ if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
+ fprintf (file, ".weak_definition %s\n", lab);
+
+ if (empty)
+ fprintf (file, "%s = 0\n", lab);
+ else
+ fprintf (file, "%s:\n", lab);
+
+ free (lab);
+}
+
+/* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
+void
+darwin_non_lazy_pcrel (FILE *file, rtx addr)
+{
+ const char *str;
+ const char *nlp_name;
+
+ if (GET_CODE (addr) != SYMBOL_REF)
+ abort ();
+
+ str = darwin_strip_name_encoding (XSTR (addr, 0));
+ nlp_name = machopic_non_lazy_ptr_name (str);
+ fputs ("\t.long\t", file);
+ ASM_OUTPUT_LABELREF (file, nlp_name);
+ fputs ("-.", file);
+}
+
/* Emit an assembler directive to set visibility for a symbol. The
only supported visibilities are VISIBILITY_DEFAULT and
VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
const char *lab1, const char *lab2)
{
- const char *p = lab1 + (lab1[0] == '*');
- int islocaldiff = (p[0] == 'L');
+ int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
+ && lab2[0] == '*' && lab2[1] == 'L');
if (islocaldiff)
fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
"\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", "" , N_SO); \
} while (0)
+/* Making a symbols weak on Darwin requires more than just setting DECL_WEAK. */
+#define MAKE_DECL_ONE_ONLY(DECL) darwin_make_decl_one_only (DECL)
+
+/* Representation of linkonce symbols for the MACH-O assembler. Linkonce
+ symbols must be given a special section *and* must be preceded by a
+ special assembler directive. */
+#define ASM_MAKE_LABEL_LINKONCE(FILE, NAME) \
+ do { const char* _x = (NAME); if (!!strncmp (_x, "_OBJC_", 6)) { \
+ fputs (".weak_definition ", FILE); assemble_name (FILE, _x); \
+ fputs ("\n", FILE); }} while (0)
+
+/* We support hidden visibility */
+#undef TARGET_SUPPORTS_HIDDEN
+#define TARGET_SUPPORTS_HIDDEN 1
+
+/* The Darwin linker imposes two limitations on common symbols: they
+ can't have hidden visibility, and they can't appear in dylibs. As
+ a consequence, we should never use common symbols to represent
+ vague linkage. */
+#undef USE_COMMON_FOR_ONE_ONLY
+#define USE_COMMON_FOR_ONE_ONLY 0
+
+/* The Darwin linker doesn't like explicit template instantions to be
+ coalesced, because it doesn't want coalesced symbols to appear in
+ a static archive's table of contents. */
+#undef TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
+#define TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY 0
+
+/* We make exception information linkonce. */
+#undef TARGET_USES_WEAK_UNWIND_INFO
+#define TARGET_USES_WEAK_UNWIND_INFO 1
+
+/* We need to use a nonlocal label for the start of an EH frame: the
+ Darwin linker requires that a coalesced section start with a label. */
+#undef FRAME_BEGIN_LABEL
+#define FRAME_BEGIN_LABEL "EH_frame"
+
+/* Emit a label for the FDE corresponding to DECL. EMPTY means
+ emit a label for an empty FDE. */
+#define TARGET_ASM_EMIT_UNWIND_LABEL darwin_emit_unwind_label
+
/* Our profiling scheme doesn't LP labels and counter words. */
#define NO_PROFILE_COUNTERS 1
const char *xname = NAME; \
if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- machopic_define_name (xname); \
+ if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL)) \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ machopic_define_name (xname); \
if ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
const char *xname = NAME; \
if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- machopic_define_name (xname); \
+ if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL)) \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ machopic_define_name (xname); \
if ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
".section __DATA,__gcc_except_tab", 0) \
SECTION_FUNCTION (darwin_eh_frame_section, \
in_darwin_eh_frame, \
- ".section __TEXT,__eh_frame", 0) \
+ ".section " EH_FRAME_SECTION_NAME ",__eh_frame" EH_FRAME_SECTION_ATTR, 0) \
\
static void \
objc_section_init (void) \
#define TARGET_ASM_SELECT_SECTION machopic_select_section
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
+#undef TARGET_ASM_UNIQUE_SECTION
+#define TARGET_ASM_UNIQUE_SECTION darwin_unique_section
+
+
#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \
do { \
#define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
+#define EH_FRAME_SECTION_NAME "__TEXT"
+#define EH_FRAME_SECTION_ATTR ",coalesced,no_toc+strip_static_syms"
+
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(((CODE) == 2 && (GLOBAL) == 1) \
#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2) \
darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE) \
+ if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) { \
+ darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR); \
+ goto DONE; \
+ }
+
+
#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION darwin_asm_named_section
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS darwin_section_type_flags
+
#define DARWIN_REGISTER_TARGET_PRAGMAS() \
do { \
c_register_pragma (0, "mark", darwin_pragma_ignore); \
+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.
/* 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)
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));
+ }
}
}
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)
{
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);
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);
{
tree tmp;
+ int explicitly_instantiate_members = 0;
/* In contrast to implicit instantiation, where only the
declarations, and not the definitions, of members are
*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))
#endif
#endif
+/* Determines whether explicit template instantiations should
+ be given link-once semantics. The C++ ABI requires this
+ macro to be nonzero; see the documentation. */
+#ifndef TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
+# define TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY 1
+#endif
+
+/* This determines whether or not we need linkonce unwind information */
+#ifndef TARGET_USES_WEAK_UNWIND_INFO
+#define TARGET_USES_WEAK_UNWIND_INFO 0
+#endif
+
/* By default, there is no prefix on user-defined symbols. */
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
# endif
#endif
+/* This determines whether this target supports hidden visibility.
+ This is a weaker condition than HAVE_GAS_HIDDEN, which probes for
+ specific assembler syntax. */
+#ifndef TARGET_SUPPORTS_HIDDEN
+# ifdef HAVE_GAS_HIDDEN
+# define TARGET_SUPPORTS_HIDDEN 1
+# else
+# define TARGET_SUPPORTS_HIDDEN 0
+# endif
+#endif
+
+/* Determines whether we may use common symbols to represent one-only
+ semantics (a.k.a. "vague linkage"). */
+#ifndef USE_COMMON_FOR_ONE_ONLY
+# define USE_COMMON_FOR_ONE_ONLY 1
+#endif
+
+
/* If the target supports init_priority C++ attribute, give
SUPPORTS_INIT_PRIORITY a nonzero value. */
#ifndef SUPPORTS_INIT_PRIORITY
be updated in @var{fs}.
@end defmac
+@defmac TARGET_USES_WEAK_UNWIND_INFO
+A C expression that evaluates to true if the target requires unwind
+info to be given comdat linkage. Define it to be @code{1} if comdat
+linkage is necessary. The default is @code{0}.
+@end defmac
+
@node Stack Checking
@subsection Specifying How Stack Checking is Done
hidden, protected or internal visibility as specified by @var{visibility}.
@end deftypefn
+@defmac TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
+A C expression that evaluates to true if the target's linker expects
+explicit template specializations, as well as implicit, to be given
+linkonce semantics. The default is @code{1}. The C++ ABI requires
+this macro to be nonzero. Define this macro for targets where full
+C++ ABI compliance is impossible and where explicit and implicit
+template specialization must be treated differently.
+@end defmac
+
+@defmac TARGET_SUPPORTS_HIDDEN
+A C expression that evaluates to true if the target supports hidden
+visibility. By default this expression is true if and only if
+@code{HAS_GAS_HIDDEN} is defined. Set this macro if the
+@code{HAS_GAS_HIDDEN} macro gives the wrong answer for this
+target. (For example, if the target's mechanism for supporting
+hidden visibility is not the same as GAS's.)
+@end defmac
+
@defmac ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the name of an external
the jump-table.
@end defmac
+@deftypefn {Target Hook} void TARGET_ASM_EMIT_UNWIND_LABEL (@var{stream}, @var{decl}, @var{empty})
+This target hook emits a label at the beginning of each FDE. It
+should be defined on targets where FDEs need special labels, and it
+should write the appropriate label, for the FDE associated with the
+function declaration @var{decl}, to the stdio stream @var{stream}.
+The third argument, @var{empty}, is a boolean: true if this is a
+placeholder label for an omitted FDE.
+
+The default is that FDEs are not given nonlocal labels.
+@end deftypefn
+
@node Exception Region Output
@subsection Assembler Commands for Exception Regions
typedef struct dw_fde_struct GTY(())
{
+ tree decl;
const char *dw_fde_begin;
const char *dw_fde_current_label;
const char *dw_fde_end;
#define FUNC_END_LABEL "LFE"
#endif
+#ifndef FRAME_BEGIN_LABEL
#define FRAME_BEGIN_LABEL "Lframe"
+#endif
#define CIE_AFTER_SIZE_LABEL "LSCIE"
#define CIE_END_LABEL "LECIE"
#define FDE_LABEL "LSFDE"
if (fde_table_in_use == 0)
return;
+ /* If we make FDEs linkonce, we may have to emit an empty label for
+ an FDE that wouldn't otherwise be emitted. We want to avoid
+ having an FDE kept around when the function it refers to is
+ discarded. (Example where this matters: a primary function
+ template in C++ requires EH information, but an explicit
+ specialization doesn't. */
+ if (TARGET_USES_WEAK_UNWIND_INFO
+ && ! flag_asynchronous_unwind_tables
+ && for_eh)
+ for (i = 0; i < fde_table_in_use; i++)
+ if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls)
+ && !fde_table[i].uses_eh_lsda
+ && ! DECL_ONE_ONLY (fde_table[i].decl))
+ (*targetm.asm_out.unwind_label) (asm_out_file, fde_table[i].decl,
+ /* empty */ 1);
+
/* If we don't have any functions we'll want to unwind out of, don't
emit any EH unwind information. Note that if exceptions aren't
enabled, we won't have collected nothrow information, and if we
for (i = 0; i < fde_table_in_use; i++)
if (fde_table[i].uses_eh_lsda)
any_eh_needed = any_lsda_needed = true;
+ else if (TARGET_USES_WEAK_UNWIND_INFO
+ && DECL_ONE_ONLY (fde_table[i].decl))
+ any_eh_needed = 1;
else if (! fde_table[i].nothrow
&& ! fde_table[i].all_throwers_are_sibcalls)
any_eh_needed = true;
P Indicates the presence of an encoding + language
personality routine in the CIE augmentation. */
- fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
+ fde_encoding = TARGET_USES_WEAK_UNWIND_INFO
+ ? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1)
+ : ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
/* Don't emit EH unwind info for leaf functions that don't need it. */
if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions
&& (fde->nothrow || fde->all_throwers_are_sibcalls)
+ && (! TARGET_USES_WEAK_UNWIND_INFO || ! DECL_ONE_ONLY (fde->decl))
&& !fde->uses_eh_lsda)
continue;
+ (*targetm.asm_out.unwind_label) (asm_out_file, fde->decl, /* empty */ 0);
(*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
if (for_eh)
{
- dw2_asm_output_encoded_addr_rtx (fde_encoding,
- gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
- "FDE initial location");
+ if (TARGET_USES_WEAK_UNWIND_INFO
+ && DECL_ONE_ONLY (fde->decl))
+ dw2_asm_output_encoded_addr_rtx (fde_encoding,
+ gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (fde->decl))),
+ "FDE initial location");
+ else
+ dw2_asm_output_encoded_addr_rtx (fde_encoding,
+ gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
+ "FDE initial location");
dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
fde->dw_fde_end, fde->dw_fde_begin,
"FDE address range");
/* Add the new FDE at the end of the fde_table. */
fde = &fde_table[fde_table_in_use++];
+ fde->decl = current_function_decl;
fde->dw_fde_begin = xstrdup (label);
fde->dw_fde_current_label = NULL;
fde->dw_fde_end = NULL;
extern bool default_binds_local_p (tree);
extern bool default_binds_local_p_1 (tree, int);
extern void default_globalize_label (FILE *, const char *);
+extern void default_emit_unwind_label (FILE *, tree, int);
extern void default_internal_label (FILE *, const char *, unsigned long);
extern void default_file_start (void);
extern void file_end_indicate_exec_stack (void);
#ifndef TARGET_ASM_GLOBALIZE_LABEL
#define TARGET_ASM_GLOBALIZE_LABEL default_globalize_label
#endif
+
+#ifndef TARGET_ASM_EMIT_UNWIND_LABEL
+#define TARGET_ASM_EMIT_UNWIND_LABEL default_emit_unwind_label
+#endif
+
#ifndef TARGET_ASM_INTERNAL_LABEL
#define TARGET_ASM_INTERNAL_LABEL default_internal_label
#endif
TARGET_ASM_UNALIGNED_INT_OP, \
TARGET_ASM_INTEGER, \
TARGET_ASM_GLOBALIZE_LABEL, \
+ TARGET_ASM_EMIT_UNWIND_LABEL, \
TARGET_ASM_INTERNAL_LABEL, \
TARGET_ASM_ASSEMBLE_VISIBILITY, \
TARGET_ASM_FUNCTION_PROLOGUE, \
/* Output code that will globalize a label. */
void (* globalize_label) (FILE *, const char *);
+ /* Output code that will emit a label for unwind info, if this
+ target requires such labels. Second argument is the decl the
+ unwind info is associated with, third is is a boolean: true if
+ this is only a placeholder for an omitted FDE. */
+ void (* unwind_label ) (FILE *, tree, int);
+
/* Output an internal label. */
void (* internal_label) (FILE *, const char *, unsigned long);
}
return;
}
+#elif defined(ASM_MAKE_LABEL_LINKONCE)
+ if (DECL_ONE_ONLY (decl))
+ ASM_MAKE_LABEL_LINKONCE (asm_out_file, name);
#endif
(*targetm.asm_out.globalize_label) (asm_out_file, name);
TREE_PUBLIC (decl) = 1;
- if (TREE_CODE (decl) == VAR_DECL
- && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
- DECL_COMMON (decl) = 1;
- else if (SUPPORTS_ONE_ONLY)
+ if (SUPPORTS_ONE_ONLY)
{
#ifdef MAKE_DECL_ONE_ONLY
MAKE_DECL_ONE_ONLY (decl);
#endif
DECL_ONE_ONLY (decl) = 1;
}
+ else if (TREE_CODE (decl) == VAR_DECL
+ && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
+ DECL_COMMON (decl) = 1;
else if (SUPPORTS_WEAK)
DECL_WEAK (decl) = 1;
else
}
#endif /* GLOBAL_ASM_OP */
+/* Default function to output a label for unwind information. The
+ default is to do nothing. A target that needs nonlocal labels for
+ unwind information must provide its own function to do this. */
+void
+default_emit_unwind_label (FILE * stream ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED,
+ int empty ATTRIBUTE_UNUSED)
+{
+}
+
/* This is how to output an internal numbered label where PREFIX is
the class of label and LABELNO is the number within the class. */
/* END(_ffi_call_AIX) */
.data
-.section __TEXT,__eh_frame
-Lframe1:
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0 ; Length of Common Information Entry
LSCIE1:
.byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
.byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
.byte 0x41 ; CIE RA Column
- .byte 0x1 ; uleb128 0x1; Augmentation size
- .byte 0x10 ; FDE Encoding (pcrel)
+ .byte 0x1 ; uleb128 0x1; Augmentation size
+ .byte 0x90 ; FDE Encoding (indirect pcrel)
.byte 0xc ; DW_CFA_def_cfa
.byte 0x1 ; uleb128 0x1
.byte 0x0 ; uleb128 0x0
.align 2
LECIE1:
+.globl _ffi_call_DARWIN.eh
+_ffi_call_DARWIN.eh:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1 ; FDE Length
LASFDE1:
- .set L$set$2,LASFDE1-Lframe1
- .long L$set$2 ; FDE CIE offset
+ .long LASFDE1-EH_frame1 ; FDE CIE offset
.long LFB0-. ; FDE initial location
.set L$set$3,LFE1-LFB0
.long L$set$3 ; FDE address range
/* END(ffi_closure_ASM) */
.data
-.section __TEXT,__eh_frame
-Lframe1:
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0 ; Length of Common Information Entry
LSCIE1:
.byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
.byte 0x41 ; CIE RA Column
.byte 0x1 ; uleb128 0x1; Augmentation size
- .byte 0x10 ; FDE Encoding (pcrel)
+ .byte 0x90 ; FDE Encoding (indirect pcrel)
.byte 0xc ; DW_CFA_def_cfa
.byte 0x1 ; uleb128 0x1
.byte 0x0 ; uleb128 0x0
.align 2
LECIE1:
+.globl _ffi_closure_ASM.eh
+_ffi_closure_ASM.eh:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1 ; FDE Length
LASFDE1:
- .set L$set$2,LASFDE1-Lframe1
- .long L$set$2 ; FDE CIE offset
+ .long LASFDE1-EH_frame1 ; FDE CIE offset
.long LFB1-. ; FDE initial location
.set L$set$3,LFE1-LFB1
.long L$set$3 ; FDE address range