configure.ac: Check for COMDAT support.
authorMark Mitchell <mark@codesourcery.com>
Wed, 15 Sep 2004 17:03:22 +0000 (17:03 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 15 Sep 2004 17:03:22 +0000 (17:03 +0000)
* 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/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-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Define.
* cp-tree.h (cxx_comdat_group): Declare.
* decl.c (cxx_comdat_group): New function.

From-SVN: r87557

29 files changed:
gcc/ChangeLog
gcc/config.in
gcc/config/alpha/alpha.c
gcc/config/arm/arm.c
gcc/config/arm/elf.h
gcc/config/c4x/c4x.c
gcc/config/cris/cris-protos.h
gcc/config/cris/cris.c
gcc/config/darwin-protos.h
gcc/config/darwin.c
gcc/config/h8300/h8300.c
gcc/config/i386/i386-protos.h
gcc/config/i386/winnt.c
gcc/config/m68k/m68k.c
gcc/config/mcore/mcore.c
gcc/config/rs6000/rs6000.c
gcc/config/sparc/sparc.c
gcc/configure
gcc/configure.ac
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.h
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/output.h
gcc/target.h
gcc/varasm.c

index c7210971c2e5d6c3b90f74cea63bfbbab99bb8af..e3505b1c2abc3b04a6e9f4c2ab3a668662570a8b 100644 (file)
@@ -1,3 +1,54 @@
+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.
index 64384e5c0084e94df4ecd5c83780c1f27510bf8e..1755c8a3721372aab4243c7916e1ee3b2086a966 100644 (file)
 /* 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
 
index 54d78f6c14393a55bac34850c04bcb44cff966c3..21aa38227973192913ca9bf58ff4ac0ec5238718 100644 (file)
@@ -8455,7 +8455,8 @@ vms_section_type_flags (tree decl, const char *name, int reloc)
    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);
@@ -8679,7 +8680,8 @@ unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
    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;
 
index e7ed0750519b3f3d1072c8fa3ba3caa4a0491c37..ee334dff1b2b655e63d1c7b5a060ab45b18372ab 100644 (file)
@@ -145,9 +145,6 @@ static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
 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
@@ -13771,62 +13768,6 @@ aof_file_end (void)
 }
 #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
index dae8acdfdf29f7120678e263a1df7e0a408b5d52..12759566ac4c52034848b6ed153569310e4e8d05 100644 (file)
 #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
index 5437568f07d413410f4366fc19716342f87ca514..2d6e66006eb95d88d3d2f1bc96d66725cff002ca 100644 (file)
@@ -195,7 +195,7 @@ static int c4x_label_ref_used_p (rtx, rtx);
 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 *);
@@ -4924,7 +4924,8 @@ c4x_init_libfuncs (void)
 }
 
 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);
 }
index 15e91df8a5999f2e2caa6a7a398e654301606bf1..f085e5d741b5830c002c632eb674988610734b93 100644 (file)
@@ -44,8 +44,8 @@ extern int cris_got_symbol (rtx);
 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);
 
index 468859f9f4241c887d695186ea00d3aa17704bf1..2021c711dca2e0e3128964a2c73ba0cf2449b133 100644 (file)
@@ -2450,12 +2450,13 @@ cris_reg_overlap_mentioned_p (rtx x, rtx in)
    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.  */
index a5ae08e24998a41196f026da996775a1980d74c1..402311c6bb129ab076efdb17a29b39f98a898ff6 100644 (file)
@@ -69,7 +69,7 @@ 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 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);
 
index 6bab55445bc01b9f2c3f212640d5d0220ea2c6ce..249ebab247bcbc224219e3f6a38cd9cdf544622d 100644 (file)
@@ -1187,7 +1187,9 @@ darwin_globalize_label (FILE *stream, const char *name)
 }
 
 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);
 }
index 6cec395483c77ca2c5ba584f9cd36155dac9cd25..564eecdfca27dd8e05a75ec2b22b9025b1a1e069 100644 (file)
@@ -114,7 +114,7 @@ static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 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);
@@ -5889,7 +5889,8 @@ h8300_reorg (void)
 
 #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);
index 1c87da6385d0499e4d1b477988200b4b77e63389..d663b0938a3c8ab6db808018e65b6a21eb42dc4b 100644 (file)
@@ -206,7 +206,7 @@ extern int ix86_constant_alignment (tree, int);
 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
 
index 7e32ca94257eee549edfff02a1894f110a7d6568..676a34af429b868989a30855c454a99aa4085e75 100644 (file)
@@ -622,7 +622,8 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
 }
 
 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;
 
index dd469c3a7df4a63c0d782ed91c46922e9a98b9e5..d85c7c60c0970c00c7459ecea6e5ecfa7cbf866f 100644 (file)
@@ -108,7 +108,7 @@ static const char *singlemove_string (rtx *);
 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);
@@ -3324,7 +3324,8 @@ output_xorsi3 (rtx *operands)
 /* 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;
 
index d121848209a519828c4ad5b73eac045c0e26b354..bdcbde99de57632fc1661f40ba271e46fb2088fa 100644 (file)
@@ -138,7 +138,7 @@ const struct attribute_spec mcore_attribute_table[];
 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);
@@ -3424,7 +3424,9 @@ mcore_naked_function_p (void)
 
 #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);
 }
index b47ccf0857572c18bde1c6066c7a25ed1e3f809e..322a7863a4898b18b45e3f443193c2f1f0a0c563 100644 (file)
@@ -16932,7 +16932,8 @@ rs6000_xcoff_asm_globalize_label (FILE *stream, const char *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" };
index dd441bac34235aef2674488161cbe7793043c840..63d3f01cdca159526372f8f92156f00d7ffba117 100644 (file)
@@ -304,7 +304,7 @@ static void emit_restore_regs (void);
 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);
@@ -8060,13 +8060,14 @@ sparc_profile_hook (int labelno)
 \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;
     }
 
index f5d20bfd1d52913d722a1f162bfd326506740dea..8a20fd34a8a0fb97a92900c7fff46917e883a1bb 100755 (executable)
 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=
index 94887f6bced3a37a1af9da019f43a255ec700d2e..1ae739e7af2206ed9e7032784d927fe985eb3bd1 100644 (file)
@@ -2218,10 +2218,29 @@ fi
 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=
index f886a1e022721b3c0b52416397fe430507d3b3b2..2be37070e5f19687a5acf8af16c77ebc214b9f4f 100644 (file)
@@ -1,3 +1,9 @@
+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.
index 1599080e896f9269ad976a9c92fc004c4138b3a3..a6ab3832a8fa8fb35b943f9fe425e373ef3a54f3 100644 (file)
@@ -92,6 +92,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 #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
index 5d788af0d1bb9df8873a68acbb4f64d6af78df76..22ac16589a4a9f3e30354f112df6b5fc9b15f4d8 100644 (file)
@@ -3789,6 +3789,7 @@ extern tree builtin_function (const char *name, tree type,
                              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);
 
index 6128598f8b800c185df7ac27c6ca5721b01aa712..e56023bbce6c72a1af6fb1372faf277ad6389956 100644 (file)
@@ -10883,4 +10883,24 @@ cp_missing_noreturn_ok_p (tree decl)
   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"
index 087fe419dae8389083a84b291966aeb910febb21..8b57a0311ab0ea25ca63bd328c4f6146b61cc11a 100644 (file)
@@ -65,6 +65,7 @@ extern void lhd_incomplete_type_error (tree, tree);
 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);
@@ -234,6 +235,7 @@ extern tree lhd_make_node (enum tree_code);
 #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, \
@@ -244,6 +246,7 @@ extern tree lhd_make_node (enum tree_code);
   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.  */
index 309bef57794fbefa3bf22e319e1f1678aea3144e..b1fd5b4df2c44cb073832e31b0088c40269b5559 100644 (file)
@@ -456,6 +456,14 @@ lhd_decl_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED)
   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
index 98532521e5e7a3c9ce893823f63ae4ee4add80a5..1b2dae10564492ebcfdd207de8388365ddeae870 100644 (file)
@@ -183,6 +183,15 @@ struct lang_hooks_for_decls
 
   /* 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.  */
index 1e1d1defa312933c0129c68eda3c2d116c568fcc..989a8dc174ea7c6a257e5efff22d850ef208ae03 100644 (file)
@@ -478,15 +478,17 @@ extern void no_asm_to_stream (FILE *);
 
 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);
index acb1814bcc3efc991c5ff0e455861a22e60ef821..a6d69e1938ea123dcc4186622b228e3569d4edf7 100644 (file)
@@ -107,9 +107,10 @@ struct gcc_target
     /* 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);
index 1561dc7b7816899f9e609a1f5ce5c40c8fed79c6..e3b53da45f3ed742a651b3d4ecd195b757e68a3e 100644 (file)
@@ -417,17 +417,19 @@ set_named_section_flags (const char *section, unsigned int flags)
   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;
@@ -478,7 +480,7 @@ named_section (tree decl, const char *name, int reloc)
        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.  */
@@ -4582,7 +4584,8 @@ default_section_type_flags_1 (tree decl, const char *name, int reloc,
 
 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.  */
@@ -4590,11 +4593,17 @@ default_no_named_section (const char *name ATTRIBUTE_UNUSED,
 }
 
 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;
@@ -4614,6 +4623,8 @@ default_elf_asm_named_section (const char *name, unsigned int flags)
     *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);
@@ -4621,23 +4632,35 @@ default_elf_asm_named_section (const char *name, unsigned int flags)
   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;
 
@@ -4651,9 +4674,10 @@ default_coff_asm_named_section (const char *name, unsigned int flags)
 }
 
 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)
     {