On Tue, Jun 5, 2012 at 8:55 PM, Iain Sandoe <i...@codesourcery.com> wrote: > I would welcome a simple solution if one is available, although I don't quite > see what you have in mind at present.
This is what I have in mind. Untested, but it shows the idea. What do you think of this? Ciao! Steven
gcc/ * config/darwin.h (ASM_OUTPUT_LABELREF): Remove special case for .objc_class_name_*. (ASM_DECLARE_UNRESOLVED_REFERENCE): Remove. (ASM_DECLARE_CLASS_REFERENCE): Remove. * config/darwin-protos.h (darwin_declare_unresolved_reference, darwin_declare_class_reference): New prototypes. * config/darwin.c: Include cgraph.h for add_asm_node. (darwin_declare_unresolved_reference): New function. (darwin_declare_class_reference): New function. objc/ * objc-next-runtime-abi-01.c: Do not include output.h. (handle_next_class_ref): Use darwin_declare_unresolved_reference directly if it is defined, i.e. we're compiling for darwin. (handle_next_impent): Use darwin_declare_class_reference directly if it is defined. (objc_generate_v1_next_metadata): Remove confusing comment. Index: config/darwin.h =================================================================== --- config/darwin.h (revision 188246) +++ config/darwin.h (working copy) @@ -616,8 +616,6 @@ int darwin_label_is_anonymous_local_objc fprintf (FILE, "\"%s\"", xname); \ else if (darwin_label_is_anonymous_local_objc_name (xname)) \ fprintf (FILE, "L%s", xname); \ - else if (!strncmp (xname, ".objc_class_name_", 17)) \ - fprintf (FILE, "%s", xname); \ else if (xname[0] != '"' && name_needs_quotes (xname)) \ asm_fprintf (FILE, "\"%U%s\"", xname); \ else \ @@ -700,29 +698,6 @@ extern GTY(()) section * darwin_sections #undef TARGET_ASM_RELOC_RW_MASK #define TARGET_ASM_RELOC_RW_MASK machopic_reloc_rw_mask - -#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \ - do { \ - if (FILE) { \ - if (MACHOPIC_INDIRECT) \ - fprintf (FILE, "\t.lazy_reference "); \ - else \ - fprintf (FILE, "\t.reference "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - } while (0) - -#define ASM_DECLARE_CLASS_REFERENCE(FILE,NAME) \ - do { \ - if (FILE) { \ - fprintf (FILE, "\t"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "=0\n"); \ - (*targetm.asm_out.globalize_label) (FILE, NAME); \ - } \ - } while (0) - /* Globalizing directive for a label. */ #define GLOBAL_ASM_OP "\t.globl " #define TARGET_ASM_GLOBALIZE_LABEL darwin_globalize_label Index: config/darwin-protos.h =================================================================== --- config/darwin-protos.h (revision 188246) +++ config/darwin-protos.h (working copy) @@ -73,6 +73,9 @@ extern void darwin_pragma_options (struc extern void darwin_pragma_unused (struct cpp_reader *); extern void darwin_pragma_ms_struct (struct cpp_reader *); +extern void darwin_declare_unresolved_reference (const char *); +extern void darwin_declare_class_reference (const char *); + extern void darwin_file_start (void); extern void darwin_file_end (void); Index: config/darwin.c =================================================================== --- config/darwin.c (revision 188246) +++ config/darwin.c (working copy) @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. #include "debug.h" #include "obstack.h" #include "lto-streamer.h" +#include "cgraph.h" /* Darwin supports a feature called fix-and-continue, which is used for rapid turn around debugging. When code is compiled with the @@ -3511,4 +3512,42 @@ darwin_function_switched_text_sections ( fputs (":\n", fp); } +/* Support routines to dump the class references for NeXT ABI v1, aka + 32-bits ObjC-2.0, as top-level asms. + The following two functions should only be called from + objc/objc-next-runtime-abi-01.c. */ + +void +darwin_declare_unresolved_reference (const char *name) +{ + const char lazy_reference = "\t.lazy_reference "; + const char hard_reference = "\t.reference "; + const char reference = MACHOPIC_INDIRECT ? lazy_reference : hard_reference; + size_t len = strlen (reference) + strlen(name) + 2; + char *buf = (char *) alloca (len); + + gcc_assert (!strncmp (name, ".objc_class_name_", 17)); + + snprintf (buf, len, "%s%s\n", reference, name); + add_asm_node (build_string (strlen (buf), buf)); +} + +void +darwin_declare_class_reference (const char *name) +{ + const char *xname = targetm.strip_name_encoding (name); + size_t len = strlen (xname) + strlen (GLOBAL_ASM_OP) + 5; + char *buf = (char *) alloca (len); + + gcc_assert (!strncmp (name, ".objc_class_name_", 17) + || !strncmp (name, "*.objc_category_name_", 21)); + + snprintf (buf, len, "\t%s=0\n", xname); + add_asm_node (build_string (strlen (buf), buf)); + + /* Mimic default_globalize_label. */ + snprintf (buf, len, "%s%s\n", GLOBAL_ASM_OP, xname); + add_asm_node (build_string (strlen (buf), buf)); +} + #include "gt-darwin.h" Index: objc/objc-next-runtime-abi-01.c =================================================================== --- objc/objc-next-runtime-abi-01.c (revision 188246) +++ objc/objc-next-runtime-abi-01.c (working copy) @@ -49,7 +49,6 @@ along with GCC; see the file COPYING3. #include "ggc.h" #include "target.h" -#include "output.h" /* for asm_out_file */ #include "tree-iterator.h" #include "objc-runtime-hooks.h" @@ -2267,25 +2266,33 @@ generate_objc_symtab_decl (void) init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); } +/* Dump the class references. We force the appropriate classes to be + linked into the executable image, preserving unix archive semantics, + by emitting the references explicitly. We do this via top-level + asms instead of writing to asm_out_file because that would break + LTO, and a front end isn't supposed to write to asm_out_file anyway. + We call directly into a pair of special routines in darwin-c.c to + emit the references. It's a bit of a hack... + OK, it's a gross hack. + But it's for 32-bits Darwin only, and it works, so who cares. */ static void -handle_next_class_ref (tree chain) +handle_next_class_ref (tree chain ATTRIBUTE_UNUSED) { +#ifdef darwin_declare_unresolved_reference const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); char *string = (char *) alloca (strlen (name) + 30); - sprintf (string, ".objc_class_name_%s", name); - -#ifdef ASM_DECLARE_UNRESOLVED_REFERENCE - ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string); + darwin_declare_unresolved_reference (string); #else return ; /* NULL build for targets other than Darwin. */ #endif } static void -handle_next_impent (struct imp_entry *impent) +handle_next_impent (struct imp_entry *impent ATTRIBUTE_UNUSED) { +#ifdef darwin_declare_class_reference char buf[BUFSIZE]; switch (TREE_CODE (impent->imp_context)) @@ -2303,8 +2310,7 @@ handle_next_impent (struct imp_entry *im return; } -#ifdef ASM_DECLARE_CLASS_REFERENCE - ASM_DECLARE_CLASS_REFERENCE (asm_out_file, buf); + darwin_declare_class_reference (buf); #else return ; /* NULL build for targets other than Darwin. */ #endif @@ -2414,9 +2420,7 @@ objc_generate_v1_next_metadata (void) /* Dump the class references. This forces the appropriate classes to be linked into the executable image, preserving unix archive - semantics. This can be removed when we move to a more dynamically - linked environment. */ - + semantics. */ for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) { handle_next_class_ref (chain);