+2004-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ * configure.ac: Check for COMDAT support. Robustify check for
+ SHF_MERGE support.
+ * configure: Regenerated.
+ * config.in: Likewise.
+ * langhooks-def.h (lhd_comdat_group): New function.
+ (LANG_HOOKS_COMDAT_GROUP): New macro.
+ (LANG_HOOKS_DECLS): Use it.
+ * langhooks.c (lhd_comdat_group): Define.
+ * langhooks.h (lang_hooks_for_decls): Add comdat_group.
+ * output.h (named_section_flags): Make it a macro.
+ (named_section_real): New function.
+ (default_no_named_section): Add decl parameter.
+ (default_elf_asm_named_section): Likewise.
+ (default_coff_asm_named_section): Likewise.
+ (default_pe_asm_named_section): Likewise.
+ * target.h (gcc_target): Adjust type of named_section.
+ * varasm.c (named_section_flags): Rename to named_section_real.
+ Add decl parameter.
+ (default_no_named_section): Add decl parameter.
+ (default_elf_asm_named_section): Use COMDAT, if available. Deal
+ with the case that ASM_COMMENT_START is "@".
+ (default_coff_asm_named_section): Add decl parameter.
+ (default_pe_asm_named_section): Likewise.
+ * config/alpha/alpha.c (vms_asm_named_section): Add decl
+ parameter.
+ (unicosmk_asm_named_section): Likewise.
+ * config/arm/arm.c (arm_elf_asm_named_section): Remove.
+ * config/arm/elf.h (TARGET_ASM_NAMED_SECTION): Likewise.
+ * config/c4x/c4x.c (c4x_asm_named_section): Add decl parameter.
+ * config/cris/cris-protos.h (cris_target_asm_named_section):
+ Likewise.
+ * config/cris/cris.c (cris_target_asm_named_section):
+ Likewise.
+ * config/darwin/darwin-protos.h (darwin_asm_named_section):
+ Likewise.
+ * config/darwin/darwin.c (darwin_asm_named_section): Likewise.
+ * config/h8300/h8300.c (h8300_asm_named_section): Likewise.
+ * config/i386/i386-protos.h (i386_pe_asm_named_section):
+ Likewise.
+ * config/i386/winnt.c (i386_pe_asm_named_section): Likewise.
+ * config/m68k/m68k.c (m68k_coff_asm_named_section): Likewise.
+ * config/mcore/mcore.c (mcore_asm_named_section): Likewise.
+ * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section):
+ Likewise.
+ * config/sparc/sparc.c (sparce_elf_asm_named_section): Likewise.
+ * cp/cp-lang.h (LANG_HOOKS_COMDAT_GROUP): Define.
+ * cp/cp-tree.h (cxx_comdat_group): Declare.
+ * cp/decl.c (cxx_comdat_group): New function.
+
2004-09-15 Jan Hubicka <jh@suse.cz>
* tree-ssa.c (verify_flow_sensitive_alias_info): Do not walk dead nodes.
/* Define if your assembler supports .balign and .p2align. */
#undef HAVE_GAS_BALIGN_AND_P2ALIGN
+/* Define 0/1 if your assembler supports COMDAT group. */
+#undef HAVE_GAS_COMDAT_GROUP
+
/* Define if your assembler uses the new HImode fild and fist notation. */
#undef HAVE_GAS_FILDS_FISTS
the section; 0 if the default should be used. */
static void
-vms_asm_named_section (const char *name, unsigned int flags)
+vms_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
fputc ('\n', asm_out_file);
fprintf (asm_out_file, ".section\t%s", name);
the section; 0 if the default should be used. */
static void
-unicosmk_asm_named_section (const char *name, unsigned int flags)
+unicosmk_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
const char *kind;
static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static void emit_constant_insn (rtx cond, rtx pattern);
-#ifdef OBJECT_FORMAT_ELF
-static void arm_elf_asm_named_section (const char *, unsigned int);
-#endif
#ifndef ARM_PE
static void arm_encode_section_info (tree, rtx, int);
#endif
}
#endif /* AOF_ASSEMBLER */
-#ifdef OBJECT_FORMAT_ELF
-/* Switch to an arbitrary section NAME with attributes as specified
- by FLAGS. ALIGN specifies any known alignment requirements for
- the section; 0 if the default should be used.
-
- Differs from the default elf version only in the prefix character
- used before the section type. */
-
-static void
-arm_elf_asm_named_section (const char *name, unsigned int flags)
-{
- char flagchars[10], *f = flagchars;
-
- if (! named_section_first_declaration (name))
- {
- fprintf (asm_out_file, "\t.section\t%s\n", name);
- return;
- }
-
- if (!(flags & SECTION_DEBUG))
- *f++ = 'a';
- if (flags & SECTION_WRITE)
- *f++ = 'w';
- if (flags & SECTION_CODE)
- *f++ = 'x';
- if (flags & SECTION_SMALL)
- *f++ = 's';
- if (flags & SECTION_MERGE)
- *f++ = 'M';
- if (flags & SECTION_STRINGS)
- *f++ = 'S';
- if (flags & SECTION_TLS)
- *f++ = 'T';
- *f = '\0';
-
- fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
-
- if (!(flags & SECTION_NOTYPE))
- {
- const char *type;
-
- if (flags & SECTION_BSS)
- type = "nobits";
- else
- type = "progbits";
-
- fprintf (asm_out_file, ",%%%s", type);
-
- if (flags & SECTION_ENTSIZE)
- fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
- }
-
- putc ('\n', asm_out_file);
-}
-#endif
-
#ifndef ARM_PE
/* Symbols in the text segment can be accessed without indirecting via the
constant pool; it may take an extra binary operation, but this is still
#define TARGET_ASM_FILE_START_APP_OFF true
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
\f
-#undef TARGET_ASM_NAMED_SECTION
-#define TARGET_ASM_NAMED_SECTION arm_elf_asm_named_section
-\f
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
#define NEED_PLT_RELOC flag_pic
static tree c4x_handle_fntype_attribute (tree *, tree, tree, int, bool *);
const struct attribute_spec c4x_attribute_table[];
static void c4x_insert_attributes (tree, tree *);
-static void c4x_asm_named_section (const char *, unsigned int);
+static void c4x_asm_named_section (const char *, unsigned int, tree);
static int c4x_adjust_cost (rtx, rtx, rtx, int);
static void c4x_globalize_label (FILE *, const char *);
static bool c4x_rtx_costs (rtx, int, int, int *);
}
static void
-c4x_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+c4x_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
{
fprintf (asm_out_file, "\t.sect\t\"%s\"\n", name);
}
extern int cris_symbol (rtx);
extern void cris_output_addr_const (FILE *, rtx);
extern int cris_cfun_uses_pic_table (void);
-extern void cris_target_asm_named_section (const char *, unsigned int);
#endif /* RTX_CODE */
+extern void cris_target_asm_named_section (const char *, unsigned int, tree);
extern int cris_return_address_on_stack (void);
We just dispatch to the functions for ELF and a.out. */
void
-cris_target_asm_named_section (const char *name, unsigned int flags)
+cris_target_asm_named_section (const char *name, unsigned int flags,
+ tree decl)
{
if (! TARGET_ELF)
- default_no_named_section (name, flags);
+ default_no_named_section (name, flags, decl);
else
- default_elf_asm_named_section (name, flags);
+ default_elf_asm_named_section (name, flags, decl);
}
/* The LEGITIMATE_PIC_OPERAND_P worker. */
unsigned HOST_WIDE_INT);
extern void darwin_unique_section (tree decl, int reloc);
-extern void darwin_asm_named_section (const char *, unsigned int);
+extern void darwin_asm_named_section (const char *, unsigned int, tree);
extern unsigned int darwin_section_type_flags (tree, const char *, int);
extern void darwin_non_lazy_pcrel (FILE *, rtx);
}
void
-darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+darwin_asm_named_section (const char *name,
+ unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
{
fprintf (asm_out_file, ".section %s\n", name);
}
static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *);
static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *);
#ifndef OBJECT_FORMAT_ELF
-static void h8300_asm_named_section (const char *, unsigned int);
+static void h8300_asm_named_section (const char *, unsigned int, tree);
#endif
static int h8300_and_costs (rtx);
static int h8300_shift_costs (rtx);
#ifndef OBJECT_FORMAT_ELF
static void
-h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl)
{
/* ??? Perhaps we should be using default_coff_asm_named_section. */
fprintf (asm_out_file, "\t.section %s\n", name);
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
-extern void i386_pe_asm_named_section (const char *, unsigned int);
+extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
extern int x86_field_alignment (tree, int);
#endif
}
void
-i386_pe_asm_named_section (const char *name, unsigned int flags)
+i386_pe_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
char flagchars[8], *f = flagchars;
static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT);
static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT);
#ifdef M68K_TARGET_COFF
-static void m68k_coff_asm_named_section (const char *, unsigned int);
+static void m68k_coff_asm_named_section (const char *, unsigned int, tree);
#endif /* M68K_TARGET_COFF */
static void m68k_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
/* Output assembly to switch to section NAME with attribute FLAGS. */
static void
-m68k_coff_asm_named_section (const char *name, unsigned int flags)
+m68k_coff_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
char flagchar;
static tree mcore_handle_naked_attribute (tree *, tree, tree, int, bool *);
#ifdef OBJECT_FORMAT_ELF
static void mcore_asm_named_section (const char *,
- unsigned int);
+ unsigned int, tree);
#endif
static void mcore_unique_section (tree, int);
static void mcore_encode_section_info (tree, rtx, int);
#ifdef OBJECT_FORMAT_ELF
static void
-mcore_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+mcore_asm_named_section (const char *name,
+ unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
{
fprintf (asm_out_file, "\t.section %s\n", name);
}
}
static void
-rs6000_xcoff_asm_named_section (const char *name, unsigned int flags)
+rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
int smclass;
static const char * const suffix[3] = { "PR", "RO", "RW" };
static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);
static void sparc_asm_function_epilogue (FILE *, HOST_WIDE_INT);
#ifdef OBJECT_FORMAT_ELF
-static void sparc_elf_asm_named_section (const char *, unsigned int);
+static void sparc_elf_asm_named_section (const char *, unsigned int, tree);
#endif
static int sparc_adjust_cost (rtx, rtx, rtx, int);
\f
#ifdef OBJECT_FORMAT_ELF
static void
-sparc_elf_asm_named_section (const char *name, unsigned int flags)
+sparc_elf_asm_named_section (const char *name, unsigned int flags,
+ tree decl)
{
if (flags & SECTION_MERGE)
{
/* entsize cannot be expressed in this section attributes
encoding style. */
- default_elf_asm_named_section (name, flags);
+ default_elf_asm_named_section (name, flags, decl);
return;
}
echo "$as_me:$LINENO: result: $gcc_cv_as_shf_merge" >&5
echo "${ECHO_T}$gcc_cv_as_shf_merge" >&6
+if test $gcc_cv_as_shf_merge = no; then
+ echo "$as_me:$LINENO: checking assembler for section merging support" >&5
+echo $ECHO_N "checking assembler for section merging support... $ECHO_C" >&6
+if test "${gcc_cv_as_shf_merge+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_shf_merge=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
+ then gcc_cv_as_shf_merge=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.section .rodata.str, "aMS", %progbits, 1' > conftest.s
+ if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_shf_merge=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_shf_merge" >&5
+echo "${ECHO_T}$gcc_cv_as_shf_merge" >&6
+
+fi
cat >>confdefs.h <<_ACEOF
#define HAVE_GAS_SHF_MERGE `if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`
_ACEOF
+echo "$as_me:$LINENO: checking assembler for COMDAT group support" >&5
+echo $ECHO_N "checking assembler for COMDAT group support... $ECHO_C" >&6
+if test "${gcc_cv_as_comdat_group+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_comdat_group=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+ then gcc_cv_as_comdat_group=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.section .text,"axG",@progbits,.foo,comdat' > conftest.s
+ if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_comdat_group=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_comdat_group" >&5
+echo "${ECHO_T}$gcc_cv_as_comdat_group" >&6
+
+if test $gcc_cv_as_comdat_group = yes; then
+ gcc_cv_as_comdat_group_percent=no
+else
+ echo "$as_me:$LINENO: checking assembler for COMDAT group support" >&5
+echo $ECHO_N "checking assembler for COMDAT group support... $ECHO_C" >&6
+if test "${gcc_cv_as_comdat_group_percent+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_comdat_group_percent=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+ then gcc_cv_as_comdat_group_percent=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.section .text,"axG",%progbits,.foo,comdat' > conftest.s
+ if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_comdat_group_percent=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_comdat_group_percent" >&5
+echo "${ECHO_T}$gcc_cv_as_comdat_group_percent" >&6
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_COMDAT_GROUP `if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+
# Thread-local storage - the check is heavily parametrized.
conftest_s=
tls_first_major=
gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
[elf,2,12,0], [--fatal-warnings],
[.section .rodata.str, "aMS", @progbits, 1])
+if test $gcc_cv_as_shf_merge = no; then
+ gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
+ [elf,2,12,0], [--fatal-warnings],
+ [.section .rodata.str, "aMS", %progbits, 1])
+fi
AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE,
[`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`],
[Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.])
+gcc_GAS_CHECK_FEATURE(COMDAT group support, gcc_cv_as_comdat_group,
+ [elf,2,15,91], [--fatal-warnings],
+ [.section .text,"axG",@progbits,.foo,comdat])
+if test $gcc_cv_as_comdat_group = yes; then
+ gcc_cv_as_comdat_group_percent=no
+else
+ gcc_GAS_CHECK_FEATURE(COMDAT group support, gcc_cv_as_comdat_group_percent,
+ [elf,2,15,91], [--fatal-warnings],
+ [.section .text,"axG",%progbits,.foo,comdat])
+fi
+AC_DEFINE_UNQUOTED(HAVE_GAS_COMDAT_GROUP,
+ [`if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`],
+[Define 0/1 if your assembler supports COMDAT group.])
+
# Thread-local storage - the check is heavily parametrized.
conftest_s=
tls_first_major=
+2004-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Define.
+ * cp-tree.h (cxx_comdat_group): Declare.
+ * decl.c (cxx_comdat_group): New function.
+
2004-09-15 Nathan Sidwell <nathan@codesourcery.com>
* search.c (get_pure_virtuals): Remove unused variables.
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing
+#undef LANG_HOOKS_COMDAT_GROUP
+#define LANG_HOOKS_COMDAT_GROUP cxx_comdat_group
#undef LANG_HOOKS_FUNCTION_INIT
#define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context
const char *libname, tree attrs);
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree);
+extern const char *cxx_comdat_group (tree);
extern bool cp_missing_noreturn_ok_p (tree);
extern void initialize_artificial_var (tree, tree);
return DECL_MAIN_P (decl);
}
+/* Return the COMDAT group into which DECL should be placed. */
+
+const char *
+cxx_comdat_group (tree decl)
+{
+ tree name;
+
+ /* Virtual tables, construction virtual tables, and virtual table
+ tables all go in a single COMDAT group, named after the primary
+ virtual table. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl))
+ name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl)));
+ /* For all other DECLs, the COMDAT group is the mangled name of the
+ declaration itself. */
+ else
+ name = DECL_ASSEMBLER_NAME (decl);
+
+ return IDENTIFIER_POINTER (name);
+}
+
#include "gt-cp-decl.h"
extern tree lhd_type_promotes_to (tree);
extern void lhd_register_builtin_type (tree, const char *);
extern bool lhd_decl_ok_for_sibcall (tree);
+extern const char *lhd_comdat_group (tree);
extern tree lhd_expr_size (tree);
extern bool lhd_decl_uninit (tree);
extern tree lhd_get_callee_fndecl (tree);
#define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
#define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
+#define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group
#define LANG_HOOKS_DECLS { \
LANG_HOOKS_GLOBAL_BINDINGS_P, \
LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
+ LANG_HOOKS_COMDAT_GROUP \
}
/* The whole thing. The structure is defined in langhooks.h. */
return true;
}
+/* Return the COMDAT group into which DECL should be placed. */
+
+const char *
+lhd_comdat_group (tree decl)
+{
+ return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+}
+
/* lang_hooks.decls.final_write_globals: perform final processing on
global variables. */
void
/* True if this decl may be called via a sibcall. */
bool (*ok_for_sibcall) (tree);
+
+ /* Return the COMDAT group into which this DECL should be placed.
+ It is known that the DECL belongs in *some* COMDAT group when
+ this hook is called. The return value will be used immediately,
+ but not explicitly deallocated, so implementations should not use
+ xmalloc to allocate the string returned. (Typically, the return
+ value will be the string already stored in an
+ IDENTIFIER_NODE.) */
+ const char * (*comdat_group) (tree);
};
/* Language-specific hooks. See langhooks-def.h for defaults. */
extern unsigned int get_named_section_flags (const char *);
extern bool set_named_section_flags (const char *, unsigned int);
-extern void named_section_flags (const char *, unsigned int);
+#define named_section_flags(NAME, FLAGS) \
+ named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE)
+extern void named_section_real (const char *, unsigned int, tree);
extern bool named_section_first_declaration (const char *);
extern unsigned int default_section_type_flags (tree, const char *, int);
extern unsigned int default_section_type_flags_1 (tree, const char *, int, int);
-extern void default_no_named_section (const char *, unsigned int);
-extern void default_elf_asm_named_section (const char *, unsigned int);
-extern void default_coff_asm_named_section (const char *, unsigned int);
-extern void default_pe_asm_named_section (const char *, unsigned int);
+extern void default_no_named_section (const char *, unsigned int, tree);
+extern void default_elf_asm_named_section (const char *, unsigned int, tree);
+extern void default_coff_asm_named_section (const char *, unsigned int, tree);
+extern void default_pe_asm_named_section (const char *, unsigned int, tree);
extern void default_stabs_asm_out_destructor (rtx, int);
extern void default_named_section_asm_out_destructor (rtx, int);
/* Output the assembler code for function exit. */
void (* function_epilogue) (FILE *, HOST_WIDE_INT);
- /* Switch to an arbitrary section NAME with attributes as
- specified by FLAGS. */
- void (* named_section) (const char *, unsigned int);
+ /* Tell assembler to change to section NAME with attributes FLAGS.
+ If DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with
+ which this section is associated. */
+ void (* named_section) (const char *name, unsigned int flags, tree decl);
/* Switch to the section that holds the exception table. */
void (* exception_section) (void);
return true;
}
-/* Tell assembler to change to section NAME with attributes FLAGS. */
+/* Tell assembler to change to section NAME with attributes FLAGS. If
+ DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with which
+ this section is associated. */
void
-named_section_flags (const char *name, unsigned int flags)
+named_section_real (const char *name, unsigned int flags, tree decl)
{
if (in_section != in_named || strcmp (name, in_named_name) != 0)
{
if (! set_named_section_flags (name, flags))
abort ();
- targetm.asm_out.named_section (name, flags);
+ targetm.asm_out.named_section (name, flags, decl);
if (flags & SECTION_FORGET)
in_section = no_section;
error ("%J%D causes a section type conflict", decl, decl);
}
- named_section_flags (name, flags);
+ named_section_real (name, flags, decl);
}
/* If required, set DECL_SECTION_NAME to a unique name. */
void
default_no_named_section (const char *name ATTRIBUTE_UNUSED,
- unsigned int flags ATTRIBUTE_UNUSED)
+ unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
{
/* Some object formats don't support named sections at all. The
front-end should already have flagged this as an error. */
}
void
-default_elf_asm_named_section (const char *name, unsigned int flags)
+default_elf_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
char flagchars[10], *f = flagchars;
- if (! named_section_first_declaration (name))
+ /* If we have already declared this section, we can use an
+ abbreviated form to switch back to it -- unless this section is
+ part of a COMDAT groups, in which case GAS requires the full
+ declaration every time. */
+ if (!(HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+ && ! named_section_first_declaration (name))
{
fprintf (asm_out_file, "\t.section\t%s\n", name);
return;
*f++ = 'S';
if (flags & SECTION_TLS)
*f++ = 'T';
+ if (HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+ *f++ = 'G';
*f = '\0';
fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
if (!(flags & SECTION_NOTYPE))
{
const char *type;
+ const char *format;
if (flags & SECTION_BSS)
type = "nobits";
else
type = "progbits";
- fprintf (asm_out_file, ",@%s", type);
+ format = ",@%s";
+#ifdef ASM_COMMENT_START
+ /* On platforms that use "@" as the assembly comment character,
+ use "%" instead. */
+ if (strcmp (ASM_COMMENT_START, "@") == 0)
+ format = ",%%%s";
+#endif
+ fprintf (asm_out_file, format, type);
if (flags & SECTION_ENTSIZE)
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
+ if (HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+ fprintf (asm_out_file, ",%s,comdat",
+ lang_hooks.decls.comdat_group (decl));
}
putc ('\n', asm_out_file);
}
void
-default_coff_asm_named_section (const char *name, unsigned int flags)
+default_coff_asm_named_section (const char *name, unsigned int flags,
+ tree decl ATTRIBUTE_UNUSED)
{
char flagchars[8], *f = flagchars;
}
void
-default_pe_asm_named_section (const char *name, unsigned int flags)
+default_pe_asm_named_section (const char *name, unsigned int flags,
+ tree decl)
{
- default_coff_asm_named_section (name, flags);
+ default_coff_asm_named_section (name, flags, decl);
if (flags & SECTION_LINKONCE)
{