This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Darwin] enable linkonce support


This patch enables linkonce support, a.k.a. vague linkage, a.k.a comdat, for Darwin. It fixes a bunch of test case failures from g++.dg and g++.old-deja. (init/init-ref4.C, parse/attr-ctor1.C, parse/constant4.C, template/non-dependent2.C, template/non-dependent3.C, g++.other/comdat3.C, g++.other/mangle3.C, g++.pt/static3.C, g++.pt/static6.C) It also fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11026.

Testing: bootstrapped (C, C++) on OS X 10.3. No regresions. (I didn't bootstrap Java because, as of yesterday when I did the testing, Java in the mainline compiler was broken.)

This is very similar to my previous patch. The main difference: I have taken out the new feature -fhidden-one-only. All of the discussion about the patch was about that feature. It's separable from the main work, so I'd like to get the main part in and working and then we can discuss whether or not -fhidden-one-only is a feature we want.

The explanation of the patch is pretty much the same as in the first version, but I'm reposting it here so people don't have to go back through the archives. As before, it's pretty easy to understand in terms of Darwin linker features.

Vague linkage on Darwin uses a feature called coalescing, which is sort of like ELF weak symbols and sort of like GNU linkonce sections except that it's not all that much like either of them. A coalesced symbol must be marked with the .weak_definition directive and must also appear in a section that is marked with the "coalesced" flag. These aren't like GNU linkonce sections because we have many symbols per coalesced section, not one section per symbol. All coalesced function definitions, for example, go in __TEXT,__textcoal_nt. References to coalesced symbols must be indirect, even if the compiler thinks it sees a definition of a coalesced symbol in the same translation unit as the use. Coalescing is only for defined symbols, and only applies to symbols with global or private extern scope.

The Darwin linker doesn't have a notion of subsections, so coalescing simply works at the level of things between one nonlocal symbol (a nonlocal symbol starts with something other than "L") and the next. A coalesced section must begin with a nonlocal symbol.

Exceptions are an annoying problem. Here's the problem scenerio: suppose an FDE in a .o refers to local symbols in a coalesced function from that same .o, and now suppose that particular copy of the coalesced function gets discarded by the linker. In that case, the dangling reference will cause the Darwin linker to die horribly. The solution we came up with, which Apple has been using in our locally modified compiler for two years, is to coalesce FDEs too. We give every FDE its own symbol (the name we choose is <foo>.eh, where <foo> is the assembler name of the function the FDE corresponds to), so that the FDEs too are coalesced. We make sure that a function and its FDE always have the same scope and visibility; the idea is that if the linker discards a coalesced function, it will also discard the corresponding coalesced FDE. There's one little subtlety involving implicit instantiations that have FDEs and explicit instantiations that don't, and we solve that by sometimes generating dummy FDE labels. This is admittedly a crude scheme; you can think of it as "poor man's group COMDAT". It's probably the best we can do given the Darwin linker, though, and Apple has shown that it can actually work.

To support all this exception machinery I put in a link from dw_fde_struct back to the associated decl (we'll need that for other targets, anyway, when and if we move to ELF group COMDAT), and I introduced a new target macro, ASM_OUTPUT_UNWIND_LABEL, to give FDEs their labels. Everywhere but Darwin, that macro does nothing.

A minor quirk of the Darwin linker that we have to accommodate: coalesced symbols can't be put in a static archive's table of contents. If the linker sees a static archive with duplicate TOC entries, it will give an unfriendly warning and then behave unpredictably. That's why (as you'll see if you look in the darwin.c section of my patch) the __TEXT,__textcoal_nt section is given the "no_toc" flag. OK, what's the consequence of this? Since you'll never find a coalesced symbol from the TOC, you have to make sure a symbol will only be marked as coalesced if it's something that can be regenerated in every translation unit where it's needed. There's exactly one obscure corner case where it matters: explicit instantiation of a class template that's marked as "extern". The question is whether explicit instantiation of a class template triggers explicit or implicit instantiation of its member functions. As it stands, the compiler does an implicit instantiation (with a note in the comments saying that the standard doesn't say which one it should do). My patch keeps that behavior in general, but makes it an explicit instantiation, thus something that will appear in the TOC, for Darwin in the special case where we're explicitly instantiating a previously extern template. I introduced a new target macro, TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY. to control whether explicit instantiations get marked linkonce just like implicit instantiations. On Darwin they shouldn't.

Here's the patch. OK to commit to mainline?

--Matt


Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.2767
diff -p -r2.2767 ChangeLog
*** gcc/ChangeLog 13 Feb 2004 04:55:32 -0000 2.2767
--- gcc/ChangeLog 13 Feb 2004 06:03:23 -0000
***************
*** 1,3 ****
--- 1,58 ----
+ 2004-02-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-02-12 Chris Demetriou <cgd@broadcom.com>


  	* config/mips/mips.md (casesi_internal, casesi_internal_di):
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.127
diff -p -r1.127 defaults.h
*** gcc/defaults.h	8 Feb 2004 02:13:28 -0000	1.127
--- gcc/defaults.h	13 Feb 2004 06:03:24 -0000
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 237,242 ****
--- 237,253 ----
  #endif
  #endif

+ /* Determines whether explicit template instantiations should
+ be given link-once semantics. */
+ #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 ""
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 257,262 ****
--- 268,291 ----
# define TARGET_ATTRIBUTE_WEAK
# 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.  */
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.494
diff -p -r1.494 dwarf2out.c
*** gcc/dwarf2out.c	12 Feb 2004 21:42:17 -0000	1.494
--- gcc/dwarf2out.c	13 Feb 2004 06:03:31 -0000
*************** typedef struct cfa_loc GTY(())
*** 243,248 ****
--- 243,249 ----

  typedef struct dw_fde_struct GTY(())
  {
+   tree decl;
    const char *dw_fde_begin;
    const char *dw_fde_current_label;
    const char *dw_fde_end;
*************** static void def_cfa_1 (const char *, dw_
*** 391,397 ****
--- 392,400 ----
  #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"
*************** output_call_frame_info (int for_eh)
*** 1942,1947 ****
--- 1945,1966 ----
    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
*************** output_call_frame_info (int for_eh)
*** 1953,1958 ****
--- 1972,1980 ----
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;
*************** output_call_frame_info (int for_eh)
*** 2004,2010 ****
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);
per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);


--- 2026,2034 ----
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */

! 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);


*************** output_call_frame_info (int for_eh)
*** 2095,2103 ****
--- 2119,2129 ----
/* 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);
*************** output_call_frame_info (int for_eh)
*** 2113,2121 ****


        if (for_eh)
  	{
! 	  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");
--- 2139,2154 ----

        if (for_eh)
  	{
! 	  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");
*************** dwarf2out_begin_prologue (unsigned int l
*** 2248,2253 ****
--- 2281,2287 ----

/* 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;
Index: gcc/output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.135
diff -p -r1.135 output.h
*** gcc/output.h 18 Jan 2004 22:37:27 -0000 1.135
--- gcc/output.h 13 Feb 2004 06:03:31 -0000
*************** extern const char *default_strip_name_en
*** 509,514 ****
--- 509,515 ----
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);
Index: gcc/target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.68
diff -p -r1.68 target-def.h
*** gcc/target-def.h 8 Feb 2004 23:08:33 -0000 1.68
--- gcc/target-def.h 13 Feb 2004 06:03:31 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 57,62 ****
--- 57,67 ----
#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
*************** Foundation, 59 Temple Place - Suite 330,
*** 189,194 ****
--- 194,200 ----
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, \
Index: gcc/target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.77
diff -p -r1.77 target.h
*** gcc/target.h 8 Feb 2004 02:13:28 -0000 1.77
--- gcc/target.h 13 Feb 2004 06:03:32 -0000
*************** struct gcc_target
*** 74,79 ****
--- 74,85 ----
/* 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);

Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.411
diff -p -r1.411 varasm.c
*** gcc/varasm.c	8 Feb 2004 02:09:58 -0000	1.411
--- gcc/varasm.c	13 Feb 2004 06:03:34 -0000
*************** globalize_decl (tree decl)
*** 4118,4123 ****
--- 4118,4126 ----
  	}
        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);
*************** make_decl_one_only (tree decl)
*** 4242,4257 ****

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)
{
#ifdef MAKE_DECL_ONE_ONLY
MAKE_DECL_ONE_ONLY (decl);
#endif
DECL_ONE_ONLY (decl) = 1;
}
else if (SUPPORTS_WEAK)
DECL_WEAK (decl) = 1;
else
--- 4245,4260 ----


TREE_PUBLIC (decl) = 1;

! 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
*************** default_globalize_label (FILE * stream,
*** 4935,4940 ****
--- 4938,4953 ----
putc ('\n', stream);
}
#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.  */
Index: gcc/config/darwin-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin-protos.h,v
retrieving revision 1.29
diff -p -r1.29 darwin-protos.h
*** gcc/config/darwin-protos.h	10 Nov 2003 23:07:09 -0000	1.29
--- gcc/config/darwin-protos.h	13 Feb 2004 06:03:35 -0000
*************** extern void machopic_select_section (tre
*** 73,83 ****
--- 73,92 ----
  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);
Index: gcc/config/darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.c,v
retrieving revision 1.57
diff -p -r1.57 darwin.c
*** gcc/config/darwin.c	7 Feb 2004 14:14:52 -0000	1.57
--- gcc/config/darwin.c	13 Feb 2004 06:03:36 -0000
*************** machopic_finish (FILE *asm_out_file)
*** 900,909 ****
        if (! TREE_USED (temp))
  	continue;

-       /* If the symbol is actually defined, we don't need a stub.  */
-       if (sym_name[0] == '!' && sym_name[1] == 'T')
- 	continue;
-
        sym_name = darwin_strip_name_encoding (sym_name);

sym = alloca (strlen (sym_name) + 2);
--- 900,905 ----
*************** darwin_encode_section_info (tree decl, r
*** 1008,1013 ****
--- 1004,1010 ----
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)
*************** update_stubs (const char *name)
*** 1159,1164 ****
--- 1156,1175 ----
}


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)
{
*************** darwin_globalize_label (FILE *stream, co
*** 1325,1330 ****
--- 1336,1438 ----
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
*************** void
*** 1361,1368 ****
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');


    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
--- 1469,1476 ----
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   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);
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.68
diff -p -r1.68 darwin.h
*** gcc/config/darwin.h	13 Feb 2004 01:58:37 -0000	1.68
--- gcc/config/darwin.h	13 Feb 2004 06:03:36 -0000
*************** do { text_section ();							\
*** 308,313 ****
--- 308,354 ----
  	      "\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
*************** do { text_section (); \
*** 359,368 ****
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 ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
--- 400,410 ----
const char *xname = NAME; \
if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
! 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)) \
*************** do { text_section (); \
*** 379,396 ****
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 ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
(* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
ASM_OUTPUT_LABEL (FILE, xname); \
- /* Avoid generating stubs for functions we've just defined by \
- outputting any required stub name label now. */ \
- machopic_output_possible_stub_label (FILE, xname); \
} while (0)


#define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE) \
--- 421,436 ----
const char *xname = NAME; \
if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
! 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)) \
(* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
ASM_OUTPUT_LABEL (FILE, xname); \
} while (0)


#define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE) \
*************** SECTION_FUNCTION (darwin_exception_secti
*** 638,644 ****
".section __DATA,__gcc_except_tab", 0) \
SECTION_FUNCTION (darwin_eh_frame_section, \
in_darwin_eh_frame, \
! ".section __TEXT,__eh_frame", 0) \
\
static void \
objc_section_init (void) \
--- 678,684 ----
".section __DATA,__gcc_except_tab", 0) \
SECTION_FUNCTION (darwin_eh_frame_section, \
in_darwin_eh_frame, \
! ".section " EH_FRAME_SECTION_NAME ",__eh_frame" EH_FRAME_SECTION_ATTR, 0) \
\
static void \
objc_section_init (void) \
*************** objc_section_init (void) \
*** 679,684 ****
--- 719,728 ----
#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 {								\
*************** enum machopic_addr_class {
*** 806,811 ****
--- 850,858 ----

#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) \
*************** enum machopic_addr_class {
*** 815,821 ****
--- 862,880 ----
  #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 {								\
Index: gcc/cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3950
diff -p -r1.3950 ChangeLog
*** gcc/cp/ChangeLog	12 Feb 2004 21:42:27 -0000	1.3950
--- gcc/cp/ChangeLog	13 Feb 2004 06:03:37 -0000
***************
*** 1,3 ****
--- 1,14 ----
+ 2004-02-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-02-12  Zack Weinberg  <zack@codesourcery.com>

  	* cp-lang.c: Don't define LANG_HOOKS_BUILTIN_TYPE_DECLS.
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.697
diff -p -r1.697 decl2.c
*** gcc/cp/decl2.c	26 Jan 2004 17:41:50 -0000	1.697
--- gcc/cp/decl2.c	13 Feb 2004 06:03:39 -0000
*************** comdat_linkage (tree decl)
*** 1406,1412 ****

  /* 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.  */

  void
  maybe_make_one_only (tree decl)
--- 1406,1414 ----

  /* 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.
!    For Darwin we do not want explicit instantiations to be
!    linkonce. */

void
maybe_make_one_only (tree decl)
*************** maybe_make_one_only (tree decl)
*** 1425,1437 ****
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)
      {
!       DECL_COMDAT (decl) = 1;
!       /* Mark it needed so we don't forget to emit it.  */
!       mark_referenced (DECL_ASSEMBLER_NAME (decl));
      }
  }

--- 1427,1444 ----
to for variables so that cp_finish_decl will update their linkage,
because their DECL_INITIAL may not have been set properly yet. */


!   if (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
!       || (! DECL_EXPLICIT_INSTANTIATION (decl)
! 	  && ! DECL_TEMPLATE_SPECIALIZATION (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));
! 	}
      }
  }

Index: gcc/cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.277
diff -p -r1.277 method.c
*** gcc/cp/method.c	4 Feb 2004 12:22:42 -0000	1.277
--- gcc/cp/method.c	13 Feb 2004 06:03:40 -0000
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 390,395 ****
--- 390,397 ----
       rewrite.  */
    TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
    DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
+   if (flag_weak)
+     comdat_linkage (thunk_fndecl);

    if (flag_syntax_only)
      {
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.828
diff -p -r1.828 pt.c
*** gcc/cp/pt.c	4 Feb 2004 18:35:17 -0000	1.828
--- gcc/cp/pt.c	13 Feb 2004 06:03:47 -0000
*************** do_type_instantiation (tree t, tree stor
*** 10635,10640 ****
--- 10635,10641 ----
    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);
*************** do_type_instantiation (tree t, tree stor
*** 10696,10706 ****
  	 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
&& (complain & tf_error))
pedwarn ("duplicate explicit instantiation of `%#T'", t);


--- 10697,10712 ----
  	 No program shall explicitly instantiate any template more
  	 than once.

!          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);

*************** do_type_instantiation (tree t, tree stor
*** 10717,10722 ****
--- 10723,10729 ----

    {
      tree tmp;
+     int explicitly_instantiate_members = 0;

      /* In contrast to implicit instantiation, where only the
         declarations, and not the definitions, of members are
*************** do_type_instantiation (tree t, tree stor
*** 10735,10760 ****
         *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.  */

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

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 (CLASSTYPE_NESTED_UTDS (t))
--- 10742,10787 ----
         *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.  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))
  	  {
! 	    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))
{
! 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))
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.297
diff -p -r1.297 tm.texi
*** gcc/doc/tm.texi	8 Feb 2004 23:08:48 -0000	1.297
--- gcc/doc/tm.texi	13 Feb 2004 06:04:04 -0000
*************** for the abi and context in the @code{.un
*** 3040,3045 ****
--- 3040,3051 ----
  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

*************** commands that will make the symbol(s) as
*** 6703,6708 ****
--- 6709,6731 ----
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}. Define this macro
+ if explicit and implicit template specialization should 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
*************** of the preceding label.
*** 7424,7429 ****
--- 7447,7463 ----
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
Index: libffi/src/powerpc/darwin.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin.S,v
retrieving revision 1.7
diff -p -r1.7 darwin.S
*** libffi/src/powerpc/darwin.S	21 Oct 2003 19:01:56 -0000	1.7
--- libffi/src/powerpc/darwin.S	13 Feb 2004 06:04:09 -0000
*************** _ffi_call_AIX:
*** 162,169 ****
  /* END(_ffi_call_AIX)  */

  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 162,169 ----
  /* END(_ffi_call_AIX)  */

  .data
! .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:
*************** LSCIE1:
*** 173,191 ****
  	.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	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  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	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
--- 173,192 ----
  	.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	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:
! 	.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
Index: libffi/src/powerpc/darwin_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin_closure.S,v
retrieving revision 1.6
diff -p -r1.6 darwin_closure.S
*** libffi/src/powerpc/darwin_closure.S	18 Sep 2003 19:35:46 -0000	1.6
--- libffi/src/powerpc/darwin_closure.S	13 Feb 2004 06:04:09 -0000
*************** Lfinish:
*** 234,241 ****
  /* END(ffi_closure_ASM)  */

  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 234,241 ----
  /* END(ffi_closure_ASM)  */

  .data
! .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:
*************** LSCIE1:
*** 246,264 ****
  	.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	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  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	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range
--- 246,265 ----
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.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_closure_ASM.eh
+ _ffi_closure_ASM.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length

  LASFDE1:
! 	.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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]