/* Implement classes and message passing for Objective C.
Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
Contributed by Steve Naroff.
This file is part of GCC.
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "rtl.h"
-#include "tm_p.h"
-#include "expr.h"
#ifdef OBJCPLUS
#include "cp-tree.h"
#include "langhooks.h"
#include "objc-act.h"
#include "input.h"
-#include "except.h"
+#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
#include "function.h"
#include "output.h"
#include "toplev.h"
#include "ggc.h"
-#include "varray.h"
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
#include "intl.h"
#include "cgraph.h"
#include "tree-iterator.h"
-#include "libfuncs.h"
#include "hashtab.h"
#include "langhooks-def.h"
+/* For enum gimplify_status */
+#include "gimple.h"
+
#define OBJC_VOID_AT_END void_list_node
static unsigned int should_call_super_dealloc = 0;
/* Code generation. */
-static tree objc_build_constructor (tree, tree);
+static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
static tree get_proto_encoding (tree);
static tree lookup_interface (tree);
structure-returning methods. */
default_constant_string_class_name = "NXConstantString";
flag_typed_selectors = 1;
+ /* GNU runtime does not need the compiler to change code
+ in order to do GC. */
+ if (flag_objc_gc)
+ {
+ warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
+ flag_objc_gc=0;
+ }
}
init_objc ();
finish_struct(), and then reinstate it afterwards. */
for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
- objc_info
- = chainon (objc_info,
- build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
+ {
+ if (!TYPE_HAS_OBJC_INFO (t))
+ {
+ INIT_TYPE_OBJC_INFO (t);
+ TYPE_OBJC_INTERFACE (t) = klass;
+ }
+ objc_info
+ = chainon (objc_info,
+ build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
+ }
/* Point the struct at its related Objective-C class. */
INIT_TYPE_OBJC_INFO (s);
mark_decl_referenced (var);
/* Mark the decl to avoid "defined but not used" warning. */
TREE_USED (var) = 1;
+ DECL_READ_P (var) = 1;
+ /* We reserve the right for the runtime to use/modify these variables
+ in ways that are opaque to us. */
+ DECL_PRESERVE_P (var) = 1;
}
/* Find the decl for the constant string class reference. This is only
tree
objc_build_string_object (tree string)
{
- tree initlist, constructor, constant_string_class;
+ tree constructor, constant_string_class;
int length;
tree fields, addr;
struct string_descriptor *desc, key;
if (!desc)
{
tree var;
+ VEC(constructor_elt,gc) *v = NULL;
*loc = desc = GGC_NEW (struct string_descriptor);
desc->literal = string;
/* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
/* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
fields = TYPE_FIELDS (internal_const_str_type);
- initlist
- = build_tree_list (fields,
- flag_next_runtime
- ? build_unary_op (input_location,
- ADDR_EXPR, string_class_decl, 0)
- : build_int_cst (NULL_TREE, 0));
+ CONSTRUCTOR_APPEND_ELT (v, fields,
+ flag_next_runtime
+ ? build_unary_op (input_location,
+ ADDR_EXPR, string_class_decl, 0)
+ : build_int_cst (NULL_TREE, 0));
fields = TREE_CHAIN (fields);
- initlist = tree_cons (fields, build_unary_op (input_location,
- ADDR_EXPR, string, 1),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (v, fields,
+ build_unary_op (input_location,
+ ADDR_EXPR, string, 1));
fields = TREE_CHAIN (fields);
- initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
- initlist);
- constructor = objc_build_constructor (internal_const_str_type,
- nreverse (initlist));
+ CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
+ constructor = objc_build_constructor (internal_const_str_type, v);
if (!flag_next_runtime)
constructor
sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
decl = build_decl (input_location,
VAR_DECL, get_identifier (buf), class_decl);
- DECL_COMMON (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
TREE_USED (decl) = 1;
with type TYPE and elements ELTS. */
static tree
-objc_build_constructor (tree type, tree elts)
+objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
{
- tree constructor = build_constructor_from_list (type, elts);
+ tree constructor = build_constructor (type, elts);
TREE_CONSTANT (constructor) = 1;
TREE_STATIC (constructor) = 1;
#ifdef OBJCPLUS
/* Adjust for impedance mismatch. We should figure out how to build
CONSTRUCTORs that consistently please both the C and C++ gods. */
- if (!TREE_PURPOSE (elts))
+ if (!VEC_index (constructor_elt, elts, 0)->index)
TREE_TYPE (constructor) = init_list_type_node;
#endif
static tree
init_def_list (tree type)
{
- tree expr, initlist = NULL_TREE;
+ tree expr;
struct imp_entry *impent;
+ VEC(constructor_elt,gc) *v = NULL;
if (imp_count)
for (impent = imp_list; impent; impent = impent->next)
{
expr = build_unary_op (input_location,
ADDR_EXPR, impent->class_decl, 0);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
}
{
expr = build_unary_op (input_location,
ADDR_EXPR, impent->class_decl, 0);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
}
if (!flag_next_runtime)
{
/* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
- tree expr;
-
if (static_instances_decl)
expr = build_unary_op (input_location,
ADDR_EXPR, static_instances_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, v);
}
/* Construct the initial value for all of _objc_symtab. */
static tree
init_objc_symtab (tree type)
{
- tree initlist;
+ VEC(constructor_elt,gc) *v = NULL;
/* sel_ref_cnt = { ..., 5, ... } */
- initlist = build_tree_list (NULL_TREE,
- build_int_cst (long_integer_type_node, 0));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ build_int_cst (long_integer_type_node, 0));
/* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
if (flag_next_runtime || ! sel_ref_chain)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
- initlist
- = tree_cons (NULL_TREE,
- convert (build_pointer_type (objc_selector_type),
- build_unary_op (input_location, ADDR_EXPR,
- UOBJC_SELECTOR_TABLE_decl, 1)),
- initlist);
+ {
+ tree expr = build_unary_op (input_location, ADDR_EXPR,
+ UOBJC_SELECTOR_TABLE_decl, 1);
+
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ convert (build_pointer_type (objc_selector_type),
+ expr));
+ }
/* cls_def_cnt = { ..., 5, ... } */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, imp_count));
/* cat_def_cnt = { ..., 5, ... } */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, cat_count));
/* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
tree field = TYPE_FIELDS (type);
field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
- initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
}
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, v);
}
/* Generate forward declarations for metadata such as
static tree
init_module_descriptor (tree type)
{
- tree initlist, expr;
+ tree expr;
+ VEC(constructor_elt,gc) *v = NULL;
/* version = { 1, ... } */
expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
- initlist = build_tree_list (NULL_TREE, expr);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
/* size = { ..., sizeof (struct _objc_module), ... } */
expr = convert (long_integer_type_node,
size_in_bytes (objc_module_template));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
/* Don't provide any file name for security reasons. */
/* name = { ..., "", ... } */
expr = add_objc_string (get_identifier (""), class_names);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
/* symtab = { ..., _OBJC_SYMBOLS, ... } */
ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, v);
}
/* Write out the data structures to describe Objective C classes defined.
objc_push_parm (build_decl (input_location,
PARM_DECL, NULL_TREE, void_type_node));
+#ifdef OBJCPLUS
+ objc_start_function (get_identifier (TAG_GNUINIT),
+ build_function_type (void_type_node,
+ OBJC_VOID_AT_END),
+ NULL_TREE, NULL_TREE);
+#else
objc_start_function (get_identifier (TAG_GNUINIT),
build_function_type (void_type_node,
OBJC_VOID_AT_END),
NULL_TREE, objc_get_parm_info (0));
-
+#endif
body = c_begin_compound_stmt (true);
add_stmt (build_function_call
(input_location,
static void
generate_static_references (void)
{
- tree decls = NULL_TREE, expr = NULL_TREE;
- tree class_name, klass, decl, initlist;
+ tree expr = NULL_TREE;
+ tree class_name, klass, decl;
tree cl_chain, in_chain, type
= build_array_type (build_pointer_type (void_type_node), NULL_TREE);
int num_inst, num_class;
char buf[256];
+ VEC(constructor_elt,gc) *decls = NULL;
if (flag_next_runtime)
abort ();
for (cl_chain = objc_static_instances, num_class = 0;
cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
{
+ VEC(constructor_elt,gc) *v = NULL;
+
for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
/* Output {class_name, ...}. */
klass = TREE_VALUE (cl_chain);
class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
- initlist = build_tree_list (NULL_TREE,
- build_unary_op (input_location,
- ADDR_EXPR, class_name, 1));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ build_unary_op (input_location,
+ ADDR_EXPR, class_name, 1));
/* Output {..., instance, ...}. */
for (in_chain = TREE_PURPOSE (cl_chain);
{
expr = build_unary_op (input_location,
ADDR_EXPR, TREE_VALUE (in_chain), 1);
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
/* Output {..., NULL}. */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
- expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
+ expr = objc_build_constructor (TREE_TYPE (decl), v);
finish_var_decl (decl, expr);
- decls
- = tree_cons (NULL_TREE, build_unary_op (input_location,
- ADDR_EXPR, decl, 1), decls);
+ CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
+ build_unary_op (input_location,
+ ADDR_EXPR, decl, 1));
}
- decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
- expr = objc_build_constructor (type, nreverse (decls));
+ CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ expr = objc_build_constructor (type, decls);
static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
finish_var_decl (static_instances_decl, expr);
}
static void
build_selector_translation_table (void)
{
- tree chain, initlist = NULL_TREE;
+ tree chain;
int offset = 0;
tree decl = NULL_TREE;
+ VEC(constructor_elt,gc) *inits = NULL;
for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
{
{
if (flag_typed_selectors)
{
- tree eltlist = NULL_TREE;
+ VEC(constructor_elt,gc) *v = NULL;
tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
- eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
- eltlist = tree_cons (NULL_TREE, encoding, eltlist);
- expr = objc_build_constructor (objc_selector_template,
- nreverse (eltlist));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
+ expr = objc_build_constructor (objc_selector_template, v);
}
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
}
}
if (! flag_next_runtime)
{
/* Cause the selector table (previously forward-declared)
- to be actually output. */
- initlist = tree_cons (NULL_TREE,
- flag_typed_selectors
- ? objc_build_constructor
- (objc_selector_template,
- tree_cons (NULL_TREE,
- build_int_cst (NULL_TREE, 0),
- tree_cons (NULL_TREE,
- build_int_cst (NULL_TREE, 0),
- NULL_TREE)))
- : build_int_cst (NULL_TREE, 0), initlist);
- initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
- nreverse (initlist));
- finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
+ to be actually output. */
+ tree expr;
+
+ if (flag_typed_selectors)
+ {
+ VEC(constructor_elt,gc) *v = NULL;
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ expr = objc_build_constructor (objc_selector_template, v);
+ }
+ else
+ expr = build_int_cst (NULL_TREE, 0);
+
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+ expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
+ inits);
+ finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
}
}
return build_indirect_ref (input_location,
objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
- newexpr), "->");
+ newexpr), RO_ARROW);
default:
return expr;
}
/* The CATCH_EXPR of an open @catch clause. */
tree current_catch;
- /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
+ /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
tree caught_decl;
tree stack_decl;
tree rethrow_decl;
}
#endif
-/* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
- we'll arrange for it to be initialized (and associated with a binding)
- later. */
+/* Build __builtin_eh_pointer, or the moral equivalent. In the case
+ of Darwin, we'll arrange for it to be initialized (and associated
+ with a binding) later. */
static tree
objc_build_exc_ptr (void)
return var;
}
else
- return build0 (EXC_PTR_EXPR, objc_object_type);
+ {
+ tree t;
+ t = built_in_decls[BUILT_IN_EH_POINTER];
+ t = build_call_expr (t, 1, integer_zero_node);
+ return fold_convert (objc_object_type, t);
+ }
}
/* Build "objc_exception_try_exit(&_stack)". */
/* ??? As opposed to __attribute__((unused))? Anyway, this appears to
be what the previous objc implementation did. */
TREE_USED (decl) = 1;
+ DECL_READ_P (decl) = 1;
/* Verify that the type of the catch is valid. It must be a pointer
to an Objective-C class, or "id" (which is catch-all). */
static tree
build_descriptor_table_initializer (tree type, tree entries)
{
- tree initlist = NULL_TREE;
+ VEC(constructor_elt,gc) *inits = NULL;
do
{
- tree eltlist = NULL_TREE;
+ VEC(constructor_elt,gc) *elts = NULL;
- eltlist
- = tree_cons (NULL_TREE,
- build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
- eltlist
- = tree_cons (NULL_TREE,
- add_objc_string (METHOD_ENCODING (entries),
- meth_var_types),
- eltlist);
+ CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
+ build_selector (METHOD_SEL_NAME (entries)));
+ CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
+ add_objc_string (METHOD_ENCODING (entries),
+ meth_var_types));
- initlist
- = tree_cons (NULL_TREE,
- objc_build_constructor (type, nreverse (eltlist)),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
+ objc_build_constructor (type, elts));
entries = TREE_CHAIN (entries);
}
while (entries);
- return objc_build_constructor (build_array_type (type, 0),
- nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0), inits);
}
/* struct objc_method_prototype_list {
generate_descriptor_table (tree type, const char *name, int size, tree list,
tree proto)
{
- tree decl, initlist;
+ tree decl;
+ VEC(constructor_elt,gc) *v = NULL;
decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
- initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
- initlist = tree_cons (NULL_TREE, list, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
- finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
+ finish_var_decl (decl, objc_build_constructor (type, v));
return decl;
}
tree protocol_list, tree instance_methods,
tree class_methods)
{
- tree initlist = NULL_TREE, expr;
+ tree expr;
tree cast_type = build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier (UTAG_CLASS)));
+ VEC(constructor_elt,gc) *inits = NULL;
/* Filling the "isa" in with one allows the runtime system to
detect that the version change...should remove before final release. */
expr = build_int_cst (cast_type, PROTOCOL_VERSION);
- initlist = tree_cons (NULL_TREE, expr, initlist);
- initlist = tree_cons (NULL_TREE, protocol_name, initlist);
- initlist = tree_cons (NULL_TREE, protocol_list, initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
if (!instance_methods)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_method_proto_list_ptr,
build_unary_op (input_location,
ADDR_EXPR, instance_methods, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
}
if (!class_methods)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_method_proto_list_ptr,
build_unary_op (input_location,
ADDR_EXPR, class_methods, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
}
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, inits);
}
\f
/* struct _objc_category {
static tree
build_ivar_list_initializer (tree type, tree field_decl)
{
- tree initlist = NULL_TREE;
+ VEC(constructor_elt,gc) *inits = NULL;
do
{
- tree ivar = NULL_TREE;
+ VEC(constructor_elt,gc) *ivar = NULL;
+ tree id;
/* Set name. */
if (DECL_NAME (field_decl))
- ivar = tree_cons (NULL_TREE,
- add_objc_string (DECL_NAME (field_decl),
- meth_var_names),
- ivar);
+ CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
+ add_objc_string (DECL_NAME (field_decl),
+ meth_var_names));
else
/* Unnamed bit-field ivar (yuck). */
- ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
+ CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* Set type. */
encode_field_decl (field_decl,
/* Null terminate string. */
obstack_1grow (&util_obstack, 0);
- ivar
- = tree_cons
- (NULL_TREE,
- add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
- meth_var_types),
- ivar);
+ id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
+ meth_var_types);
+ CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
obstack_free (&util_obstack, util_firstobj);
/* Set offset. */
- ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
- initlist = tree_cons (NULL_TREE,
- objc_build_constructor (type, nreverse (ivar)),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
+ objc_build_constructor (type, ivar));
do
field_decl = TREE_CHAIN (field_decl);
while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
}
while (field_decl);
- return objc_build_constructor (build_array_type (type, 0),
- nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0), inits);
}
static tree
generate_ivars_list (tree type, const char *name, int size, tree list)
{
- tree decl, initlist;
+ tree decl;
+ VEC(constructor_elt,gc) *inits = NULL;
decl = start_var_decl (type, synth_id_with_class_suffix
(name, objc_implementation_context));
- initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
- initlist = tree_cons (NULL_TREE, list, initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
finish_var_decl (decl,
- objc_build_constructor (TREE_TYPE (decl),
- nreverse (initlist)));
+ objc_build_constructor (TREE_TYPE (decl), inits));
return decl;
}
static tree
build_dispatch_table_initializer (tree type, tree entries)
{
- tree initlist = NULL_TREE;
+ VEC(constructor_elt,gc) *inits = NULL;
do
{
- tree elemlist = NULL_TREE;
+ VEC(constructor_elt,gc) *elems = NULL;
+ tree expr;
- elemlist = tree_cons (NULL_TREE,
- build_selector (METHOD_SEL_NAME (entries)),
- NULL_TREE);
+ CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
+ build_selector (METHOD_SEL_NAME (entries)));
/* Generate the method encoding if we don't have one already. */
if (! METHOD_ENCODING (entries))
METHOD_ENCODING (entries) =
encode_method_prototype (entries);
- elemlist = tree_cons (NULL_TREE,
- add_objc_string (METHOD_ENCODING (entries),
- meth_var_types),
- elemlist);
+ CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
+ add_objc_string (METHOD_ENCODING (entries),
+ meth_var_types));
- elemlist
- = tree_cons (NULL_TREE,
- convert (ptr_type_node,
- build_unary_op (input_location, ADDR_EXPR,
- METHOD_DEFINITION (entries), 1)),
- elemlist);
+ expr = convert (ptr_type_node,
+ build_unary_op (input_location, ADDR_EXPR,
+ METHOD_DEFINITION (entries), 1));
+ CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
- initlist = tree_cons (NULL_TREE,
- objc_build_constructor (type, nreverse (elemlist)),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
+ objc_build_constructor (type, elems));
entries = TREE_CHAIN (entries);
}
while (entries);
- return objc_build_constructor (build_array_type (type, 0),
- nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0), inits);
}
/* To accomplish method prototyping without generating all kinds of
static tree
generate_dispatch_table (tree type, const char *name, int size, tree list)
{
- tree decl, initlist;
+ tree decl;
+ VEC(constructor_elt,gc) *v = NULL;
decl = start_var_decl (type, synth_id_with_class_suffix
(name, objc_implementation_context));
- initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
- initlist = tree_cons (NULL_TREE, list, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
finish_var_decl (decl,
- objc_build_constructor (TREE_TYPE (decl),
- nreverse (initlist)));
+ objc_build_constructor (TREE_TYPE (decl), v));
return decl;
}
static tree
generate_protocol_list (tree i_or_p)
{
- tree initlist;
tree refs_decl, lproto, e, plist;
int size = 0;
const char *ref_name;
+ VEC(constructor_elt,gc) *v = NULL;
if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
|| TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
size++;
/* Build initializer. */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
e = build_int_cst (build_pointer_type (objc_protocol_template), size);
- initlist = tree_cons (NULL_TREE, e, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
{
{
e = build_unary_op (input_location, ADDR_EXPR,
PROTOCOL_FORWARD_DECL (pval), 0);
- initlist = tree_cons (NULL_TREE, e, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
}
}
build_index_type (build_int_cst (NULL_TREE, size + 2))),
ref_name);
- finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
- nreverse (initlist)));
+ finish_var_decl (refs_decl,
+ objc_build_constructor (TREE_TYPE (refs_decl), v));
return refs_decl;
}
tree instance_methods, tree class_methods,
tree protocol_list)
{
- tree initlist = NULL_TREE, expr;
+ tree expr;
+ VEC(constructor_elt,gc) *v = NULL;
- initlist = tree_cons (NULL_TREE, cat_name, initlist);
- initlist = tree_cons (NULL_TREE, class_name, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
if (!instance_methods)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_method_list_ptr,
build_unary_op (input_location, ADDR_EXPR,
instance_methods, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
if (!class_methods)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_method_list_ptr,
build_unary_op (input_location, ADDR_EXPR,
class_methods, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
/* protocol_list = */
if (!protocol_list)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (build_pointer_type
(objc_protocol_template)),
build_unary_op (input_location, ADDR_EXPR,
protocol_list, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, v);
}
/* struct _objc_class {
tree dispatch_table, tree ivar_list,
tree protocol_list)
{
- tree initlist = NULL_TREE, expr;
+ tree expr;
+ VEC(constructor_elt,gc) *v = NULL;
/* isa = */
- initlist = tree_cons (NULL_TREE, isa, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
/* super_class = */
- initlist = tree_cons (NULL_TREE, super, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
/* name = */
- initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
/* version = */
- initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ build_int_cst (long_integer_type_node, 0));
/* info = */
- initlist = tree_cons (NULL_TREE,
- build_int_cst (long_integer_type_node, status),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ build_int_cst (long_integer_type_node, status));
/* instance_size = */
- initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
- initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ convert (long_integer_type_node, size));
/* objc_ivar_list = */
if (!ivar_list)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_ivar_list_ptr,
build_unary_op (input_location, ADDR_EXPR,
ivar_list, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
/* objc_method_list = */
if (!dispatch_table)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (objc_method_list_ptr,
build_unary_op (input_location, ADDR_EXPR,
dispatch_table, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
if (flag_next_runtime)
/* method_cache = */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
/* dtable = */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* subclass_list = */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* sibling_class = */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
}
/* protocol_list = */
if (! protocol_list)
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
else
{
expr = convert (build_pointer_type
(objc_protocol_template)),
build_unary_op (input_location, ADDR_EXPR,
protocol_list, 0));
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
}
if (flag_next_runtime)
/* sel_id = NULL */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* gc_object_type = NULL */
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
- return objc_build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, v);
}
/* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
static void
generate_shared_structures (int cls_flags)
{
- tree sc_spec, decl_specs, decl;
+ tree decl;
tree name_expr, super_expr, root_expr;
tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
tree cast_type, initlist, protocol_decl;
/* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
- sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
- decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
-
decl = start_var_decl (objc_class_template,
IDENTIFIER_POINTER
(DECL_NAME (UOBJC_METACLASS_decl)));
objc_build_message_expr (tree mess)
{
tree receiver = TREE_PURPOSE (mess);
- location_t loc;
tree sel_name;
#ifdef OBJCPLUS
tree args = TREE_PURPOSE (TREE_VALUE (mess));
if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
return error_mark_node;
- if (CAN_HAVE_LOCATION_P (receiver))
- loc = EXPR_LOCATION (receiver);
- else
- loc = input_location;
-
/* Obtain the full selector name. */
if (TREE_CODE (args) == IDENTIFIER_NODE)
/* A unary selector. */
}
else if (rtype)
{
- tree orig_rtype = rtype, saved_rtype;
+ tree orig_rtype = rtype;
if (TREE_CODE (rtype) == POINTER_TYPE)
rtype = TREE_TYPE (rtype);
&& TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
- saved_rtype = rtype;
if (TYPED_OBJECT (rtype))
{
rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
}
return objc_build_component_ref (build_indirect_ref (input_location,
- self_decl, "->"), id);
+ self_decl, RO_ARROW),
+ id);
}
\f
/* Compute a hash value for a given method SEL_NAME. */
/* Encode the struct/union tag name, or '?' if a tag was
not provided. Typedef aliases do not qualify. */
- if (name && TREE_CODE (name) == IDENTIFIER_NODE
#ifdef OBJCPLUS
+ /* For compatibility with the NeXT runtime, ObjC++ encodes template
+ args as a composite struct tag name. */
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE
/* Did this struct have a tag? */
- && !TYPE_WAS_ANONYMOUS (type)
-#endif
- )
+ && !TYPE_WAS_ANONYMOUS (type))
+ obstack_grow (&util_obstack,
+ decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
+ strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
+#else
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
obstack_grow (&util_obstack,
IDENTIFIER_POINTER (name),
strlen (IDENTIFIER_POINTER (name)));
+#endif
else
obstack_1grow (&util_obstack, '?');
static void
encode_field_decl (tree field_decl, int curtype, int format)
{
- tree type;
-
#ifdef OBJCPLUS
/* C++ static members, and things that are not fields at all,
should not appear in the encoding. */
return;
#endif
- type = TREE_TYPE (field_decl);
-
/* Generate the bitfield typing information, if needed. Note the difference
between GNU and NeXT runtimes. */
if (DECL_BIT_FIELD_TYPE (field_decl))
/* Suppress unused warnings. */
TREE_USED (self_decl) = 1;
+ DECL_READ_P (self_decl) = 1;
TREE_USED (TREE_CHAIN (self_decl)) = 1;
+ DECL_READ_P (TREE_CHAIN (self_decl)) = 1;
#ifdef OBJCPLUS
pop_lang_context ();
#endif
objc_super_template);
/* This prevents `unused variable' warnings when compiling with -Wall. */
TREE_USED (UOBJC_SUPER_decl) = 1;
+ DECL_READ_P (UOBJC_SUPER_decl) = 1;
lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
NULL_TREE);
(input_location,
build_c_cast (input_location,
build_pointer_type (objc_class_type),
- super_class), "unary *");
+ super_class), RO_UNARY_STAR);
}
else
{
DECL_INITIAL (decl) = exp;
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
+ DECL_READ_P (decl) = 1;
/* Force the output of the decl as this forces the reference of the class. */
mark_decl_referenced (decl);
static void
generate_objc_image_info (void)
{
- tree decl, initlist;
+ tree decl;
int flags
= ((flag_replace_objc_classes && imp_list ? 1 : 0)
| (flag_objc_gc ? 2 : 0));
+ VEC(constructor_elt,gc) *v = NULL;
decl = start_var_decl (build_array_type
(integer_type_node,
build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
"_OBJC_IMAGE_INFO");
- initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
- initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
- initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
- finish_var_decl (decl, initlist);
+ finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
}
/* Look up ID as an instance variable. OTHER contains the result of