/* Implement classes and message passing for Objective C.
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
Contributed by Steve Naroff.
This file is part of GNU CC.
#include "flags.h"
#include "objc-act.h"
#include "input.h"
+#include "except.h"
#include "function.h"
char *util_firstobj;
/* List of classes with list of their static instances. */
-static tree objc_static_instances;
+static tree objc_static_instances = NULL_TREE;
/* The declaration of the array administrating the static instances. */
-static tree static_instances_decl;
+static tree static_instances_decl = NULL_TREE;
/* for encode_method_def */
#include "rtl.h"
#include "c-parse.h"
-#define OBJC_VERSION (flag_next_runtime ? 5 : 7)
+#define OBJC_VERSION (flag_next_runtime ? 5 : 8)
#define PROTOCOL_VERSION 2
#define OBJC_ENCODE_INLINE_DEFS 0
/* void *defs[cls_def_cnt + cat_def_cnt]; */
- index = build_index_type (build_int_2 (imp_count + cat_count - 1,
- imp_count == 0 && cat_count == 0
- ? -1 : 0));
+ if (!flag_next_runtime)
+ index = build_index_type (build_int_2 (imp_count + cat_count, 0));
+ else
+ index = build_index_type (build_int_2 (imp_count + cat_count - 1,
+ imp_count == 0 && cat_count == 0
+ ? -1 : 0));
field_decl = create_builtin_decl (FIELD_DECL,
build_array_type (ptr_type_node, index),
"defs");
}
}
+ if (!flag_next_runtime)
+ {
+ /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
+ tree expr;
+
+ if (static_instances_decl)
+ expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+ else
+ expr = build_int_2 (0, 0);
+
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
return build_constructor (type, nreverse (initlist));
}
/* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
- if (imp_count || cat_count)
+ if (imp_count || cat_count || static_instances_decl)
{
+
tree field = TYPE_FIELDS (type);
field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
expr = add_objc_string (get_identifier (input_filename), class_names);
initlist = tree_cons (NULL_TREE, expr, initlist);
-
- if (!flag_next_runtime)
- {
- /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
- if (static_instances_decl)
- expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
- else
- expr = build_int_2 (0, 0);
- initlist = tree_cons (NULL_TREE, expr, initlist);
- }
-
/* symtab = { ..., _OBJC_SYMBOLS, ... } */
if (UOBJC_SYMBOLS_decl)
= grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
-
- if (!flag_next_runtime)
- {
- /* void *statics */
-
- decl_specs = get_identifier (UTAG_STATICS);
- decl_specs
- = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
- field_decl
- = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("statics"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
- chainon (field_decl_chain, field_decl);
- }
-
-
/* struct objc_symtab *symtab; */
decl_specs = get_identifier (UTAG_SYMTAB);
ridpointers[(int) RID_STATIC]));
static_instances_decl
= start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+ TREE_USED (static_instances_decl) = 1;
DECL_CONTEXT (static_instances_decl) = 0;
DECL_ARTIFICIAL (static_instances_decl) = 1;
end_temporary_allocation ();
}
\f
static void
-encode_aggregate (type, curtype, format)
+encode_aggregate_within (type, curtype, format, left, right)
tree type;
int curtype;
int format;
+ char left;
+ char right;
{
- enum tree_code code = TREE_CODE (type);
-
- switch (code)
+ if (obstack_object_size (&util_obstack) > 0
+ && *(obstack_next_free (&util_obstack) - 1) == '^')
{
- case RECORD_TYPE:
- {
- if (obstack_object_size (&util_obstack) > 0
- && *(obstack_next_free (&util_obstack) - 1) == '^')
- {
- tree name = TYPE_NAME (type);
+ tree name = TYPE_NAME (type);
- /* We have a reference; this is a NeXT extension. */
+ /* we have a reference; this is a NeXT extension. */
- if (obstack_object_size (&util_obstack) - curtype == 1
- && format == OBJC_ENCODE_INLINE_DEFS)
- {
- /* Output format of struct for first level only. */
- tree fields = TYPE_FIELDS (type);
+ if (obstack_object_size (&util_obstack) - curtype == 1
+ && format == OBJC_ENCODE_INLINE_DEFS)
+ {
+ /* Output format of struct for first level only. */
+ tree fields = TYPE_FIELDS (type);
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- {
- obstack_1grow (&util_obstack, '{');
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- obstack_1grow (&util_obstack, '=');
- }
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ obstack_1grow (&util_obstack, '=');
+ }
+ else
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack, "?=", 2);
+ }
- else
- obstack_grow (&util_obstack, "{?=", 3);
+ for ( ; fields; fields = TREE_CHAIN (fields))
+ encode_field_decl (fields, curtype, format);
- for ( ; fields; fields = TREE_CHAIN (fields))
- encode_field_decl (fields, curtype, format);
+ obstack_1grow (&util_obstack, right);
+ }
- obstack_1grow (&util_obstack, '}');
- }
+ else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ obstack_1grow (&util_obstack, right);
+ }
- else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- {
- obstack_1grow (&util_obstack, '{');
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- obstack_1grow (&util_obstack, '}');
- }
+ else
+ {
+ /* We have an untagged structure or a typedef. */
+ obstack_1grow (&util_obstack, left);
+ obstack_1grow (&util_obstack, '?');
+ obstack_1grow (&util_obstack, right);
+ }
+ }
- else
- /* We have an untagged structure or a typedef. */
- obstack_grow (&util_obstack, "{?}", 3);
- }
+ else
+ {
+ tree name = TYPE_NAME (type);
+ tree fields = TYPE_FIELDS (type);
- else
- {
- tree name = TYPE_NAME (type);
- tree fields = TYPE_FIELDS (type);
+ if (format == OBJC_ENCODE_INLINE_DEFS
+ || generating_instance_variables)
+ {
+ obstack_1grow (&util_obstack, left);
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ else
+ obstack_1grow (&util_obstack, '?');
- if (format == OBJC_ENCODE_INLINE_DEFS
- || generating_instance_variables)
- {
- obstack_1grow (&util_obstack, '{');
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
+ obstack_1grow (&util_obstack, '=');
- else
- obstack_1grow (&util_obstack, '?');
+ for (; fields; fields = TREE_CHAIN (fields))
+ {
+ if (generating_instance_variables)
+ {
+ tree fname = DECL_NAME (fields);
- obstack_1grow (&util_obstack, '=');
+ obstack_1grow (&util_obstack, '"');
+ if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
+ {
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (fname),
+ strlen (IDENTIFIER_POINTER (fname)));
+ }
- for (; fields; fields = TREE_CHAIN (fields))
- {
- if (generating_instance_variables)
- {
- tree fname = DECL_NAME (fields);
-
- obstack_1grow (&util_obstack, '"');
- if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
- {
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (fname),
- strlen (IDENTIFIER_POINTER (fname)));
- }
+ obstack_1grow (&util_obstack, '"');
+ }
- obstack_1grow (&util_obstack, '"');
- }
+ encode_field_decl (fields, curtype, format);
+ }
- encode_field_decl (fields, curtype, format);
- }
+ obstack_1grow (&util_obstack, right);
+ }
- obstack_1grow (&util_obstack, '}');
- }
+ else
+ {
+ obstack_1grow (&util_obstack, left);
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ else
+ /* We have an untagged structure or a typedef. */
+ obstack_1grow (&util_obstack, '?');
- else
- {
- obstack_1grow (&util_obstack, '{');
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- else
- /* We have an untagged structure or a typedef. */
- obstack_1grow (&util_obstack, '?');
-
- obstack_1grow (&util_obstack, '}');
- }
- }
+ obstack_1grow (&util_obstack, right);
+ }
+ }
+}
+
+static void
+encode_aggregate (type, curtype, format)
+ tree type;
+ int curtype;
+ int format;
+{
+ enum tree_code code = TREE_CODE (type);
+
+ switch (code)
+ {
+ case RECORD_TYPE:
+ {
+ encode_aggregate_within(type, curtype, format, '{', '}');
break;
}
-
case UNION_TYPE:
{
- if (*obstack_next_free (&util_obstack) == '^'
- || format != OBJC_ENCODE_INLINE_DEFS)
- {
- /* We have a reference (this is a NeXT extension)
- or we don't want the details. */
- if (TYPE_NAME (type)
- && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- {
- obstack_1grow (&util_obstack, '(');
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (TYPE_NAME (type)),
- strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
- obstack_1grow (&util_obstack, ')');
- }
-
- else
- /* We have an untagged structure or a typedef. */
- obstack_grow (&util_obstack, "(?)", 3);
- }
- else
- {
- tree fields = TYPE_FIELDS (type);
- obstack_1grow (&util_obstack, '(');
- for ( ; fields; fields = TREE_CHAIN (fields))
- encode_field_decl (fields, curtype, format);
-
- obstack_1grow (&util_obstack, ')');
- }
+ encode_aggregate_within(type, curtype, format, '(', ')');
break;
}
OBJC_PROLOGUE;
#endif
+ /* Process the static instances here because initialization of objc_symtab
+ dependens on them. */
+ if (objc_static_instances)
+ generate_static_references ();
+
if (implementation_context || class_names_chain
|| meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
generate_objc_symtab_decl ();
if (protocol_chain)
generate_protocols ();
- if (objc_static_instances)
- generate_static_references ();
-
if (implementation_context || class_names_chain || objc_static_instances
|| meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
{