aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKresten Krab Thorup <krab@gcc.gnu.org>1993-08-24 09:56:48 +0000
committerKresten Krab Thorup <krab@gcc.gnu.org>1993-08-24 09:56:48 +0000
commit30c0e2df8c68f8cda6d51c71ed945cd151ead94d (patch)
tree60089e5f77cad5996c41c4f95b545f7628eebdf7
parentfb2ca25a9d578674144a76548fc4f90187a5ca03 (diff)
downloadgcc-30c0e2df8c68f8cda6d51c71ed945cd151ead94d.zip
gcc-30c0e2df8c68f8cda6d51c71ed945cd151ead94d.tar.gz
gcc-30c0e2df8c68f8cda6d51c71ed945cd151ead94d.tar.bz2
(offset_is_register): New variable
(offset_is_register): New variable (forwarding_offset): Use apply_args_register_offset to get register offset. (encode_method_def, encode_method_prototype): Prepend argument offset by '+' if passed in register. (apply_args_register_offset): Added declaration. (generate_method_descriptors, generate_ivar_lists, generate_dispatch_tables): Reorganized use of constructors. (build_descriptor_table_initializer, build_ivar_list_initializer, build_dispatch_table_initializer): Removed argument `int *size'. From-SVN: r5199
-rw-r--r--gcc/objc/objc-act.c154
1 files changed, 86 insertions, 68 deletions
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 72b859b..7db3d88 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -174,6 +174,9 @@ static tree init_selector PROTO((int));
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;
@@ -265,7 +268,7 @@ static tree build_class_reference_decl PROTO((tree));
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));
@@ -279,9 +282,9 @@ static void generate_protocols PROTO((void));
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));
@@ -2218,25 +2221,26 @@ build_protocol_template ()
}
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 {
@@ -2314,6 +2318,9 @@ build_method_prototype_template ()
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;
@@ -2335,16 +2342,14 @@ forwarding_offset (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;
@@ -2391,7 +2396,7 @@ encode_method_prototype (method_decl, func_decl)
+ (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;
}
@@ -2420,6 +2425,11 @@ encode_method_prototype (method_decl, func_decl)
/* 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));
}
@@ -2474,17 +2484,15 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */
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,
@@ -2499,16 +2507,14 @@ generate_method_descriptors (protocol) /* generate_dispatch_tables */
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,
@@ -3218,52 +3224,57 @@ build_method_list_template (list_type, size)
}
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
@@ -3317,10 +3328,10 @@ generate_ivar_lists ()
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",
@@ -3334,10 +3345,9 @@ generate_ivar_lists ()
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",
@@ -3352,39 +3362,45 @@ generate_ivar_lists ()
}
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 ()
@@ -3476,12 +3492,10 @@ generate_dispatch_tables ()
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,
@@ -3499,12 +3513,11 @@ generate_dispatch_tables ()
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,
@@ -6598,7 +6611,7 @@ encode_method_def (func_decl)
+ (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;
}
@@ -6618,6 +6631,11 @@ encode_method_def (func_decl)
/* 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));
}