static tree build_keyword_selector PROTO((tree));
static tree synth_id_with_class_suffix PROTO((char *, tree));
+/* from expr.c */
+extern int apply_args_register_offset PROTO((int));
+
/* misc. bookkeeping */
typedef struct hashed_entry *hash;
static void add_class_reference PROTO((tree));
static tree objc_copy_list PROTO((tree, tree *));
static tree build_protocol_template PROTO((void));
-static tree build_descriptor_table_initializer PROTO((tree, tree, int *));
+static tree build_descriptor_table_initializer PROTO((tree, tree));
static tree build_method_prototype_list_template PROTO((tree, int));
static tree build_method_prototype_template PROTO((void));
static int forwarding_offset PROTO((tree));
static void check_ivars PROTO((tree, tree));
static tree build_ivar_list_template PROTO((tree, int));
static tree build_method_list_template PROTO((tree, int));
-static tree build_ivar_list_initializer PROTO((tree, tree, int *));
+static tree build_ivar_list_initializer PROTO((tree, tree));
static tree generate_ivars_list PROTO((tree, char *, int, tree));
-static tree build_dispatch_table_initializer PROTO((tree, tree, int *));
+static tree build_dispatch_table_initializer PROTO((tree, tree));
static tree generate_dispatch_table PROTO((tree, char *, int, tree));
static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree));
static void generate_category PROTO((tree));
}
static tree
-build_descriptor_table_initializer (type, entries, size)
+build_descriptor_table_initializer (type, entries)
tree type;
tree entries;
- int *size;
{
tree initlist = NULLT;
do
{
- initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist);
+ tree eltlist = NULLT;
+
+ eltlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), NULLT);
+ eltlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), eltlist);
- initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist);
+ initlist = tree_cons (NULLT, build_constructor (type, nreverse (eltlist)), initlist);
- (*size)++;
entries = TREE_CHAIN (entries);
}
while (entries);
- return build_constructor (type, nreverse (initlist));
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
}
/* struct objc_method_prototype_list {
return proto_record;
}
+/* True if last call to forwarding_offset yielded a register offset */
+static int offset_is_register;
+
static int
forwarding_offset (parm)
tree parm;
offset_in_bytes = 0;
offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
+ offset_is_register = 0;
}
-#ifdef OBJC_FORWARDING_REG_OFFSET
else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
{
int regno = REGNO (DECL_INCOMING_RTL (parm));
-
- offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG)
- + OBJC_FORWARDING_REG_OFFSET;
+ offset_in_bytes = apply_args_register_offset (regno);
+ offset_is_register = 1;
}
-#endif /* OBJC_FORWARDING_REG_OFFSET */
else
return 0;
+ (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
/ BITS_PER_UNIT));
- if (parm_end > max_parm_end)
+ if (!offset_is_register && max_parm_end < parm_end)
max_parm_end = parm_end;
}
/* compute offset */
sprintf (buf, "%d", forwarding_offset (parms));
+
+ /* indicate register */
+ if (offset_is_register)
+ obstack_1grow (&util_obstack, '+');
+
obstack_grow (&util_obstack, buf, strlen (buf));
}
chain = PROTOCOL_CLS_METHODS (protocol);
if (chain)
{
- tree field;
-
- size = 0;
+ size = list_length (chain);
method_list_template
= build_method_prototype_list_template (objc_method_prototype_template,
size);
- field = TREE_CHAIN (TYPE_FIELDS (method_list_template));
- initlist = build_descriptor_table_initializer (TREE_TYPE (field),
- chain, &size);
+ initlist
+ = build_descriptor_table_initializer (objc_method_prototype_template,
+ chain);
UOBJC_CLASS_METHODS_decl
= generate_descriptor_table (method_list_template,
chain = PROTOCOL_NST_METHODS (protocol);
if (chain)
{
- tree field;
-
- size = 0;
+ size = list_length (chain);
method_list_template
= build_method_prototype_list_template (objc_method_prototype_template,
size);
- field = TREE_CHAIN (TYPE_FIELDS (method_list_template));
- initlist = build_descriptor_table_initializer (TREE_TYPE (field),
- chain, &size);
+ initlist
+ = build_descriptor_table_initializer (objc_method_prototype_template,
+ chain);
UOBJC_INSTANCE_METHODS_decl
= generate_descriptor_table (method_list_template,
}
static tree
-build_ivar_list_initializer (type, field_decl, size)
+build_ivar_list_initializer (type, field_decl)
tree type;
tree field_decl;
- int *size;
{
tree initlist = NULLT;
do
{
+ tree ivar = NULLT;
+
/* set name */
if (DECL_NAME (field_decl))
- initlist = tree_cons (NULLT,
- add_objc_string (DECL_NAME (field_decl),
- meth_var_names),
- initlist);
+ ivar = tree_cons (NULLT,
+ add_objc_string (DECL_NAME (field_decl),
+ meth_var_names),
+ ivar);
else
/* unnamed bit-field ivar (yuck). */
- initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+ ivar = tree_cons (NULLT, build_int_2 (0, 0), ivar);
/* set type */
encode_field_decl (field_decl,
obstack_object_size (&util_obstack),
OBJC_ENCODE_DONT_INLINE_DEFS);
obstack_1grow (&util_obstack, 0); /* null terminate string */
- initlist
+ ivar
= tree_cons
(NULLT,
add_objc_string (get_identifier (obstack_finish (&util_obstack)),
meth_var_types),
- initlist);
+ ivar);
obstack_free (&util_obstack, util_firstobj);
/* set offset */
- initlist
+ ivar
= tree_cons
(NULLT,
build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
/ BITS_PER_UNIT),
0),
- initlist);
- (*size)++;
+ ivar);
+
+ initlist = tree_cons (NULLT,
+ build_constructor (type, nreverse (ivar)),
+ initlist);
+
field_decl = TREE_CHAIN (field_decl);
}
while (field_decl);
- return build_constructor (type, nreverse (initlist));
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
}
static tree
if (CLASS_SUPER_NAME (implementation_template) == NULLT
&& (chain = TYPE_FIELDS (objc_class_template)))
{
- size = 0;
+ size = list_length (chain);
+
ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
- initlist = build_ivar_list_initializer (ivar_list_template,
- chain, &size);
+ initlist = build_ivar_list_initializer (objc_ivar_template, chain);
UOBJC_CLASS_VARIABLES_decl
= generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
chain = CLASS_IVARS (implementation_template);
if (chain)
{
- size = 0;
+ size = list_length (chain);
ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
- initlist = build_ivar_list_initializer (ivar_list_template,
- chain, &size);
+ initlist = build_ivar_list_initializer (objc_ivar_template, chain);
UOBJC_INSTANCE_VARIABLES_decl
= generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
}
static tree
-build_dispatch_table_initializer (type, entries, size)
+build_dispatch_table_initializer (type, entries)
tree type;
tree entries;
- int *size;
{
tree initlist = NULLT;
do
{
- initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
- initlist);
+ tree elemlist = NULLT;
+
+ elemlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
+ NULLT);
- initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
+ elemlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
meth_var_types),
- initlist);
+ elemlist);
- initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
+ elemlist = tree_cons (NULLT,
+ build_unary_op (ADDR_EXPR, METHOD_DEFINITION (entries), 1),
+ elemlist);
+
+ initlist = tree_cons (NULLT,
+ build_constructor (type, nreverse (elemlist)),
+ initlist);
- (*size)++;
entries = TREE_CHAIN (entries);
}
while (entries);
- return build_constructor (type, nreverse (initlist));
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
}
/* To accomplish method prototyping without generating all kinds of
inane warnings, the definition of the dispatch table entries were
changed from:
- struct objc_method { SEL _cmd; id (*_imp)(); };
+ struct objc_method { SEL _cmd; ...; id (*_imp)(); };
to:
- struct objc_method { SEL _cmd; void *_imp; }; */
+ struct objc_method { SEL _cmd; ...; void *_imp; }; */
static tree
build_method_template ()
chain = CLASS_CLS_METHODS (implementation_context);
if (chain)
{
- size = 0;
+ size = list_length (chain);
- method_list_template = build_method_list_template (objc_method_template,
- size);
- initlist = build_dispatch_table_initializer (method_list_template,
- chain, &size);
+ method_list_template = build_method_list_template (objc_method_template, size);
+ initlist = build_dispatch_table_initializer (objc_method_template, chain);
UOBJC_CLASS_METHODS_decl
= generate_dispatch_table (method_list_template,
chain = CLASS_NST_METHODS (implementation_context);
if (chain)
{
- size = 0;
+ size = list_length (chain);
+
+ method_list_template = build_method_list_template (objc_method_template, size);
+ initlist = build_dispatch_table_initializer (objc_method_template, chain);
- method_list_template = build_method_list_template (objc_method_template,
- size);
- initlist = build_dispatch_table_initializer (method_list_template,
- chain, &size);
if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
UOBJC_INSTANCE_METHODS_decl
= generate_dispatch_table (method_list_template,
+ (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
/ BITS_PER_UNIT));
- if (parm_end > max_parm_end)
+ if (!offset_is_register && parm_end > max_parm_end)
max_parm_end = parm_end;
}
/* compute offset */
sprintf (buffer, "%d", forwarding_offset (parms));
+
+ /* indicate register */
+ if (offset_is_register)
+ obstack_1grow (&util_obstack, '+');
+
obstack_grow (&util_obstack, buffer, strlen (buffer));
}