aboutsummaryrefslogtreecommitdiff
path: root/gcc/objc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-10-12 09:46:38 -0700
committerIan Lance Taylor <iant@golang.org>2020-10-12 09:46:38 -0700
commit9cd320ea6572c577cdf17ce1f9ea5230b166af6d (patch)
treed1c8e7c2e09a91ed75f0e5476c648c2e745aa2de /gcc/objc
parent4854d721be78358e59367982bdd94461b4be3c5a (diff)
parent3175d40fc52fb8eb3c3b18cc343d773da24434fb (diff)
downloadgcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.zip
gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.gz
gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.bz2
Merge from trunk revision 3175d40fc52fb8eb3c3b18cc343d773da24434fb.
Diffstat (limited to 'gcc/objc')
-rw-r--r--gcc/objc/ChangeLog108
-rw-r--r--gcc/objc/objc-act.c6
-rw-r--r--gcc/objc/objc-gnu-runtime-abi-01.c36
-rw-r--r--gcc/objc/objc-next-runtime-abi-01.c4
-rw-r--r--gcc/objc/objc-next-runtime-abi-02.c474
-rw-r--r--gcc/objc/objc-runtime-shared-support.c9
6 files changed, 476 insertions, 161 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 5d8500c..f69d2d7 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,111 @@
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c
+ (create_global_decl): Update to allow the caller to
+ specify declaration or definition.
+ (create_hidden_decl): Likewise.
+ (next_runtime_abi_02_protocol_decl): Make the symbol
+ weak and hidden for later OS runtime versions.
+ (build_v2_protocol_list_address_table): Likewise.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c (objc_v2_build_ivar_ref): Test
+ DECL_C_BIT_FIELD to detect that an ivar is a bitfield.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c (FIXUP_NEEDED): Rename ...
+ (USE_FIXUP_BEFORE): ... to this.
+ (next_runtime_02_initialize): Likewise.
+ (next_runtime_abi_02_get_arg_type_list_base): Likewise.
+ (next_runtime_abi_02_build_objc_method_call): Likewise.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c (TAG_MSGSENDSUPER): Revised
+ spelling.
+ (TAG_MSGSENDID): Likewise.
+ (TAG_MSGSENDSUPER_STRET): Likewise.
+ (TAG_MSGSENDID_STRET): Likewise.
+ (FIXUP_NEEDED): Likewise.
+ (TAG_FIXUP): New.
+ (next_runtime_02_initialize): Adjust message calls to use
+ fixup variants only when required.
+ (next_runtime_abi_02_get_arg_type_list_base): Correct
+ indent.
+ (build_v2_build_objc_method_call): New.
+ (build_v2_objc_method_fixup_call): Split out from ...
+ (next_runtime_abi_02_build_objc_method_call): ... here.
+ Arrange to adjust the call on the basis of the target
+ runtime.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-runtime-shared-support.c (start_var_decl): Make the
+ decl_assembler_name follow the metadata name for C++ on NeXT
+ runtime platforms.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c
+ (next_runtime_abi_02_category_decl): Adjust category
+ superclass name ordering.
+
+2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c (build_v2_super_template): Add new
+ fields to the template.
+ (build_v2_protocol_template): Build new field entries.
+ (generate_v2_meth_descriptor_table): Adjust to allow recording all
+ method types.
+ (generate_v2_meth_type_list): New.
+ (build_v2_protocol_initializer): Initialize the additional fields.
+ (generate_v2_protocols): Record method types for all entries and
+ generate the additional method type table.
+
+2020-10-10 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c
+ (objc_get_superclass_ref_decl): Split this code out.
+ (next_runtime_abi_02_get_class_super_ref): Compute
+ super refs using the objc_get_superclass_ref_decl().
+ (next_runtime_abi_02_get_category_super_ref): Likewise.
+
+2020-10-10 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c
+ (next_runtime_abi_02_init_metadata_attributes): Make protocol
+ refs a distinct section.
+
+2020-10-10 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-next-runtime-abi-02.c
+ (next_runtime_abi_02_init_metadata_attributes): Attach metadata
+ for the special string sections to class, method and method type
+ string sections.
+
+2020-10-10 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc-gnu-runtime-abi-01.c
+ (build_shared_structure_initializer): Remove references to
+ the NeXT runtime.
+ (generate_static_references): Likewise.
+
+2020-09-19 Sandra Loosemore <sandra@codesourcery.com>
+
+ * objc-act.c (objc_start_method_definition): Update to reflect
+ changes to break/continue state bookkeeping in C front end.
+
+2020-09-17 Patrick Palka <ppalka@redhat.com>
+
+ PR c/80076
+ * objc-gnu-runtime-abi-01.c
+ (gnu_runtime_abi_01_get_class_super_ref): Reduce indentation of
+ misleadingly indented return statements.
+ * objc-next-runtime-abi-01.c
+ (next_runtime_abi_01_get_class_super_ref): Likewise.
+
2020-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 54af1cf..31a2cf3 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -2050,10 +2050,8 @@ objc_start_method_definition (bool is_class_method, tree decl, tree attributes,
return false;
#ifndef OBJCPLUS
- /* Indicate no valid break/continue context by setting these variables
- to some non-null, non-label value. We'll notice and emit the proper
- error message in c_finish_bc_stmt. */
- c_break_label = c_cont_label = size_zero_node;
+ /* Indicate no valid break/continue context. */
+ in_statement = 0;
#endif
if (attributes)
diff --git a/gcc/objc/objc-gnu-runtime-abi-01.c b/gcc/objc/objc-gnu-runtime-abi-01.c
index d586243..25c0e01 100644
--- a/gcc/objc/objc-gnu-runtime-abi-01.c
+++ b/gcc/objc/objc-gnu-runtime-abi-01.c
@@ -821,7 +821,7 @@ gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
ucls_super_ref =
objc_build_component_ref (imp->class_decl,
get_identifier ("super_class"));
- return ucls_super_ref;
+ return ucls_super_ref;
}
else
{
@@ -829,7 +829,7 @@ gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
uucls_super_ref =
objc_build_component_ref (imp->meta_decl,
get_identifier ("super_class"));
- return uucls_super_ref;
+ return uucls_super_ref;
}
}
@@ -1540,25 +1540,14 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
- /* FIXME: Remove NeXT runtime code. */
- if (flag_next_runtime)
- {
- ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
- get_identifier ("objc_cache")));
- /* method_cache = */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
- }
- else
- {
- /* dtable = */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ /* dtable = */
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
- /* subclass_list = */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ /* subclass_list = */
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
- /* sibling_class = */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
- }
+ /* sibling_class = */
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* protocol_list = */
ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
@@ -1572,11 +1561,6 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
- /* FIXME: Remove NeXT runtime code. */
- if (flag_next_runtime)
- /* sel_id = NULL */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
-
/* gc_object_type = NULL */
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
@@ -1864,10 +1848,6 @@ generate_static_references (void)
char buf[BUFSIZE];
vec<constructor_elt, va_gc> *decls = NULL;
- /* FIXME: Remove NeXT runtime code. */
- if (flag_next_runtime)
- gcc_unreachable ();
-
for (cl_chain = objc_static_instances, num_class = 0;
cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
{
diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c
index 5c34fcb..233d89e 100644
--- a/gcc/objc/objc-next-runtime-abi-01.c
+++ b/gcc/objc/objc-next-runtime-abi-01.c
@@ -938,7 +938,7 @@ next_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
ucls_super_ref =
objc_build_component_ref (imp->class_decl,
get_identifier ("super_class"));
- return ucls_super_ref;
+ return ucls_super_ref;
}
else
{
@@ -946,7 +946,7 @@ next_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
uucls_super_ref =
objc_build_component_ref (imp->meta_decl,
get_identifier ("super_class"));
- return uucls_super_ref;
+ return uucls_super_ref;
}
}
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index e401906..d7812ff 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -63,9 +63,15 @@ along with GCC; see the file COPYING3. If not see
#define TAG_GETMETACLASS "objc_getMetaClass"
#define TAG_MSGSEND "objc_msgSend"
-#define TAG_MSGSENDSUPER "objc_msgSendSuper"
+#define TAG_MSGSENDID "objc_msgSendId"
+#define TAG_MSGSENDSUPER "objc_msgSendSuper2"
#define TAG_MSGSEND_STRET "objc_msgSend_stret"
-#define TAG_MSGSENDSUPER_STRET "objc_msgSendSuper_stret"
+#define TAG_MSGSENDID_STRET "objc_msgSendId_stret"
+#define TAG_MSGSENDSUPER_STRET "objc_msgSendSuper2_stret"
+
+#define USE_FIXUP_BEFORE 100600
+#define TAG_FIXUP "_fixup"
+
#define TAG_NEXT_EHVTABLE_NAME "objc_ehtype_vtable"
#define TAG_V2_EH_TYPE "objc_ehtype_t"
@@ -305,8 +311,8 @@ next_runtime_abi_02_init_metadata_attributes (void)
meta_class = get_identifier ("G2_CLAS");
meta_metaclass = get_identifier ("G2_META");
- meta_category =
- meta_protocol = meta_base;
+ meta_category = meta_base;
+ meta_protocol = get_identifier ("V2_PCOL");
meta_clac_vars =
meta_clai_vars = meta_base;
@@ -323,9 +329,10 @@ next_runtime_abi_02_init_metadata_attributes (void)
meta_sel_refs = get_identifier ("V2_SRFS");
- meta_class_name =
- meta_meth_name =
- meta_meth_type =
+ meta_class_name = get_identifier ("V2_CNAM");
+ meta_meth_name = get_identifier ("V2_MNAM");
+
+ meta_meth_type = get_identifier ("V2_MTYP");
meta_prop_name_attr = get_identifier ("V2_STRG");
meta_mref = get_identifier ("V2_MREF");
@@ -385,32 +392,43 @@ static void next_runtime_02_initialize (void)
build_v2_protocol_template ();
build_v2_category_template ();
- /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */
- type = build_varargs_function_type_list (objc_object_type,
- objc_object_type,
- objc_v2_selector_type,
- NULL_TREE);
- umsg_fixup_decl = add_builtin_function ("objc_msgSend_fixup",
- type, 0, NOT_BUILT_IN,
+ bool fixup_p = flag_next_runtime < USE_FIXUP_BEFORE;
+ if (fixup_p)
+ {
+ /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */
+ type = build_varargs_function_type_list (objc_object_type,
+ objc_object_type,
+ objc_v2_selector_type,
+ NULL_TREE);
+ }
+ else
+ {
+ /* id objc_msgSendXXXX (id, SEL, ...); */
+ type = build_varargs_function_type_list (objc_object_type,
+ objc_object_type,
+ objc_selector_type,
+ NULL_TREE);
+ }
+ const char *fnam = fixup_p ? TAG_MSGSEND TAG_FIXUP : TAG_MSGSEND;
+ umsg_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
TREE_NOTHROW (umsg_fixup_decl) = 0;
/* id objc_msgSend_stret_fixup_rtp (id, struct message_ref_t*, ...); */
- umsg_stret_fixup_decl = add_builtin_function ("objc_msgSend_stret_fixup",
- type, 0, NOT_BUILT_IN,
+ fnam = fixup_p ? TAG_MSGSEND_STRET TAG_FIXUP : TAG_MSGSEND_STRET;
+ umsg_stret_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
TREE_NOTHROW (umsg_stret_fixup_decl) = 0;
/* id objc_msgSendId_fixup_rtp (id, struct message_ref_t*, ...); */
- umsg_id_fixup_decl = add_builtin_function ("objc_msgSendId_fixup",
- type, 0, NOT_BUILT_IN,
+ fnam = fixup_p ? TAG_MSGSENDID TAG_FIXUP : TAG_MSGSENDID;
+ umsg_id_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
TREE_NOTHROW (umsg_id_fixup_decl) = 0;
- /* id objc_msgSendId_stret_fixup_rtp
- (id, struct message_ref_t*, ...); */
- umsg_id_stret_fixup_decl = add_builtin_function ("objc_msgSendId_stret_fixup",
- type, 0, NOT_BUILT_IN,
+ /* id objc_msgSendId_stret_fixup_rtp (id, struct message_ref_t*, ...); */
+ fnam = fixup_p ? TAG_MSGSENDID_STRET TAG_FIXUP : TAG_MSGSENDID_STRET;
+ umsg_id_stret_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
TREE_NOTHROW (umsg_id_stret_fixup_decl) = 0;
@@ -420,17 +438,17 @@ static void next_runtime_02_initialize (void)
objc_super_type,
objc_v2_super_selector_type,
NULL_TREE);
- umsg_id_super2_fixup_decl = add_builtin_function ("objc_msgSendSuper2_fixup",
- type, 0, NOT_BUILT_IN,
+ fnam = fixup_p ? TAG_MSGSENDSUPER TAG_FIXUP : TAG_MSGSENDSUPER;
+ umsg_id_super2_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
TREE_NOTHROW (umsg_id_super2_fixup_decl) = 0;
/* id objc_msgSendSuper2_stret_fixup_rtp
(struct objc_super *, struct message_ref_t*, ...); */
- umsg_id_super2_stret_fixup_decl =
- add_builtin_function ("objc_msgSendSuper2_stret_fixup",
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ fnam = fixup_p ? TAG_MSGSENDSUPER_STRET TAG_FIXUP : TAG_MSGSENDSUPER_STRET;
+ umsg_id_super2_stret_fixup_decl = add_builtin_function (fnam, type, 0,
+ NOT_BUILT_IN, NULL,
+ NULL_TREE);
TREE_NOTHROW (umsg_id_super2_stret_fixup_decl) = 0;
/* Present in the library, but unused by the FE. */
@@ -742,6 +760,9 @@ build_v2_super_template (void)
const struct _prop_list_t * const properties;
const uint32_t size;
const uint32_t flags;
+ const char ** extended_method_types;
+ const char * demangled_name;
+ const struct _prop_list_t * class_properties;
}
*/
static void
@@ -783,6 +804,16 @@ build_v2_protocol_template (void)
/* const uint32_t flags; */
add_field_decl (integer_type_node, "flags", &chain);
+ /* const char **extendedMethodTypes; */
+ tree ptr_to_ptr_to_char = build_pointer_type (string_type_node);
+ add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain);
+
+ /* const char *demangledName; */
+ add_field_decl (string_type_node, "demangled_name", &chain);
+
+ /* const struct _prop_list_t *class_properties; */
+ add_field_decl (objc_prop_list_ptr, "class_properties", &chain);
+
objc_finish_struct (objc_v2_protocol_template, decls);
}
@@ -889,33 +920,39 @@ create_extern_decl (tree type, const char *name)
/* Create a globally visible definition for variable NAME of a given TYPE. The
finish_var_decl() routine will need to be called on it afterwards. */
+static tree
+create_global_decl (tree type, const char *name, bool is_def = false);
static tree
-create_global_decl (tree type, const char *name)
+create_global_decl (tree type, const char *name, bool is_def)
{
tree id = get_identifier (name);
tree var = hash_name_lookup (extern_names, id);
if (var)
- {
- DECL_EXTERNAL (var) = 0;
- TREE_STATIC (var) = 1;
- }
+ is_def = true;
else
{
var = start_var_decl (type, name);
hash_name_enter (extern_names, var);
}
+ if (is_def)
+ {
+ DECL_EXTERNAL (var) = 0;
+ TREE_STATIC (var) = 1;
+ }
TREE_PUBLIC (var) = 1;
return var;
}
/* Create a symbol with __attribute__ ((visibility ("hidden")))
attribute (private extern). */
+static tree
+create_hidden_decl (tree type, const char *name, bool is_def = false);
static tree
-create_hidden_decl (tree type, const char *name)
+create_hidden_decl (tree type, const char *name, bool is_def)
{
- tree decl = create_global_decl (type, name);
+ tree decl = create_global_decl (type, name, is_def);
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
return decl;
@@ -966,9 +1003,9 @@ next_runtime_abi_02_category_decl (tree klass)
{
tree decl;
char buf[BUFSIZE];
- snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
- IDENTIFIER_POINTER (CLASS_NAME (klass)));
+ snprintf (buf, BUFSIZE, "_OBJC_Category_%s_%s",
+ IDENTIFIER_POINTER (CLASS_NAME (klass)),
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)));
decl = start_var_decl (objc_v2_category_template, buf);
OBJCMETA (decl, objc_meta, meta_category);
return decl;
@@ -983,7 +1020,13 @@ next_runtime_abi_02_protocol_decl (tree p)
/* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
- decl = start_var_decl (objc_v2_protocol_template, buf);
+ if (flag_next_runtime >= USE_FIXUP_BEFORE)
+ {
+ decl = create_hidden_decl (objc_v2_protocol_template, buf);
+ DECL_WEAK (decl) = true;
+ }
+ else
+ decl = start_var_decl (objc_v2_protocol_template, buf);
OBJCMETA (decl, objc_meta, meta_protocol);
return decl;
}
@@ -1120,10 +1163,12 @@ next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
receiver_type = objc_object_type;
vec_safe_push (*argtypes, receiver_type);
- /* Selector type - will eventually change to `int'. */
- vec_safe_push (*argtypes,
- superflag ? objc_v2_super_selector_type
- : objc_v2_selector_type);
+ if (flag_next_runtime < USE_FIXUP_BEFORE)
+ /* Selector type - will eventually change to `int'. */
+ vec_safe_push (*argtypes, superflag ? objc_v2_super_selector_type
+ : objc_v2_selector_type);
+ else
+ vec_safe_push (*argtypes, objc_selector_type);
}
/* TODO: Merge this with the message refs. */
@@ -1362,12 +1407,7 @@ objc_v2_build_ivar_ref (tree datum, tree component)
return NULL_TREE;
/* This routine only handles non-bitfield fields */
- /* DECL_INITIAL macro is set to width of bitfield and can be relied
- on to check for bitfield ivars. Note that I cannot rely on
- DECL_BIT_FIELD macro because it is only set when the whole struct
- is seen (at finish_struct) and not when the ivar chain is
- built. */
- if (DECL_INITIAL (field))
+ if (DECL_C_BIT_FIELD (field))
return NULL_TREE;
create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name), field);
@@ -1438,13 +1478,12 @@ build_v2_superclass_ref_decl (tree ident, bool inst)
static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs;
static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs;
+/* Find or build a superclass reference decl for class NAME. */
+
static tree
-next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
- struct imp_entry *imp, bool inst_meth)
+objc_get_superclass_ref_decl (tree name, bool inst_meth)
{
tree decl;
- ident_data_tuple e;
- tree id = CLASS_NAME (imp->imp_context);
vec<ident_data_tuple, va_gc> *list = inst_meth ? class_super_refs
: metaclass_super_refs;
@@ -1454,10 +1493,10 @@ next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
ident_data_tuple *ref;
FOR_EACH_VEC_ELT (*list, count, ref)
{
- if (ref->ident == id)
+ if (ref->ident == name)
{
if (!ref->data)
- ref->data = build_v2_superclass_ref_decl (id, inst_meth);
+ ref->data = build_v2_superclass_ref_decl (name, inst_meth);
return ref->data;
}
}
@@ -1478,48 +1517,49 @@ next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
}
/* We come here if we don't find the entry - or if the table was yet
to be created. */
- decl = build_v2_superclass_ref_decl (id, inst_meth);
- e.ident = id;
+ decl = build_v2_superclass_ref_decl (name, inst_meth);
+ ident_data_tuple e;
+ e.ident = name;
e.data = decl;
vec_safe_push (list, e);
return decl;
}
+/* Get a reference to the superclass for IMP. */
+
+static tree
+next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
+ struct imp_entry *imp, bool inst_meth)
+{
+ tree name = CLASS_NAME (imp->imp_context);
+ return objc_get_superclass_ref_decl (name, inst_meth);
+}
+
+/* Get a reference to the superclass for category IMP. */
+
static tree
next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
- struct imp_entry *imp, bool inst_meth)
+ struct imp_entry *imp,
+ bool inst_meth)
{
- /* ??? is this OK when zero-link = true? */
- tree super_name = CLASS_SUPER_NAME (imp->imp_template);
- tree super_class;
-
- if (!flag_zero_link)
+ if (flag_zero_link)
{
- super_class = objc_get_class_reference (CLASS_NAME (imp->imp_template));
-
- if (!inst_meth)
-
- /* If we are in a class method, we must retrieve the
- _metaclass_ for the current class, pointed at by the
- class's "isa" pointer. The following assumes that "isa" is
- the first ivar in a class (which it must be). */
- super_class =
- build_indirect_ref (input_location,
- build_c_cast (input_location,
- build_pointer_type (objc_class_type),
- super_class),
- RO_UNARY_STAR);
- return super_class;
- }
- /* ??? Do we need to add the class ref anway for zero-link? */
- /* else do it the slow way. */
- super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
- super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
- IDENTIFIER_POINTER (super_name));
- /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
- return build_function_call (input_location,
- super_class,
- build_tree_list (NULL_TREE, super_name));
+ /* Do it the slow way. */
+ tree get_cl_fn = inst_meth ? objc_get_class_decl
+ : objc_get_meta_class_decl;
+ tree super_name = CLASS_SUPER_NAME (imp->imp_template);
+ super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
+ IDENTIFIER_POINTER (super_name));
+ /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
+ return build_function_call (input_location, get_cl_fn,
+ build_tree_list (NULL_TREE, super_name));
+ }
+
+ /* This is the 'usual' path. */
+ tree cls_name = CLASS_NAME (imp->imp_template);
+ if (!inst_meth)
+ return objc_get_superclass_ref_decl (cls_name, inst_meth);
+ return objc_get_class_reference (cls_name);
}
static tree
@@ -1575,10 +1615,9 @@ objc_copy_to_temp_side_effect_params (tree fntype, tree values)
(*_msg.messenger) (receiver, &_msg, ...) */
static tree
-build_v2_build_objc_method_call (int super_flag, tree method_prototype,
- tree lookup_object, tree selector,
- tree method_params,
- bool check_for_nil)
+build_v2_objc_method_fixup_call (int super_flag, tree method_prototype,
+ tree lookup_object, tree selector,
+ tree method_params, bool check_for_nil)
{
tree ret_val;
tree sender, rcv_p, t;
@@ -1659,6 +1698,118 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
}
static tree
+build_v2_build_objc_method_call (int super, tree method_prototype,
+ tree lookup_object, tree selector,
+ tree method_params, location_t loc,
+ bool check_for_nil, bool rx_is_id)
+{
+ tree sender, sender_cast, method, t;
+ tree rcv_p = (super ? objc_super_type : objc_object_type);
+ vec<tree, va_gc> *parms;
+ unsigned nparm = (method_params ? list_length (method_params) : 0);
+
+ /* If a prototype for the method to be called exists, then cast
+ the sender's return type and arguments to match that of the method.
+ Otherwise, leave sender as is. */
+ tree ret_type
+ = (method_prototype
+ ? TREE_VALUE (TREE_TYPE (method_prototype))
+ : objc_object_type);
+ tree ftype = build_function_type_for_method (ret_type, method_prototype,
+ METHOD_REF, super);
+
+ if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
+ ftype = build_type_attribute_variant (ftype,
+ METHOD_TYPE_ATTRIBUTES
+ (method_prototype));
+
+ sender_cast = build_pointer_type (ftype);
+
+ lookup_object = build_c_cast (loc, rcv_p, lookup_object);
+
+ /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
+ lookup_object = save_expr (lookup_object);
+
+ /* Param list + 2 slots for object and selector. */
+ vec_alloc (parms, nparm + 2);
+
+ /* If we are returning a struct in memory, and the address
+ of that memory location is passed as a hidden first
+ argument, then change which messenger entry point this
+ expr will call. NB: Note that sender_cast remains
+ unchanged (it already has a struct return type). */
+ if (!targetm.calls.struct_value_rtx (0, 0)
+ && (TREE_CODE (ret_type) == RECORD_TYPE
+ || TREE_CODE (ret_type) == UNION_TYPE)
+ && targetm.calls.return_in_memory (ret_type, 0))
+ {
+ if (super)
+ sender = umsg_id_super2_stret_fixup_decl;
+ else
+ sender = rx_is_id ? umsg_id_stret_fixup_decl
+ : umsg_stret_fixup_decl;
+ }
+ else
+ {
+ if (super)
+ sender = umsg_id_super2_fixup_decl;
+ else
+ sender = rx_is_id ? umsg_id_fixup_decl
+ : umsg_fixup_decl;
+ }
+
+ method = build_fold_addr_expr_loc (loc, sender);
+
+ /* Pass the object to the method. */
+ parms->quick_push (lookup_object);
+ /* Pass the selector to the method. */
+ parms->quick_push (selector);
+ /* Now append the remainder of the parms. */
+ if (nparm)
+ for (; method_params; method_params = TREE_CHAIN (method_params))
+ parms->quick_push (TREE_VALUE (method_params));
+
+ /* Build an obj_type_ref, with the correct cast for the method call. */
+ t = build3 (OBJ_TYPE_REF, sender_cast, method,
+ lookup_object, size_zero_node);
+ tree ret_val = build_function_call_vec (loc, vNULL, t, parms, NULL);
+ vec_free (parms);
+ if (check_for_nil)
+ {
+ /* receiver != nil ? ret_val : 0 */
+ tree ftree;
+ tree ifexp;
+
+ if (TREE_CODE (ret_type) == RECORD_TYPE
+ || TREE_CODE (ret_type) == UNION_TYPE)
+ {
+ vec<constructor_elt, va_gc> *rtt = NULL;
+ /* ??? CHECKME. hmmm..... think we need something more
+ here. */
+ CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
+ ftree = objc_build_constructor (ret_type, rtt);
+ }
+ else
+ ftree = fold_convert (ret_type, integer_zero_node);
+
+ ifexp = build_binary_op (loc, NE_EXPR,
+ lookup_object,
+ fold_convert (rcv_p, integer_zero_node), 1);
+
+#ifdef OBJCPLUS
+ ret_val = build_conditional_expr (loc, ifexp, ret_val, ftree,
+ tf_warning_or_error);
+#else
+ /* ??? CHECKME. */
+ ret_val = build_conditional_expr (loc, ifexp, 1,
+ ret_val, NULL_TREE, loc,
+ ftree, NULL_TREE, loc);
+#endif
+ }
+ return ret_val;
+}
+
+static tree
next_runtime_abi_02_build_objc_method_call (location_t loc,
tree method_prototype,
tree receiver,
@@ -1667,27 +1818,38 @@ next_runtime_abi_02_build_objc_method_call (location_t loc,
tree method_params,
int super)
{
- tree ret_type, selector;
- tree message_func_decl;
- bool check_for_nil = flag_objc_nilcheck;
-
- ret_type = method_prototype
- ? TREE_VALUE (TREE_TYPE (method_prototype))
- : objc_object_type;
-
/* Do we need to check for nil receivers ? */
/* For now, message sent to classes need no nil check. In the
future, class declaration marked as weak_import must be nil
checked. */
+ bool check_for_nil = flag_objc_nilcheck;
if (super
|| (TREE_CODE (receiver) == VAR_DECL
&& TREE_TYPE (receiver) == objc_class_type))
check_for_nil = false;
+ if (flag_next_runtime >= USE_FIXUP_BEFORE)
+ {
+ tree selector
+ = next_runtime_abi_02_build_selector_reference (loc, sel_name,
+ method_prototype);
+ return build_v2_build_objc_method_call (super, method_prototype,
+ receiver, selector,
+ method_params, loc,
+ check_for_nil,
+ objc_is_id (rtype));
+ }
+
+ /* else we have to build a pair of the function and selector. */
+ tree message_func_decl;
+ tree ret_type = method_prototype
+ ? TREE_VALUE (TREE_TYPE (method_prototype))
+ : objc_object_type;
+
if (!targetm.calls.struct_value_rtx (0, 0)
- && (TREE_CODE (ret_type) == RECORD_TYPE
- || TREE_CODE (ret_type) == UNION_TYPE)
- && targetm.calls.return_in_memory (ret_type, 0))
+ && (TREE_CODE (ret_type) == RECORD_TYPE
+ || TREE_CODE (ret_type) == UNION_TYPE)
+ && targetm.calls.return_in_memory (ret_type, 0))
{
if (super)
message_func_decl = umsg_id_super2_stret_fixup_decl;
@@ -1706,7 +1868,7 @@ next_runtime_abi_02_build_objc_method_call (location_t loc,
: umsg_fixup_decl;
}
- selector = build_v2_selector_messenger_reference (sel_name,
+ tree selector = build_v2_selector_messenger_reference (sel_name,
message_func_decl);
/* selector = &_msg; */
@@ -1717,9 +1879,9 @@ next_runtime_abi_02_build_objc_method_call (location_t loc,
selector);
/* (*_msg.messenger) (receiver, &_msg, ...); */
- return build_v2_build_objc_method_call (super, method_prototype,
- receiver, selector,
- method_params, check_for_nil);
+ return build_v2_objc_method_fixup_call (super, method_prototype, receiver,
+ selector, method_params,
+ check_for_nil);
}
/* NOTE --- Constant String Class Stuff --- */
@@ -2145,7 +2307,13 @@ build_v2_protocol_list_address_table (void)
gcc_assert (ref->id && TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE);
snprintf (buf, BUFSIZE, "_OBJC_LabelProtocol_%s",
IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id)));
- decl = create_global_decl (objc_protocol_type, buf);
+ if (flag_next_runtime >= USE_FIXUP_BEFORE)
+ {
+ decl = create_hidden_decl (objc_protocol_type, buf, /*is def=*/true);
+ DECL_WEAK (decl) = true;
+ }
+ else
+ decl = create_global_decl (objc_protocol_type, buf, /*is def=*/true);
expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl));
OBJCMETA (decl, objc_meta, meta_label_protocollist);
finish_var_decl (decl, expr);
@@ -2295,9 +2463,10 @@ build_v2_method_list_template (tree list_type, int size)
objc_method_prototype_template which is missing this field. */
static tree
generate_v2_meth_descriptor_table (tree chain, tree protocol,
- const char *prefix, tree attr)
+ const char *prefix, tree attr,
+ vec<tree>& all_meths)
{
- tree method_list_template, initlist, decl, methods;
+ tree method_list_template, initlist, decl;
int size, entsize;
vec<constructor_elt, va_gc> *v = NULL;
char buf[BUFSIZE];
@@ -2305,13 +2474,14 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol,
if (!chain || !prefix)
return NULL_TREE;
- methods = chain;
+ tree method = chain;
size = 0;
- while (methods)
+ while (method)
{
- if (! METHOD_ENCODING (methods))
- METHOD_ENCODING (methods) = encode_method_prototype (methods);
- methods = TREE_CHAIN (methods);
+ if (! METHOD_ENCODING (method))
+ METHOD_ENCODING (method) = encode_method_prototype (method);
+ all_meths.safe_push (method);
+ method = TREE_CHAIN (method);
size++;
}
@@ -2336,6 +2506,31 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol,
return decl;
}
+static tree
+generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol,
+ const char *prefix)
+{
+ if (all_meths.is_empty () || !prefix)
+ return NULL_TREE;
+
+ unsigned size = all_meths.length ();
+ tree list_type = build_sized_array_type (string_type_node, size);
+ char *nam;
+ asprintf (&nam, "%s_%s", prefix,
+ IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
+ tree decl = start_var_decl (list_type, nam);
+ free (nam);
+ OBJCMETA (decl, objc_meta, meta_base);
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ for (unsigned i = 0; i < size; ++i)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ add_objc_string (METHOD_ENCODING (all_meths[i]),
+ meth_var_types));
+ finish_var_decl (decl, objc_build_constructor (list_type, v));
+ return decl;
+}
+
/* This routine builds the initializer list to initialize the 'struct
_prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */
@@ -2462,7 +2657,8 @@ static tree
build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
tree inst_methods, tree class_methods,
tree opt_ins_meth, tree opt_cls_meth,
- tree property_list)
+ tree property_list, tree ext_meth_types,
+ tree demangled_name, tree class_prop_list)
{
tree expr, ttyp;
location_t loc;
@@ -2517,7 +2713,28 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list
/* const uint32_t flags; = 0 */
CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node);
- return objc_build_constructor (type, inits);
+ ttyp = build_pointer_type (string_type_node);
+ if (ext_meth_types)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ ttyp = string_type_node;
+ if (demangled_name)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ ttyp = objc_prop_list_ptr;
+ if (class_prop_list)
+ expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0));
+ else
+ expr = convert (ttyp, null_pointer_node);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+
+ return objc_build_constructor (type, inits);
}
/* Main routine to build all meta data for all protocols used in a
@@ -2553,25 +2770,26 @@ generate_v2_protocols (void)
loc = DECL_SOURCE_LOCATION (decl);
some = true;
+ vec<tree> all_meths = vNULL;
inst_meth =
generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
"_OBJC_ProtocolInstanceMethods",
- meta_proto_nst_meth);
+ meta_proto_nst_meth, all_meths);
class_meth =
generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
"_OBJC_ProtocolClassMethods",
- meta_proto_cls_meth);
+ meta_proto_cls_meth, all_meths);
opt_inst_meth =
generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p,
- "_OBJC_OptProtocolInstMethods",
- meta_proto_nst_meth);
+ "_OBJC_ProtocolOptInstMethods",
+ meta_proto_nst_meth, all_meths);
opt_class_meth =
generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p,
- "_OBJC_OptProtocolClassMethods",
- meta_proto_cls_meth);
+ "_OBJC_ProtocolOptClassMethods",
+ meta_proto_cls_meth, all_meths);
if (PROTOCOL_LIST (p))
refs_decl = generate_v2_protocol_list (p, NULL_TREE);
@@ -2589,13 +2807,21 @@ generate_v2_protocols (void)
props = generate_v2_property_table (p, NULL_TREE);
+ tree ext_meth_types
+ = generate_v2_meth_type_list (all_meths, p,
+ "_OBJC_ProtocolMethodTypes");
+ tree demangled_name = NULL_TREE;
+ tree class_prop_list = NULL_TREE;
+
initlist = build_v2_protocol_initializer (TREE_TYPE (decl),
protocol_name_expr, refs_expr,
inst_meth, class_meth,
opt_inst_meth, opt_class_meth,
- props);
+ props, ext_meth_types,
+ demangled_name,class_prop_list);
finish_var_decl (decl, initlist);
objc_add_to_protocol_list (p, decl);
+ all_meths.truncate (0);
}
if (some)
diff --git a/gcc/objc/objc-runtime-shared-support.c b/gcc/objc/objc-runtime-shared-support.c
index 4aecc7f..16d4d63 100644
--- a/gcc/objc/objc-runtime-shared-support.c
+++ b/gcc/objc/objc-runtime-shared-support.c
@@ -117,14 +117,17 @@ add_field_decl (tree type, const char *name, tree **chain)
tree
start_var_decl (tree type, const char *name)
{
- tree var = build_decl (input_location,
- VAR_DECL, get_identifier (name), type);
- TREE_STATIC (var) = 1;
+ tree name_id = get_identifier (name);
+ tree var = build_decl (input_location, VAR_DECL, name_id, type);
DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
+ TREE_STATIC (var) = 1;
DECL_IGNORED_P (var) = 1;
DECL_ARTIFICIAL (var) = 1;
DECL_CONTEXT (var) = NULL_TREE;
#ifdef OBJCPLUS
+ /* Meta-data for the NeXT runtime is expected to be 'extern "C"'. */
+ if (flag_next_runtime)
+ SET_DECL_ASSEMBLER_NAME (var, name_id);
DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
#endif
return var;