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
This commit is contained in:
Matt Austern 2004-03-12 17:09:03 +00:00 committed by Matt Austern
parent cd33cf6e2f
commit 4746cf8447
17 changed files with 463 additions and 51 deletions

View File

@ -1,3 +1,58 @@
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

View File

@ -71,12 +71,21 @@ extern void machopic_select_section (tree, int, unsigned HOST_WIDE_INT);
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);

View File

@ -1004,6 +1004,7 @@ darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
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)
@ -1123,6 +1124,20 @@ update_stubs (const char *name)
}
}
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)
@ -1289,6 +1304,103 @@ darwin_globalize_label (FILE *stream, const char *name)
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
@ -1325,8 +1437,8 @@ void
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);

View File

@ -319,6 +319,47 @@ do { text_section (); \
"\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
@ -370,10 +411,11 @@ do { text_section (); \
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)) \
@ -390,10 +432,11 @@ do { text_section (); \
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)) \
@ -646,7 +689,7 @@ SECTION_FUNCTION (darwin_exception_section, \
".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) \
@ -687,6 +730,10 @@ 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 { \
@ -814,6 +861,9 @@ enum machopic_addr_class {
#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) \
@ -823,8 +873,20 @@ enum machopic_addr_class {
#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); \

View File

@ -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.

View File

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

View File

@ -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)
{

View File

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

View File

@ -237,6 +237,18 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
#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 ""
@ -258,6 +270,24 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
# 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

View File

@ -3072,6 +3072,12 @@ for the abi and context in the @code{.unwabi} directive. If the
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
@ -6705,6 +6711,24 @@ commands that will make the symbol(s) associated with @var{decl} have
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
@ -7427,6 +7451,17 @@ If this macro is not defined, nothing special is output at the end of
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

View File

@ -243,6 +243,7 @@ typedef struct cfa_loc GTY(())
typedef struct dw_fde_struct GTY(())
{
tree decl;
const char *dw_fde_begin;
const char *dw_fde_current_label;
const char *dw_fde_end;
@ -391,7 +392,9 @@ static void def_cfa_1 (const char *, dw_cfa_location *);
#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"
@ -1942,6 +1945,22 @@ output_call_frame_info (int for_eh)
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
@ -1953,6 +1972,9 @@ output_call_frame_info (int for_eh)
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;
@ -2004,7 +2026,9 @@ output_call_frame_info (int for_eh)
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);
@ -2095,9 +2119,11 @@ output_call_frame_info (int for_eh)
/* 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);
@ -2113,9 +2139,16 @@ output_call_frame_info (int for_eh)
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");
@ -2248,6 +2281,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
/* 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;

View File

@ -514,6 +514,7 @@ extern const char *default_strip_name_encoding (const char *);
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);

View File

@ -57,6 +57,11 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#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
@ -189,6 +194,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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, \

View File

@ -74,6 +74,12 @@ struct gcc_target
/* 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);

View File

@ -4104,6 +4104,9 @@ globalize_decl (tree decl)
}
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);
@ -4228,16 +4231,16 @@ make_decl_one_only (tree decl)
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
@ -4917,6 +4920,16 @@ default_globalize_label (FILE * stream, const char *name)
}
#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. */

View File

@ -162,8 +162,8 @@ _ffi_call_AIX:
/* 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:
@ -173,19 +173,20 @@ 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

View File

@ -234,8 +234,8 @@ Lfinish:
/* 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:
@ -246,19 +246,20 @@ 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