Iain
===
gcc/
* target.def (handled_assemble_variable_p): New hook.
* varasm.c (assemble_variable): Allow target to handle
variable
output
in some special manner.
* doc/tm.texi: Regenerate.
* config/darwin.c (darwin_objc1_section): Handle class defs/
refs.
(darwin_handled_assemble_variable_p): New.
* config/darwin-protos.h
(darwin_handled_assemble_variable_p): New.
* config/darwin.h (TARGET_ASM_HANDLED_ASSEMBLE_VARIABLE_P):
New.
gcc/objc/
*objc-next-runtime-abi-01.c (handle_next_class_ref): Don't
emit lazy
refs. for
cases where the class is local. Declare a real, meta-data
item
tagged as
a class reference.
(handle_next_impent): Declare a real, meta-data item tagged
as a
class def.
===
Index: gcc/target.def
===================================================================
--- gcc/target.def (revision 175628)
+++ gcc/target.def (working copy)
@@ -449,6 +449,13 @@ DEFHOOK
bool, (FILE *file, rtx x),
default_asm_output_addr_const_extra)
+DEFHOOK
+(handled_assemble_variable_p,
+ "Returns @code{true} iff the target has handled the assembly of
the\
+ variable @var{var_decl}",
+ bool, (tree var_decl),
+ hook_bool_tree_false)
+
/* ??? The TARGET_PRINT_OPERAND* hooks are part of the asm_out
struct,
even though that is not reflected in the macro name to override
their
initializers. */
Index: gcc/objc/objc-next-runtime-abi-01.c
===================================================================
--- gcc/objc/objc-next-runtime-abi-01.c (revision 175628)
+++ gcc/objc/objc-next-runtime-abi-01.c (working copy)
@@ -2267,27 +2267,51 @@ generate_objc_symtab_decl (void)
init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
}
-
static void
handle_next_class_ref (tree chain)
{
+ tree decl, exp;
+ struct imp_entry *impent;
const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
char *string = (char *) alloca (strlen (name) + 30);
+ for (impent = imp_list; impent; impent = impent->next)
+ if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE
+ && IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))
+ == IDENTIFIER_POINTER (TREE_VALUE (chain)))
+ return; /* we declare this, no need for a lazy ref. */
+
sprintf (string, ".objc_class_name_%s", name);
-#ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
- ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
-#else
- return ; /* NULL build for targets other than Darwin. */
-#endif
+ decl = build_decl (UNKNOWN_LOCATION,
+ VAR_DECL, get_identifier (string),
char_type_node);
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ DECL_CONTEXT (decl) = NULL_TREE;
+ finish_var_decl (decl, NULL);
+
+ /* We build a variable to signal the reference. This will be
intercepted
+ and output as a lazy reference. */
+ sprintf (string, "_OBJC_class_ref_%s", name);
+ exp = build1 (ADDR_EXPR, string_type_node, decl);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (string),
string_type_node);
+ TREE_STATIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+
+ /* We must force the reference. */
+ DECL_PRESERVE_P (decl) = 1;
+ OBJCMETA (decl, objc_meta, get_identifier ("V1_CREF"));
+ DECL_CONTEXT (decl) = NULL_TREE;
+ finish_var_decl (decl, exp);
}
static void
handle_next_impent (struct imp_entry *impent)
{
char buf[BUFSIZE];
-
+ tree decl;
switch (TREE_CODE (impent->imp_context))
{
case CLASS_IMPLEMENTATION_TYPE:
@@ -2303,11 +2327,16 @@ handle_next_impent (struct imp_entry *impent)
return;
}
-#ifdef ASM_DECLARE_CLASS_REFERENCE
- ASM_DECLARE_CLASS_REFERENCE (asm_out_file, buf);
-#else
- return ; /* NULL build for targets other than Darwin. */
-#endif
+ /* We build a variable to signal that this TU contains this class
metadata. */
+ decl = build_decl (UNKNOWN_LOCATION,
+ VAR_DECL, get_identifier (buf), char_type_node);
+ TREE_PUBLIC (decl) = 1;
+ DECL_CONTEXT (decl) = NULL_TREE;
+ OBJCMETA (decl, objc_meta, get_identifier ("V1_CDEF"));
+ TREE_STATIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ finish_var_decl (decl, NULL);
}
static void
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c (revision 175628)
+++ gcc/varasm.c (working copy)
@@ -2009,6 +2009,10 @@ assemble_variable (tree decl, int top_level
ATTRIB
align_variable (decl, dont_output_data);
set_mem_align (decl_rtl, DECL_ALIGN (decl));
+ /* Allow the target to handle the variable output in some
special manner.
*/
+ if (targetm.asm_out.handled_assemble_variable_p (decl))
+ return;
+
if (TREE_PUBLIC (decl))
maybe_assemble_visibility (decl);
Index: gcc/config/darwin-protos.h
===================================================================
--- gcc/config/darwin-protos.h (revision 175628)
+++ gcc/config/darwin-protos.h (working copy)
@@ -106,6 +106,7 @@ extern void
darwin_asm_output_aligned_decl_local (
extern void darwin_asm_output_aligned_decl_common (FILE *, tree,
const char
*,
unsigned
HOST_WIDE_INT,
unsigned int);
+extern bool darwin_handled_assemble_variable_p (tree);
extern bool darwin_binds_local_p (const_tree);
extern void darwin_cpp_builtins (struct cpp_reader *);
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c (revision 175628)
+++ gcc/config/darwin.c (working copy)
@@ -1439,6 +1439,11 @@ darwin_objc1_section (tree decl
ATTRIBUTE_UNUSED,
else if (!strncmp (p, "V2_CSTR", 7))
return darwin_sections[objc_constant_string_object_section];
+ else if (!strncmp (p, "V1_CREF", 7))
+ return darwin_sections[objc_cls_refs_section];
+ else if (!strncmp (p, "V1_CDEF", 7))
+ return data_section;
+
return base;
}
@@ -2594,6 +2599,53 @@ darwin_assemble_visibility (tree decl, int
vis)
"not supported in this configuration; ignored");
}
+/* For certain Objective-C metadata we handle the assembly of the
variables
+ here (it must be here, rather than in darwin-c.c, to cater for
LTO).
When
+ we reference a class we emit a lazy ref, when we have class
metadata
+ (local to a specific object), we emit a tag so that linkage
will be
+ satisfied for the class. */
+
+bool
+darwin_handled_assemble_variable_p (tree decl)
+{
+ tree meta;
+ if (DECL_ATTRIBUTES (decl)
+ && (meta = lookup_attribute ("OBJC1META", DECL_ATTRIBUTES
(decl))))
+ {
+ const char *name;
+ rtx decl_rtl, symbol;
+
+ if (TREE_VALUE (meta) == get_identifier ("V1_CREF"))
+ {
+ tree exp = DECL_INITIAL (decl);
+ gcc_assert (exp
+ && exp != error_mark_node
+ && TREE_CODE (exp) == ADDR_EXPR);
+ exp = TREE_OPERAND (exp, 0);
+ decl_rtl = DECL_RTL (exp);
+ symbol = XEXP (decl_rtl, 0);
+ name = XSTR (symbol, 0);
+ targetm.asm_out.globalize_decl_name (asm_out_file, exp);
+ fputs ("\t.lazy_reference\t",asm_out_file);
+ assemble_name (asm_out_file, name);
+ fputs ("\n",asm_out_file);
+ return true;
+ }
+ else if (TREE_VALUE (meta) == get_identifier ("V1_CDEF"))
+ {
+ decl_rtl = DECL_RTL (decl);
+ symbol = XEXP (decl_rtl, 0);
+ name = XSTR (symbol, 0);
+ targetm.asm_out.globalize_decl_name (asm_out_file, decl);
+ fputs ("\t",asm_out_file);
+ assemble_name (asm_out_file, name);
+ fputs (" = 0\n",asm_out_file);
+ return true;
+ }
+ }
+ return false;
+}
+
/* VEC Used by darwin_asm_dwarf_section.
Maybe a hash tab would be better here - but the intention is
that this is
a very short list (fewer than 16 items) and each entry should
(ideally,
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h (revision 175628)
+++ gcc/config/darwin.h (working copy)
@@ -678,6 +678,9 @@ extern GTY(()) section *
darwin_sections[NUM_DARWI
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION machopic_select_section
+#undef TARGET_ASM_HANDLED_ASSEMBLE_VARIABLE_P
+#define TARGET_ASM_HANDLED_ASSEMBLE_VARIABLE_P
darwin_handled_assemble_variable_p
+
#undef TARGET_ASM_FUNCTION_SECTION
#define TARGET_ASM_FUNCTION_SECTION darwin_function_section