Commit 38b9c8c3 by Ziemowit Laski Committed by Mike Stump

Yet more Objective-C++...

        * objc-act.c (objc_finish_try_stmt): Add return value.
        (objc_build_synchronized): Likewise.

        * objc-act.c (objc_is_gcable_type): Add.
        (objc_substitute_decl): Add.
        (objc_build_ivar_assignment): Add.
        (objc_build_global_assignment): Add.
        (objc_build_strong_cast_assignment): Add.
        (objc_is_ivar_reference_p): Add.
        (objc_is_global_reference_p): Add.
        (objc_generate_write_barrier): Add.
        (objc_rewrite_function_call): Add.
        (objc_gimplify_expr): Add Objective-C++ support.
        * objc-act.h (ALLOC_OBJC_TYPE_LANG_SPECIFIC): Likewise.
        (SIZEOF_OBJC_TYPE_LANG_SPECIFIC): Add.
        (INIT_TYPE_OBJC_INFO): Add Objective-C++ support.
        (DUP_TYPE_OBJC_INFO): Likewise.
        (struct imp_entry): Add field has_cxx_cdtors.
        (struct imp_entry *imp_list): Add OCTI_UMSG_FAST_DECL,
        OCTI_METH_LIST_TEMPL, OCTI_METH_PROTO_LIST_TEMPL,
        OCTI_IVAR_LIST_TEMPL, OCTI_ASSIGN_IVAR_DECL,
        OCTI_ASSIGN_IVAR_FAST_DECL, OCTI_ASSIGN_GLOBAL_DECL,
        OCTI_ASSIGN_STRONGCAST_DECL.
        (umsg_fast_decl): Add.
        (objc_assign_ivar_decl): Add.
        (objc_assign_ivar_fast_decl): Add.
        (objc_assign_global_decl): Add.
        (objc_assign_strong_cast_decl): Add.
        (objc_method_list_ptr): Add.
        (objc_method_proto_list_ptr): Add.
        (objc_ivar_list_ptr): Add.

        * objc-act.c (should_call_super_dealloc): Add.
        (OBJC_VERSION): Bump to 6.
        (objc_is_gcable_type): Add.
        (objc_substitute_decl): Add.
        (objc_build_ivar_assignment): Add.
        (objc_build_global_assignment): Add.
        (objc_build_strong_cast_assignment): Add.
        (objc_is_gcable_p): Add.
        (objc_is_ivar_reference_p): Add.
        (objc_is_global_reference_p): Add.
        (generate_shared_structures): Add flags parameter.
        (objc_generate_cxx_ctor_or_dtor): Add.
        (objc_generate_cxx_cdtors): Add.
        (add_class): Add name parameter.
        (objc_types_share_size_and_alignment): Add.
        (comp_proto_with_proto): Add strict parameter.
        (CLS_HAS_CXX_STRUCTORS): Add.
        (TAG_ASSIGNIVAR): Add.
        (TAG_ASSIGNGLOBAL): Add.
        (TAG_ASSIGNSTRONGCAST): Add.
        (TAG_MSGSEND_FAST): Add.
        (TAG_ASSIGNIVAR_FAST): Add.
        (TAG_CXX_CONSTRUCT): Add.
        (TAG_CXX_DESTRUCT): Add.
        (OBJC_LOOKUP_CLASS): Add.
        (OBJC_LOOKUP_NO_SUPER): Add.
        (objc_finish_file): Add pch support.
        (objc_finish_implementation): Add Objective-C++ support.
        (synth_module_prologue): Likewise.
        (synth_module_prologue): Add fast dispatching.
        (objc_get_class_reference): Add Objective-C++ support.
        (objc_generate_write_barrier): Likewise.
        (next_sjlj_build_enter_and_setjmp): Likewise.
        (objc_begin_try_stmt): Likewise.
        (build_next_objc_exception_stuff): Add fast ivar support.
        (build_private_template): Mark the record as used so debug
        information is generated.
        (build_protocol_template): Add Objective-C++ support.
        (objc_method_parm_type) Likewise.
        (objc_generate_cxx_ctor_or_dtor): Likewise.
        (objc_generate_cxx_cdtors): Likewise.
        (build_protocol_initializer): Likewise.
        (build_category_template): Likewise.
        (build_class_template): Likewise.
        (build_method_list_template): Likewise.
        (build_category_initializer): Likewise.
        (build_shared_structure_initializer): Likewise.
        (objc_finish_message_expr): Likewise.
        (build_objc_method_call): Add fast dispatch support.
        (lookup_method_static): Add support to end search at superclasses.
        (add_method_to_hash_list): Add strict parameter to
        comp_proto_with_proto.
        (objc_add_method): Likewise.
        (objc_add_method): Also set the interface_value.
        (add_instance_variable): Add Objective-C++ support.
        (objc_is_public): Likewise.
        (start_class): Likewise.
        (continue_class): Likewise.
        (encode_aggregate_within): Likewise.
        (start_method_def): Likewise.
        (objc_start_function): Clear current_function_returns_value
        and current_function_returns_null.
        (really_start_method): Add Objective-C++ support.
        (objc_finish_method_definition): Add warning for missing
        [super dealloc].
        (finish_objc): Add Objective-C++ support.
        (generate_objc_image_info): Likewise.
        (objc_lookup_ivar): Likewise.
        * objc-act.h (TYPE_HAS_OBJC_INFO): Likewise.
        (INIT_TYPE_OBJC_INFO): Likewise.
        (DUP_TYPE_OBJC_INFO): Likewise.

From-SVN: r99857
parent 3193108e
2005-05-17 Mike Stump <mrs@apple.com>
Yet more Objective-C++...
* objc-act.c (objc_finish_try_stmt): Add return value.
(objc_build_synchronized): Likewise.
* objc-act.c (objc_is_gcable_type): Add.
(objc_substitute_decl): Add.
(objc_build_ivar_assignment): Add.
(objc_build_global_assignment): Add.
(objc_build_strong_cast_assignment): Add.
(objc_is_ivar_reference_p): Add.
(objc_is_global_reference_p): Add.
(objc_generate_write_barrier): Add.
(objc_rewrite_function_call): Add.
(objc_gimplify_expr): Add Objective-C++ support.
* objc-act.h (ALLOC_OBJC_TYPE_LANG_SPECIFIC): Likewise.
(SIZEOF_OBJC_TYPE_LANG_SPECIFIC): Add.
(INIT_TYPE_OBJC_INFO): Add Objective-C++ support.
(DUP_TYPE_OBJC_INFO): Likewise.
(struct imp_entry): Add field has_cxx_cdtors.
(struct imp_entry *imp_list): Add OCTI_UMSG_FAST_DECL,
OCTI_METH_LIST_TEMPL, OCTI_METH_PROTO_LIST_TEMPL,
OCTI_IVAR_LIST_TEMPL, OCTI_ASSIGN_IVAR_DECL,
OCTI_ASSIGN_IVAR_FAST_DECL, OCTI_ASSIGN_GLOBAL_DECL,
OCTI_ASSIGN_STRONGCAST_DECL.
(umsg_fast_decl): Add.
(objc_assign_ivar_decl): Add.
(objc_assign_ivar_fast_decl): Add.
(objc_assign_global_decl): Add.
(objc_assign_strong_cast_decl): Add.
(objc_method_list_ptr): Add.
(objc_method_proto_list_ptr): Add.
(objc_ivar_list_ptr): Add.
* objc-act.c (should_call_super_dealloc): Add.
(OBJC_VERSION): Bump to 6.
(objc_is_gcable_type): Add.
(objc_substitute_decl): Add.
(objc_build_ivar_assignment): Add.
(objc_build_global_assignment): Add.
(objc_build_strong_cast_assignment): Add.
(objc_is_gcable_p): Add.
(objc_is_ivar_reference_p): Add.
(objc_is_global_reference_p): Add.
(generate_shared_structures): Add flags parameter.
(objc_generate_cxx_ctor_or_dtor): Add.
(objc_generate_cxx_cdtors): Add.
(add_class): Add name parameter.
(objc_types_share_size_and_alignment): Add.
(comp_proto_with_proto): Add strict parameter.
(CLS_HAS_CXX_STRUCTORS): Add.
(TAG_ASSIGNIVAR): Add.
(TAG_ASSIGNGLOBAL): Add.
(TAG_ASSIGNSTRONGCAST): Add.
(TAG_MSGSEND_FAST): Add.
(TAG_ASSIGNIVAR_FAST): Add.
(TAG_CXX_CONSTRUCT): Add.
(TAG_CXX_DESTRUCT): Add.
(OBJC_LOOKUP_CLASS): Add.
(OBJC_LOOKUP_NO_SUPER): Add.
(objc_finish_file): Add pch support.
(objc_finish_implementation): Add Objective-C++ support.
(synth_module_prologue): Likewise.
(synth_module_prologue): Add fast dispatching.
(objc_get_class_reference): Add Objective-C++ support.
(objc_generate_write_barrier): Likewise.
(next_sjlj_build_enter_and_setjmp): Likewise.
(objc_begin_try_stmt): Likewise.
(build_next_objc_exception_stuff): Add fast ivar support.
(build_private_template): Mark the record as used so debug
information is generated.
(build_protocol_template): Add Objective-C++ support.
(objc_method_parm_type) Likewise.
(objc_generate_cxx_ctor_or_dtor): Likewise.
(objc_generate_cxx_cdtors): Likewise.
(build_protocol_initializer): Likewise.
(build_category_template): Likewise.
(build_class_template): Likewise.
(build_method_list_template): Likewise.
(build_category_initializer): Likewise.
(build_shared_structure_initializer): Likewise.
(objc_finish_message_expr): Likewise.
(build_objc_method_call): Add fast dispatch support.
(lookup_method_static): Add support to end search at superclasses.
(add_method_to_hash_list): Add strict parameter to
comp_proto_with_proto.
(objc_add_method): Likewise.
(objc_add_method): Also set the interface_value.
(add_instance_variable): Add Objective-C++ support.
(objc_is_public): Likewise.
(start_class): Likewise.
(continue_class): Likewise.
(encode_aggregate_within): Likewise.
(start_method_def): Likewise.
(objc_start_function): Clear current_function_returns_value
and current_function_returns_null.
(really_start_method): Add Objective-C++ support.
(objc_finish_method_definition): Add warning for missing
[super dealloc].
(finish_objc): Add Objective-C++ support.
(generate_objc_image_info): Likewise.
(objc_lookup_ivar): Likewise.
* objc-act.h (TYPE_HAS_OBJC_INFO): Likewise.
(INIT_TYPE_OBJC_INFO): Likewise.
(DUP_TYPE_OBJC_INFO): Likewise.
2005-04-23 DJ Delorie <dj@redhat.com>
* objc-act.c: Adjust warning() callers.
......
......@@ -77,6 +77,8 @@ Boston, MA 02111-1307, USA. */
#define OBJC_VOID_AT_END void_list_node
static unsigned int should_call_super_dealloc = 0;
/* When building Objective-C++, we are not linking against the C front-end
and so need to replicate the C tree-construction functions in some way. */
#ifdef OBJCPLUS
......@@ -126,7 +128,7 @@ char *util_firstobj;
the module (file) was compiled for, and is recorded in the
module descriptor. */
#define OBJC_VERSION (flag_next_runtime ? 5 : 8)
#define OBJC_VERSION (flag_next_runtime ? 6 : 8)
#define PROTOCOL_VERSION 2
/* (Decide if these can ever be validly changed.) */
......@@ -142,15 +144,9 @@ static void finish_objc (void);
/* Code generation. */
static void synth_module_prologue (void);
static tree objc_build_constructor (tree, tree);
static void build_module_descriptor (void);
static void build_module_initializer_routine (void);
static tree init_module_descriptor (tree);
static tree build_objc_method_call (int, tree, tree, tree, tree);
static void generate_strings (void);
static tree get_proto_encoding (tree);
static void build_selector_translation_table (void);
static tree lookup_interface (tree);
static tree objc_add_static_instance (tree, tree);
......@@ -169,55 +165,33 @@ static tree objc_add_method (tree, tree, int);
static tree add_instance_variable (tree, int, tree);
static tree build_ivar_reference (tree);
static tree is_ivar (tree, tree);
static int is_private (tree);
static tree get_super_receiver (void);
static void build_objc_exception_stuff (void);
static void build_next_objc_exception_stuff (void);
static tree build_ivar_template (void);
static tree build_method_template (void);
static void build_private_template (tree);
static void build_class_template (void);
static void build_selector_template (void);
static void build_category_template (void);
static tree lookup_method_in_hash_lists (tree, int);
static void build_super_template (void);
static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
static tree build_protocol_initializer (tree, tree, tree, tree, tree);
static void synth_forward_declarations (void);
static int ivar_list_length (tree);
static tree get_class_ivars (tree);
static void generate_ivar_lists (void);
static void generate_dispatch_tables (void);
static void generate_shared_structures (void);
static tree generate_protocol_list (tree);
static void build_protocol_reference (tree);
static tree build_keyword_selector (tree);
static const char *synth_id_with_class_suffix (const char *, tree);
#ifdef OBJCPLUS
static void objc_generate_cxx_cdtors (void);
#endif
static void generate_static_references (void);
static int check_methods_accessible (tree, tree, int);
static void encode_aggregate_within (tree, int, int, int, int);
static const char *objc_demangle (const char *);
static const char *synth_id_with_class_suffix (const char *, tree);
/* Hash tables to manage the global pool of method prototypes. */
hash *nst_method_hash_list = 0;
hash *cls_method_hash_list = 0;
static size_t hash_func (tree);
static void hash_init (void);
static void hash_enter (hash *, tree);
static hash hash_lookup (hash *, tree);
static void hash_add_attr (hash, tree);
static tree lookup_method (tree, tree);
static tree lookup_method_static (tree, tree, int);
static void add_method_to_hash_list (hash *, tree);
static tree add_class (tree);
static void add_category (tree, tree);
static inline tree lookup_category (tree, tree);
enum string_section
{
......@@ -227,26 +201,17 @@ enum string_section
};
static tree add_objc_string (tree, enum string_section);
static tree get_objc_string_decl (tree, enum string_section);
static tree build_objc_string_decl (enum string_section);
static tree build_selector_reference_decl (void);
static void build_selector_table_decl (void);
/* Protocol additions. */
static tree add_protocol (tree);
static tree lookup_protocol (tree);
static void check_protocol_recursively (tree, tree);
static tree lookup_and_install_protocols (tree);
/* Type encoding. */
static void encode_type_qualifiers (tree);
static void encode_pointer (tree, int, int);
static void encode_array (tree, int, int);
static void encode_aggregate (tree, int, int);
static void encode_next_bitfield (int);
static void encode_gnu_bitfield (int, tree, int);
static void encode_type (tree, int, int);
static void encode_field_decl (tree, int, int);
......@@ -255,76 +220,28 @@ static void really_start_method (tree, tree);
#else
static void really_start_method (tree, struct c_arg_info *);
#endif
static int objc_types_are_equivalent (tree, tree);
static int comp_proto_with_proto (tree, tree);
static tree get_arg_type_list (tree, int, int);
static int comp_proto_with_proto (tree, tree, int);
static void objc_push_parm (tree);
#ifdef OBJCPLUS
static tree objc_get_parm_info (int);
#else
static struct c_arg_info *objc_get_parm_info (int);
#endif
static void synth_self_and_ucmd_args (void);
/* Utilities for debugging and error diagnostics. */
static void warn_with_method (const char *, int, tree);
static void error_with_ivar (const char *, tree);
static char *gen_type_name (tree);
static char *gen_type_name_0 (tree);
static char *gen_method_decl (tree);
static char *gen_declaration (tree);
static void dump_interface (FILE *, tree);
/* Everything else. */
static tree lookup_method_in_protocol_list (tree, tree, int);
static tree lookup_protocol_in_reflist (tree, tree);
static tree start_var_decl (tree, const char *);
static void finish_var_decl (tree, tree);
static tree create_field_decl (tree, const char *);
static tree setup_string_decl (void);
static int check_string_class_template (void);
static tree my_build_string (int, const char *);
static void build_objc_symtab_template (void);
static tree init_def_list (tree);
static tree init_objc_symtab (tree);
static tree build_metadata_decl (const char *, tree);
static void forward_declare_categories (void);
static void generate_objc_symtab_decl (void);
static tree build_selector (tree);
static tree build_typed_selector_reference (tree, tree);
static tree build_selector_reference (tree);
static tree build_class_reference_decl (void);
static void add_class_reference (tree);
static void build_protocol_template (void);
static tree build_descriptor_table_initializer (tree, tree);
static tree build_method_prototype_list_template (tree, int);
static tree build_method_prototype_template (void);
static tree objc_method_parm_type (tree);
static int objc_encoded_type_size (tree);
static tree encode_method_prototype (tree);
static tree generate_descriptor_table (tree, const char *, int, tree, tree);
static void generate_method_descriptors (tree);
static void generate_protocol_references (tree);
static void generate_protocols (void);
static void check_ivars (tree, tree);
static tree build_ivar_list_template (tree, int);
static tree build_method_list_template (tree, int);
static tree build_ivar_list_initializer (tree, tree);
static tree generate_ivars_list (tree, const char *, int, tree);
static tree build_dispatch_table_initializer (tree, tree);
static tree generate_dispatch_table (tree, const char *, int, tree);
static tree build_shared_structure_initializer (tree, tree, tree, tree,
tree, int, tree, tree, tree);
static void generate_category (tree);
static tree adjust_type_for_id_default (tree);
static tree check_duplicates (hash, int, int);
static tree receiver_is_class_object (tree, int, int);
static int check_methods (tree, tree, int);
static int conforms_to_protocol (tree, tree);
static void check_protocol (tree, const char *, const char *);
static void check_protocols (tree, const char *, const char *);
static void generate_classref_translation_entry (tree);
static void handle_class_ref (tree);
static void generate_struct_by_value_array (void)
......@@ -378,6 +295,7 @@ static const char *default_constant_string_class_name;
/* Runtime metadata flags. */
#define CLS_FACTORY 0x0001L
#define CLS_META 0x0002L
#define CLS_HAS_CXX_STRUCTORS 0x2000L
#define OBJC_MODIFIER_STATIC 0x00000001
#define OBJC_MODIFIER_FINAL 0x00000002
......@@ -405,11 +323,28 @@ static const char *default_constant_string_class_name;
#define TAG_SETJMP "_setjmp"
#define UTAG_EXCDATA "_objc_exception_data"
#define TAG_ASSIGNIVAR "objc_assign_ivar"
#define TAG_ASSIGNGLOBAL "objc_assign_global"
#define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
/* Branch entry points. All that matters here are the addresses;
functions with these names do not really exist in libobjc. */
#define TAG_MSGSEND_FAST "objc_msgSend_Fast"
#define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
#define TAG_CXX_CONSTRUCT ".cxx_construct"
#define TAG_CXX_DESTRUCT ".cxx_destruct"
/* GNU-specific tags. */
#define TAG_EXECCLASS "__objc_exec_class"
#define TAG_GNUINIT "__objc_gnu_init"
/* Flags for lookup_method_static(). */
#define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
#define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
/* The OCTI_... enumeration itself is in objc/objc-act.h. */
tree objc_global_trees[OCTI_MAX];
......@@ -453,9 +388,6 @@ struct string_descriptor GTY(())
static GTY((param_is (struct string_descriptor))) htab_t string_htab;
static hashval_t string_hash (const void *);
static int string_eq (const void *, const void *);
FILE *gen_declaration_file;
/* Tells "encode_pointer/encode_aggregate" whether we are generating
......@@ -596,8 +528,8 @@ objc_finish_file (void)
#endif
/* Finalize Objective-C runtime data. No need to generate tables
and code if only checking syntax. */
if (!flag_syntax_only)
and code if only checking syntax, or if generating a PCH file. */
if (!flag_syntax_only && !pch_file)
finish_objc ();
if (gen_declaration_file)
......@@ -746,6 +678,11 @@ objc_continue_implementation (void)
void
objc_finish_implementation (void)
{
#ifdef OBJCPLUS
if (flag_objc_call_cxx_cdtors)
objc_generate_cxx_cdtors ();
#endif
if (objc_implementation_context)
{
finish_class (objc_implementation_context);
......@@ -1441,6 +1378,17 @@ synth_module_prologue (void)
objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier (TAG_SUPER)));
/* Declare pointers to method and ivar lists. */
objc_method_list_ptr = build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier (UTAG_METHOD_LIST)));
objc_method_proto_list_ptr
= build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
objc_ivar_list_ptr = build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier (UTAG_IVAR_LIST)));
if (flag_next_runtime)
{
/* NB: In order to call one of the ..._stret (struct-returning)
......@@ -1470,6 +1418,21 @@ synth_module_prologue (void)
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
/* id objc_msgSend_Fast (id, SEL, ...)
__attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
#ifdef OFFS_MSGSEND_FAST
umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
DECL_ATTRIBUTES (umsg_fast_decl)
= tree_cons (get_identifier ("hard_coded_address"),
build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
NULL_TREE);
#else
/* No direct dispatch availible. */
umsg_fast_decl = umsg_decl;
#endif
/* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
/* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
type
......@@ -2550,17 +2513,24 @@ tree
objc_get_class_reference (tree ident)
{
tree orig_ident;
bool local_scope = false;
#ifdef OBJCPLUS
if (processing_template_decl)
/* Must wait until template instantiation time. */
return build_min_nt (CLASS_REFERENCE_EXPR, ident);
if (TREE_CODE (ident) == TYPE_DECL)
{
/* The type must exist in the global namespace. */
if (DECL_CONTEXT (ident) && DECL_CONTEXT (ident) != global_namespace)
local_scope = true;
ident = DECL_NAME (ident);
}
#endif
orig_ident = ident;
if (!(ident = objc_is_class_name (ident)))
if (local_scope || !(ident = objc_is_class_name (ident)))
{
error ("%qs is not an Objective-C class name or alias",
IDENTIFIER_POINTER (orig_ident));
......@@ -2808,21 +2778,320 @@ objc_is_object_ptr (tree type)
return ret;
}
static int
objc_is_gcable_type (tree type, int or_strong_p)
{
tree name;
if (!TYPE_P (type))
return 0;
if (objc_is_id (TYPE_MAIN_VARIANT (type)))
return 1;
if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
return 1;
if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
return 0;
type = TREE_TYPE (type);
if (TREE_CODE (type) != RECORD_TYPE)
return 0;
name = TYPE_NAME (type);
return (objc_is_class_name (name) != NULL_TREE);
}
static tree
lookup_interface (tree ident)
objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
{
if (expr == oldexpr)
return newexpr;
switch (TREE_CODE (expr))
{
case COMPONENT_REF:
return build_component_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr),
DECL_NAME (TREE_OPERAND (expr, 1)));
case ARRAY_REF:
return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr),
TREE_OPERAND (expr, 1));
case INDIRECT_REF:
return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr), "->");
default:
return expr;
}
}
static tree
objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
{
tree chain;
tree func_params;
/* The LHS parameter contains the expression 'outervar->memberspec';
we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
*/
tree offs
= objc_substitute_decl
(lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
tree func
= (flag_objc_direct_dispatch
? objc_assign_ivar_fast_decl
: objc_assign_ivar_decl);
offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
offs = fold (offs);
func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (objc_object_type, outervar),
tree_cons (NULL_TREE, offs,
NULL_TREE)));
assemble_external (func);
return build_function_call (func, func_params);
}
static tree
objc_build_global_assignment (tree lhs, tree rhs)
{
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
build_unary_op (ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_global_decl);
return build_function_call (objc_assign_global_decl, func_params);
}
static tree
objc_build_strong_cast_assignment (tree lhs, tree rhs)
{
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
build_unary_op (ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
return build_function_call (objc_assign_strong_cast_decl, func_params);
}
static int
objc_is_gcable_p (tree expr)
{
return (TREE_CODE (expr) == COMPONENT_REF
? objc_is_gcable_p (TREE_OPERAND (expr, 1))
: TREE_CODE (expr) == ARRAY_REF
? (objc_is_gcable_p (TREE_TYPE (expr))
|| objc_is_gcable_p (TREE_OPERAND (expr, 0)))
: TREE_CODE (expr) == ARRAY_TYPE
? objc_is_gcable_p (TREE_TYPE (expr))
: TYPE_P (expr)
? objc_is_gcable_type (expr, 1)
: (objc_is_gcable_p (TREE_TYPE (expr))
|| (DECL_P (expr)
&& lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
}
static int
objc_is_ivar_reference_p (tree expr)
{
return (TREE_CODE (expr) == ARRAY_REF
? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
: TREE_CODE (expr) == COMPONENT_REF
? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
: 0);
}
static int
objc_is_global_reference_p (tree expr)
{
return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
: DECL_P (expr)
? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
: 0);
}
tree
objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
{
tree result = NULL_TREE, outer;
int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
/* See if we have any lhs casts, and strip them out. NB: The lvalue casts
will have been transformed to the form '*(type *)&expr'. */
if (TREE_CODE (lhs) == INDIRECT_REF)
{
outer = TREE_OPERAND (lhs, 0);
while (!strong_cast_p
&& (TREE_CODE (outer) == CONVERT_EXPR
|| TREE_CODE (outer) == NOP_EXPR
|| TREE_CODE (outer) == NON_LVALUE_EXPR))
{
tree lhstype = TREE_TYPE (outer);
/* Descend down the cast chain, and record the first objc_gc
attribute found. */
if (POINTER_TYPE_P (lhstype))
{
tree attr
= lookup_attribute ("objc_gc",
TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
if (attr)
strong_cast_p = 1;
}
outer = TREE_OPERAND (outer, 0);
}
}
/* If we have a __strong cast, it trumps all else. */
if (strong_cast_p)
{
if (modifycode != NOP_EXPR)
goto invalid_pointer_arithmetic;
if (warn_assign_intercept)
warning (0, "strong-cast assignment has been intercepted");
result = objc_build_strong_cast_assignment (lhs, rhs);
goto exit_point;
}
/* the lhs must be of a suitable type, regardless of its underlying
structure. */
if (!objc_is_gcable_p (lhs))
goto exit_point;
outer = lhs;
while (outer
&& (TREE_CODE (outer) == COMPONENT_REF
|| TREE_CODE (outer) == ARRAY_REF))
outer = TREE_OPERAND (outer, 0);
if (TREE_CODE (outer) == INDIRECT_REF)
{
outer = TREE_OPERAND (outer, 0);
indirect_p = 1;
}
outer_gc_p = objc_is_gcable_p (outer);
/* Handle ivar assignments. */
if (objc_is_ivar_reference_p (lhs))
{
/* if the struct to the left of the ivar is not an Objective-C object (__strong
doesn't cut it here), the best we can do here is suggest a cast. */
if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
{
/* We may still be able to use the global write barrier... */
if (!indirect_p && objc_is_global_reference_p (outer))
goto global_reference;
suggest_cast:
if (modifycode == NOP_EXPR)
{
if (warn_assign_intercept)
warning (0, "strong-cast may possibly be needed");
}
goto exit_point;
}
if (modifycode != NOP_EXPR)
goto invalid_pointer_arithmetic;
if (warn_assign_intercept)
warning (0, "instance variable assignment has been intercepted");
result = objc_build_ivar_assignment (outer, lhs, rhs);
goto exit_point;
}
/* Likewise, intercept assignment to global/static variables if their type is
GC-marked. */
if (objc_is_global_reference_p (outer))
{
if (indirect_p)
goto suggest_cast;
global_reference:
if (modifycode != NOP_EXPR)
{
invalid_pointer_arithmetic:
if (outer_gc_p)
warning (0, "pointer arithmetic for garbage-collected objects not allowed");
goto exit_point;
}
if (warn_assign_intercept)
warning (0, "global/static variable assignment has been intercepted");
result = objc_build_global_assignment (lhs, rhs);
}
/* In all other cases, fall back to the normal mechanism. */
exit_point:
return result;
}
static GTY ((param_is (union tree_node))) htab_t interface_htab;
struct interface_tuple {
tree id;
tree class_name;
};
static hashval_t
hash_interface (const void *p)
{
const struct interface_tuple *d = p;
return htab_hash_pointer (d->id);
}
static int
eq_interface (const void *p1, const void *p2)
{
const struct interface_tuple *d = p1;
return d->id == p2;
}
static tree
lookup_interface (tree ident)
{
#ifdef OBJCPLUS
if (ident && TREE_CODE (ident) == TYPE_DECL)
ident = DECL_NAME (ident);
#endif
for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
return NULL_TREE;
{
if (ident == CLASS_NAME (chain))
return chain;
struct interface_tuple **slot;
tree i = NULL_TREE;
if (interface_htab)
{
slot = (struct interface_tuple **)
htab_find_slot_with_hash (interface_htab, ident,
htab_hash_pointer (ident),
NO_INSERT);
if (slot && *slot)
i = (*slot)->class_name;
}
return i;
}
return NULL_TREE;
}
/* Implement @defs (<classname>) within struct bodies. */
......@@ -3016,7 +3285,15 @@ next_sjlj_build_enter_and_setjmp (void)
t = build_component_ref (cur_try_context->stack_decl,
get_identifier ("buf"));
t = build_fold_addr_expr (t);
#ifdef OBJCPLUS
/* Convert _setjmp argument to type that is expected. */
if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
else
t = convert (ptr_type_node, t);
#else
t = convert (ptr_type_node, t);
#endif
t = tree_cons (NULL, t, NULL);
sj = build_function_call (objc_setjmp_decl, t);
......@@ -3243,6 +3520,9 @@ objc_begin_try_stmt (location_t try_locus, tree body)
cur_try_context = c;
objc_init_exceptions ();
if (flag_objc_sjlj_exceptions)
objc_mark_locals_volatile (NULL);
}
/* Called just after parsing "@catch (parm)". Open a binding level,
......@@ -3338,7 +3618,7 @@ objc_build_finally_clause (location_t finally_locus, tree body)
/* Called to finalize a @try construct. */
void
tree
objc_finish_try_stmt (void)
{
struct objc_try_context *c = cur_try_context;
......@@ -3376,6 +3656,7 @@ objc_finish_try_stmt (void)
cur_try_context = c->outer;
free (c);
return stmt;
}
tree
......@@ -3407,7 +3688,7 @@ objc_build_throw_stmt (tree throw_expr)
return add_stmt (build_function_call (objc_exception_throw_decl, args));
}
void
tree
objc_build_synchronized (location_t start_locus, tree mutex, tree body)
{
tree args, call;
......@@ -3427,7 +3708,7 @@ objc_build_synchronized (location_t start_locus, tree mutex, tree body)
/* Put the that and the body in a TRY_FINALLY. */
objc_begin_try_stmt (start_locus, body);
objc_build_finally_clause (input_location, call);
objc_finish_try_stmt ();
return objc_finish_try_stmt ();
}
......@@ -3509,6 +3790,44 @@ build_next_objc_exception_stuff (void)
OBJC_VOID_AT_END)));
objc_exception_match_decl
= builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* id objc_assign_ivar (id, id, unsigned int); */
/* id objc_assign_ivar_Fast (id, id, unsigned int)
__attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
temp_type
= build_function_type (objc_object_type,
tree_cons
(NULL_TREE, objc_object_type,
tree_cons (NULL_TREE, objc_object_type,
tree_cons (NULL_TREE,
unsigned_type_node,
OBJC_VOID_AT_END))));
objc_assign_ivar_decl
= builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
#ifdef OFFS_ASSIGNIVAR_FAST
objc_assign_ivar_fast_decl
= builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
NOT_BUILT_IN, NULL, NULL_TREE);
DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
= tree_cons (get_identifier ("hard_coded_address"),
build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
NULL_TREE);
#else
/* Default to slower ivar method. */
objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
#endif
/* id objc_assign_global (id, id *); */
/* id objc_assign_strongCast (id, id *); */
temp_type = build_function_type (objc_object_type,
tree_cons (NULL_TREE, objc_object_type,
tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
OBJC_VOID_AT_END)));
objc_assign_global_decl
= builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
objc_assign_strong_cast_decl
= builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
}
static void
......@@ -3556,6 +3875,11 @@ build_private_template (tree class)
INIT_TYPE_OBJC_INFO (record);
TYPE_OBJC_INTERFACE (record) = class;
CLASS_STATIC_TEMPLATE (class) = record;
/* Set the TREE_USED bit for this struct, so that stab generator
can emit stabs for this struct type. */
if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
TREE_USED (TYPE_STUB_DECL (record)) = 1;
}
}
......@@ -3595,19 +3919,13 @@ build_protocol_template (void)
"protocol_list");
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *instance_methods; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_PROTOTYPE_LIST))),
/* struct _objc__method_prototype_list *instance_methods; */
field_decl = create_field_decl (objc_method_proto_list_ptr,
"instance_methods");
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *class_methods; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_PROTOTYPE_LIST))),
/* struct _objc__method_prototype_list *class_methods; */
field_decl = create_field_decl (objc_method_proto_list_ptr,
"class_methods");
chainon (field_decl_chain, field_decl);
......@@ -3708,7 +4026,7 @@ objc_method_parm_type (tree type)
type = TREE_VALUE (TREE_TYPE (type));
if (TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
return TYPE_MAIN_VARIANT (type);
return type;
}
static int
......@@ -3886,6 +4204,136 @@ generate_protocol_references (tree plist)
}
}
/* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
current class. */
#ifdef OBJCPLUS
static void
objc_generate_cxx_ctor_or_dtor (bool dtor)
{
tree fn, body, compound_stmt, ivar;
/* - (id) .cxx_construct { ... return self; } */
/* - (void) .cxx_construct { ... } */
objc_set_method_type (MINUS_EXPR);
objc_start_method_definition
(objc_build_method_signature (build_tree_list (NULL_TREE,
dtor
? void_type_node
: objc_object_type),
get_identifier (dtor
? TAG_CXX_DESTRUCT
: TAG_CXX_CONSTRUCT),
make_node (TREE_LIST),
false));
body = begin_function_body ();
compound_stmt = begin_compound_stmt (0);
ivar = CLASS_IVARS (implementation_template);
/* Destroy ivars in reverse order. */
if (dtor)
ivar = nreverse (copy_list (ivar));
for (; ivar; ivar = TREE_CHAIN (ivar))
{
if (TREE_CODE (ivar) == FIELD_DECL)
{
tree type = TREE_TYPE (ivar);
/* Call the ivar's default constructor or destructor. Do not
call the destructor unless a corresponding constructor call
has also been made (or is not needed). */
if (IS_AGGR_TYPE (type)
&& (dtor
? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& (!TYPE_NEEDS_CONSTRUCTING (type)
|| TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
: (TYPE_NEEDS_CONSTRUCTING (type)
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
finish_expr_stmt
(build_special_member_call
(build_ivar_reference (DECL_NAME (ivar)),
dtor ? complete_dtor_identifier : complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL));
}
}
/* The constructor returns 'self'. */
if (!dtor)
finish_return_stmt (self_decl);
finish_compound_stmt (compound_stmt);
finish_function_body (body);
fn = current_function_decl;
finish_function ();
objc_finish_method_definition (fn);
}
/* The following routine will examine the current @interface for any
non-POD C++ ivars requiring non-trivial construction and/or
destruction, and then synthesize special '- .cxx_construct' and/or
'- .cxx_destruct' methods which will run the appropriate
construction or destruction code. Note that ivars inherited from
super-classes are _not_ considered. */
static void
objc_generate_cxx_cdtors (void)
{
bool need_ctor = false, need_dtor = false;
tree ivar;
/* We do not want to do this for categories, since they do not have
their own ivars. */
if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
return;
/* First, determine if we even need a constructor and/or destructor. */
for (ivar = CLASS_IVARS (implementation_template); ivar;
ivar = TREE_CHAIN (ivar))
{
if (TREE_CODE (ivar) == FIELD_DECL)
{
tree type = TREE_TYPE (ivar);
if (IS_AGGR_TYPE (type))
{
if (TYPE_NEEDS_CONSTRUCTING (type)
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
/* NB: If a default constructor is not available, we will not
be able to initialize this ivar; the add_instance_variable()
routine will already have warned about this. */
need_ctor = true;
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& (!TYPE_NEEDS_CONSTRUCTING (type)
|| TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
/* NB: If a default constructor is not available, we will not
call the destructor either, for symmetry. */
need_dtor = true;
}
}
}
/* Generate '- .cxx_construct' if needed. */
if (need_ctor)
objc_generate_cxx_ctor_or_dtor (false);
/* Generate '- .cxx_destruct' if needed. */
if (need_dtor)
objc_generate_cxx_ctor_or_dtor (true);
/* The 'imp_list' variable points at an imp_entry record for the current
@implementation. Record the existence of '- .cxx_construct' and/or
'- .cxx_destruct' methods therein; it will be included in the
metadata for the class. */
if (flag_next_runtime)
imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
}
#endif
/* For each protocol which was referenced either from a @protocol()
expression, or because a class/category implements it (then a
pointer to the protocol is stored in the struct describing the
......@@ -4019,7 +4467,8 @@ build_protocol_initializer (tree type, tree protocol_name,
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
expr = convert (objc_method_proto_list_ptr,
build_unary_op (ADDR_EXPR, instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
......@@ -4027,7 +4476,8 @@ build_protocol_initializer (tree type, tree protocol_name,
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, class_methods, 0);
expr = convert (objc_method_proto_list_ptr,
build_unary_op (ADDR_EXPR, class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
......@@ -4059,18 +4509,12 @@ build_category_template (void)
chainon (field_decl_chain, field_decl);
/* struct _objc_method_list *instance_methods; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_LIST))),
field_decl = create_field_decl (objc_method_list_ptr,
"instance_methods");
chainon (field_decl_chain, field_decl);
/* struct _objc_method_list *class_methods; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_LIST))),
field_decl = create_field_decl (objc_method_list_ptr,
"class_methods");
chainon (field_decl_chain, field_decl);
......@@ -4172,18 +4616,12 @@ build_class_template (void)
chainon (field_decl_chain, field_decl);
/* struct _objc_ivar_list *ivars; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_IVAR_LIST))),
field_decl = create_field_decl (objc_ivar_list_ptr,
"ivars");
chainon (field_decl_chain, field_decl);
/* struct _objc_method_list *methods; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_LIST))),
field_decl = create_field_decl (objc_method_list_ptr,
"methods");
chainon (field_decl_chain, field_decl);
......@@ -4434,10 +4872,7 @@ build_method_list_template (tree list_type, int size)
objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
/* struct _objc__method_prototype_list *method_next; */
field_decl = create_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE,
get_identifier
(UTAG_METHOD_PROTOTYPE_LIST))),
field_decl = create_field_decl (objc_method_proto_list_ptr,
"method_next");
field_decl_chain = field_decl;
......@@ -4836,14 +5271,16 @@ build_category_initializer (tree type, tree cat_name, tree class_name,
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
expr = convert (objc_method_list_ptr,
build_unary_op (ADDR_EXPR, instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
if (!class_methods)
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, class_methods, 0);
expr = convert (objc_method_list_ptr,
build_unary_op (ADDR_EXPR, class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
......@@ -4919,7 +5356,8 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
expr = convert (objc_ivar_list_ptr,
build_unary_op (ADDR_EXPR, ivar_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
......@@ -4928,7 +5366,8 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
else
{
expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
expr = convert (objc_method_list_ptr,
build_unary_op (ADDR_EXPR, dispatch_table, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
......@@ -5023,7 +5462,7 @@ generate_category (tree cat)
static struct objc_class _OBJC_CLASS_Foo={ ... }; */
static void
generate_shared_structures (void)
generate_shared_structures (int cls_flags)
{
tree sc_spec, decl_specs, decl;
tree name_expr, super_expr, root_expr;
......@@ -5114,7 +5553,7 @@ generate_shared_structures (void)
convert (integer_type_node,
TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
(implementation_template))),
1 /*CLS_FACTORY*/,
1 /*CLS_FACTORY*/ | cls_flags,
UOBJC_INSTANCE_METHODS_decl,
UOBJC_INSTANCE_VARIABLES_decl,
protocol_decl);
......@@ -5377,6 +5816,20 @@ check_duplicates (hash hsh, int methods, int is_class)
different types. */
attr loop;
/* But just how different are those types? If
-Wno-strict-selector-match is specified, we shall not
complain if the differences are solely among types with
identical size and alignment. */
if (!warn_strict_selector_match)
{
for (loop = hsh->list; loop; loop = loop->next)
if (!comp_proto_with_proto (meth, loop->value, 0))
goto issue_warning;
return meth;
}
issue_warning:
warning (0, "multiple %s named %<%c%s%> found",
methods ? "methods" : "selectors",
(is_class ? '+' : '-'),
......@@ -5587,6 +6040,10 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
|| (TREE_CODE (receiver) == COMPOUND_EXPR
&& !IS_SUPER (rtype)));
/* If we are calling [super dealloc], reset our warning flag. */
if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
should_call_super_dealloc = 0;
/* If the receiver is a class object, retrieve the corresponding
@interface, if one exists. */
class_tree = receiver_is_class_object (receiver, self, super);
......@@ -5615,18 +6072,13 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
/* If receiver is of type `id' or `Class' (or if the @interface for a
class is not visible), we shall be satisfied with the existence of
any instance or class method. */
if (!rtype || objc_is_id (rtype))
{
if (!rtype)
rtype = xref_tag (RECORD_TYPE, class_tree);
else
if (objc_is_id (rtype))
{
class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
: NULL_TREE);
rtype = NULL_TREE;
}
if (rprotos)
{
......@@ -5651,7 +6103,7 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
}
}
}
else
else if (rtype)
{
tree orig_rtype = rtype, saved_rtype;
......@@ -5673,7 +6125,7 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
more intelligent about which methods the receiver will
understand. */
if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
rtype = saved_rtype;
rtype = NULL_TREE;
else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
|| TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
{
......@@ -5788,7 +6240,9 @@ build_objc_method_call (int super_flag, tree method_prototype,
{
tree sender = (super_flag ? umsg_super_decl :
(!flag_next_runtime || flag_nil_receivers
? umsg_decl
? (flag_objc_direct_dispatch
? umsg_fast_decl
: umsg_decl)
: umsg_nonnil_decl));
tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
......@@ -6125,11 +6579,23 @@ lookup_method (tree mchain, tree method)
return NULL_TREE;
}
/* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
in INTERFACE, along with any categories and protocols attached thereto.
If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
be found in INTERFACE or any of its superclasses, look for an _instance_
method of the same name in the root class as a last resort.
If a suitable method cannot be found, return NULL_TREE. */
static tree
lookup_method_static (tree interface, tree ident, int is_class)
lookup_method_static (tree interface, tree ident, int flags)
{
tree meth = NULL_TREE, root_inter = NULL_TREE;
tree inter = interface;
int is_class = (flags & OBJC_LOOKUP_CLASS);
int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
while (inter)
{
......@@ -6166,6 +6632,10 @@ lookup_method_static (tree interface, tree ident, int is_class)
return meth;
}
/* If we were instructed not to look in superclasses, don't. */
if (no_superclasses)
return NULL_TREE;
/* Failing that, climb up the inheritance hierarchy. */
root_inter = inter;
inter = lookup_interface (CLASS_SUPER_NAME (inter));
......@@ -6195,9 +6665,9 @@ add_method_to_hash_list (hash *hash_list, tree method)
{
/* Check types against those; if different, add to a list. */
attr loop;
int already_there = comp_proto_with_proto (method, hsh->key);
int already_there = comp_proto_with_proto (method, hsh->key, 1);
for (loop = hsh->list; !already_there && loop; loop = loop->next)
already_there |= comp_proto_with_proto (method, loop->value);
already_there |= comp_proto_with_proto (method, loop->value, 1);
if (!already_there)
hash_add_attr (hsh, method);
}
......@@ -6233,7 +6703,7 @@ objc_add_method (tree class, tree method, int is_class)
definition errors). */
if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
|| TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth))
&& !comp_proto_with_proto (method, mth, 1))
error ("duplicate declaration of method %<%c%s%>",
is_class ? '+' : '-',
IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
......@@ -6263,11 +6733,27 @@ objc_add_method (tree class, tree method, int is_class)
}
static tree
add_class (tree class)
add_class (tree class_name, tree name)
{
struct interface_tuple **slot;
/* Put interfaces on list in reverse order. */
TREE_CHAIN (class) = interface_chain;
interface_chain = class;
TREE_CHAIN (class_name) = interface_chain;
interface_chain = class_name;
if (interface_htab == NULL)
interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
slot = (struct interface_tuple **)
htab_find_slot_with_hash (interface_htab, name,
htab_hash_pointer (name),
INSERT);
if (!*slot)
{
*slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
(*slot)->id = name;
}
(*slot)->class_name = class_name;
return interface_chain;
}
......@@ -6323,27 +6809,65 @@ add_instance_variable (tree class, int public, tree field_decl)
}
#ifdef OBJCPLUS
/* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
cannot be ivars; ditto for classes with vtables. */
if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
/* Check if the ivar being added has a non-POD C++ type. If so, we will
need to either (1) warn the user about it or (2) generate suitable
constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
methods (if '-fobjc-call-cxx-cdtors' was specified). */
if (IS_AGGR_TYPE (field_type)
&& (TYPE_NEEDS_CONSTRUCTING (field_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
|| TYPE_POLYMORPHIC_P (field_type)))
{
const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
if(TYPE_POLYMORPHIC_P (field_type)) {
/* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
error ("type %qs has virtual member functions", type_name);
error ("illegal aggregate type %qs specified for instance variable %qs",
if (flag_objc_call_cxx_cdtors)
{
/* Since the ObjC runtime will be calling the constructors and
destructors for us, the only thing we can't handle is the lack
of a default constructor. */
if (TYPE_NEEDS_CONSTRUCTING (field_type)
&& !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
{
warning (0, "type `%s' has no default constructor to call",
type_name);
/* If we cannot call a constructor, we should also avoid
calling the destructor, for symmetry. */
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
warning (0, "destructor for `%s' shall not be run either",
type_name);
}
}
else
{
static bool warn_cxx_ivars = false;
if (TYPE_POLYMORPHIC_P (field_type))
{
/* Vtable pointers are Real Bad(tm), since Obj-C cannot
initialize them. */
error ("type `%s' has virtual member functions", type_name);
error ("illegal aggregate type `%s' specified "
"for instance variable `%s'",
type_name, ivar_name);
/* Return class as is without adding this ivar. */
return class;
}
/* user-defined constructors and destructors are not known to Obj-C and
hence will not be called. This may or may not be a problem. */
/* User-defined constructors and destructors are not known to Obj-C
and hence will not be called. This may or may not be a problem. */
if (TYPE_NEEDS_CONSTRUCTING (field_type))
warning (0, "type %qs has a user-defined constructor", type_name);
warning (0, "type `%s' has a user-defined constructor", type_name);
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
warning (0, "type %qs has a user-defined destructor", type_name);
warning (0, "C++ constructors and destructors will not be invoked for Objective-C fields");
warning (0, "type `%s' has a user-defined destructor", type_name);
if (!warn_cxx_ivars)
{
warning (0, "C++ constructors and destructors will not "
"be invoked for Objective-C fields");
warn_cxx_ivars = true;
}
}
}
#endif
......@@ -6400,21 +6924,22 @@ int
objc_is_public (tree expr, tree identifier)
{
tree basetype = TREE_TYPE (expr);
enum tree_code code = TREE_CODE (basetype);
tree decl;
if (code == RECORD_TYPE)
if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
{
if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
{
if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype)) == IDENTIFIER_NODE)
tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
if (!class)
{
error ("cannot find interface declaration for %qs",
IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
return 0;
}
if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
if ((decl = is_ivar (get_class_ivars (class), identifier)))
{
if (TREE_PUBLIC (decl))
return 1;
......@@ -6455,12 +6980,6 @@ objc_is_public (tree expr, tree identifier)
return 0;
}
}
else if (objc_implementation_context && (basetype == objc_object_reference))
{
expr = convert (uprivate_record, expr);
warning (0, "static access to object of type %<id%>");
}
}
return 1;
......@@ -6687,15 +7206,24 @@ start_class (enum tree_code code, tree class_name, tree super_name,
class = make_node (code);
TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
/* Check for existence of the super class, if one was specified. */
/* Check for existence of the super class, if one was specified. Note
that we must have seen an @interface, not just a @class. If we
are looking at a @compatibility_alias, traverse it first. */
if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
&& super_name && !objc_is_class_name (super_name))
&& super_name)
{
tree super = objc_is_class_name (super_name);
if (!super || !lookup_interface (super))
{
error ("cannot find interface declaration for %qs, superclass of %qs",
IDENTIFIER_POINTER (super_name),
IDENTIFIER_POINTER (super ? super : super_name),
IDENTIFIER_POINTER (class_name));
super_name = NULL_TREE;
}
else
super_name = super;
}
CLASS_NAME (class) = class_name;
CLASS_SUPER_NAME (class) = super_name;
......@@ -6737,7 +7265,8 @@ start_class (enum tree_code code, tree class_name, tree super_name,
{
warning (0, "cannot find interface declaration for %qs",
IDENTIFIER_POINTER (class_name));
add_class (implementation_template = objc_implementation_context);
add_class (implementation_template = objc_implementation_context,
class_name);
}
/* If a super class has been specified in the implementation,
......@@ -6771,7 +7300,7 @@ start_class (enum tree_code code, tree class_name, tree super_name,
#endif
IDENTIFIER_POINTER (class_name));
else
add_class (class);
add_class (class, class_name);
if (protocol_list)
CLASS_PROTOCOL_LIST (class)
......@@ -6828,7 +7357,6 @@ continue_class (tree class)
|| TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
{
struct imp_entry *imp_entry;
tree ivar_context;
/* Check consistency of the instance variables. */
......@@ -6843,7 +7371,6 @@ continue_class (tree class)
build_private_template (implementation_template);
uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
ivar_context = TYPE_FIELDS (uprivate_record);
objc_instance_type = build_pointer_type (uprivate_record);
imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
......@@ -6855,6 +7382,7 @@ continue_class (tree class)
synth_forward_declarations ();
imp_entry->class_decl = UOBJC_CLASS_decl;
imp_entry->meta_decl = UOBJC_METACLASS_decl;
imp_entry->has_cxx_cdtors = 0;
/* Append to front and increment count. */
imp_list = imp_entry;
......@@ -6867,7 +7395,7 @@ continue_class (tree class)
pop_lang_context ();
#endif /* OBJCPLUS */
return ivar_context;
return get_class_ivars (implementation_template);
}
else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
......@@ -7159,12 +7687,13 @@ encode_aggregate_within (tree type, int curtype, int format, int left,
tree name;
/* NB: aggregates that are pointed to have slightly different encoding
rules in that you never encode the names of instance variables. */
int pointed_to
= (obstack_object_size (&util_obstack) > 0
&& *(obstack_next_free (&util_obstack) - 1) == '^');
int ob_size = obstack_object_size (&util_obstack);
char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
int inline_contents
= ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
&& (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
&& (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
/* Traverse struct aliases; it is important to get the
original struct and its tag name (if any). */
......@@ -7511,6 +8040,15 @@ start_method_def (tree method)
#endif
int have_ellipsis = 0;
/* If we are defining a "dealloc" method in a non-root class, we
will need to check if a [super dealloc] is missing, and warn if
it is. */
if(CLASS_SUPER_NAME (objc_implementation_context)
&& !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
should_call_super_dealloc = 1;
else
should_call_super_dealloc = 0;
/* Required to implement _msgSuper. */
objc_method_context = method;
UOBJC_SUPER_decl = NULL_TREE;
......@@ -7589,11 +8127,23 @@ objc_types_are_equivalent (tree type1, tree type2)
return 0;
}
/* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
static int
objc_types_share_size_and_alignment (tree type1, tree type2)
{
return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
&& TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
}
/* Return 1 if PROTO1 is equivalent to PROTO2
for purposes of method overloading. */
for purposes of method overloading. Ordinarily, the type signatures
should match up exactly, unless STRICT is zero, in which case we
shall allow differences in which the size and alignment of a type
is the same. */
static int
comp_proto_with_proto (tree proto1, tree proto2)
comp_proto_with_proto (tree proto1, tree proto2, int strict)
{
tree type1, type2;
......@@ -7606,7 +8156,8 @@ comp_proto_with_proto (tree proto1, tree proto2)
type1 = TREE_VALUE (TREE_TYPE (proto1));
type2 = TREE_VALUE (TREE_TYPE (proto2));
if (!objc_types_are_equivalent (type1, type2))
if (!objc_types_are_equivalent (type1, type2)
&& (strict || !objc_types_share_size_and_alignment (type1, type2)))
return 0;
/* Compare argument types. */
......@@ -7615,7 +8166,10 @@ comp_proto_with_proto (tree proto1, tree proto2)
type1 && type2;
type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
{
if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
&& (strict
|| !objc_types_share_size_and_alignment (TREE_VALUE (type1),
TREE_VALUE (type2))))
return 0;
}
......@@ -7682,6 +8236,9 @@ objc_start_function (tree name, tree type, tree attrs,
nstack_vm->scope = 0;
nstack_vm->next = label_context_stack_vm;
label_context_stack_vm = nstack_vm;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
decl_attributes (&fndecl, attrs, 0);
announce_function (fndecl);
DECL_INITIAL (fndecl) = error_mark_node;
......@@ -7772,11 +8329,12 @@ really_start_method (tree method,
tree proto
= lookup_method_static (implementation_template,
METHOD_SEL_NAME (method),
TREE_CODE (method) == CLASS_METHOD_DECL);
((TREE_CODE (method) == CLASS_METHOD_DECL)
| OBJC_LOOKUP_NO_SUPER));
if (proto)
{
if (!comp_proto_with_proto (method, proto))
if (!comp_proto_with_proto (method, proto, 1))
{
char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
......@@ -7948,6 +8506,9 @@ objc_finish_method_definition (tree fndecl)
/* Required to implement _msgSuper. This must be done AFTER finish_function,
since the optimizer may find "may be used before set" errors. */
objc_method_context = NULL_TREE;
if (should_call_super_dealloc)
warning (0, "method possibly missing a [super dealloc] call");
}
#if 0
......@@ -8322,7 +8883,9 @@ finish_objc (void)
/* all of the following reference the string pool... */
generate_ivar_lists ();
generate_dispatch_tables ();
generate_shared_structures ();
generate_shared_structures (impent->has_cxx_cdtors
? CLS_HAS_CXX_STRUCTORS
: 0);
}
else
{
......@@ -8339,7 +8902,7 @@ finish_objc (void)
if (protocol_chain)
generate_protocols ();
if (flag_replace_objc_classes && imp_list)
if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
generate_objc_image_info ();
/* Arrange for ObjC data structures to be initialized at run time. */
......@@ -8521,6 +9084,9 @@ static void
generate_objc_image_info (void)
{
tree decl, initlist;
int flags
= ((flag_replace_objc_classes && imp_list ? 1 : 0)
| (flag_objc_gc ? 2 : 0));
decl = start_var_decl (build_array_type
(integer_type_node,
......@@ -8528,7 +9094,7 @@ generate_objc_image_info (void)
"_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, 1), initlist);
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
finish_var_decl (decl, initlist);
......@@ -8565,7 +9131,12 @@ objc_lookup_ivar (tree other, tree id)
/* In an instance method, a local variable (or parameter) may hide the
instance variable. */
if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
&& other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
&& other && other != error_mark_node
#ifdef OBJCPLUS
&& CP_DECL_CONTEXT (other) != global_namespace)
#else
&& !DECL_FILE_SCOPE_P (other))
#endif
{
warning (0, "local declaration of %qs hides instance variable",
IDENTIFIER_POINTER (id));
......@@ -8579,6 +9150,25 @@ objc_lookup_ivar (tree other, tree id)
return build_ivar_reference (id);
}
/* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
needs to be done if we are calling a function through a cast. */
tree
objc_rewrite_function_call (tree function, tree params)
{
if (TREE_CODE (function) == NOP_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
== FUNCTION_DECL)
{
function = build (OBJ_TYPE_REF, TREE_TYPE (function),
TREE_OPERAND (function, 0),
TREE_VALUE (params), size_zero_node);
}
return function;
}
/* Look for the special case of OBJC_TYPE_REF with the address of
a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
of its cousins). */
......@@ -8604,7 +9194,11 @@ enum gimplify_status objc_gimplify_expr (tree *expr_p, tree *pre_p,
is_gimple_val, fb_rvalue);
return MIN (r0, r1);
}
#ifdef OBJCPLUS
return cp_gimplify_expr (expr_p, pre_p, post_p);
#else
return c_gimplify_expr (expr_p, pre_p, post_p);
#endif
}
/* Given a CALL expression, find the function being called. The ObjC
......
......@@ -77,43 +77,45 @@ enum gimplify_status objc_gimplify_expr (tree *, tree *, tree *);
/* ObjC-specific information pertaining to RECORD_TYPEs are stored in
the LANG_SPECIFIC structures, which may itself need allocating first. */
/* The following three macros must be overridden (in objcp/objcp-decl.h)
for Objective-C++. */
#define TYPE_OBJC_INFO(TYPE) TYPE_LANG_SPECIFIC (TYPE)->objc_info
#define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
#define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE) \
do { \
TYPE_LANG_SPECIFIC (NODE) = GGC_CNEW (struct lang_type); \
} while (0)
#define TYPE_HAS_OBJC_INFO(TYPE) \
(TYPE_LANG_SPECIFIC (TYPE) \
&& TYPE_LANG_SPECIFIC (TYPE)->objc_info)
(TYPE_LANG_SPECIFIC (TYPE) && TYPE_OBJC_INFO (TYPE))
#define TYPE_OBJC_INTERFACE(TYPE) TREE_VEC_ELT (TYPE_OBJC_INFO (TYPE), 0)
#define TYPE_OBJC_PROTOCOL_LIST(TYPE) TREE_VEC_ELT (TYPE_OBJC_INFO (TYPE), 1)
#define INIT_TYPE_OBJC_INFO(TYPE) \
do \
{ \
if (!TYPE_LANG_SPECIFIC (TYPE)) \
TYPE_LANG_SPECIFIC (TYPE) \
= ALLOC_OBJC_TYPE_LANG_SPECIFIC; \
if (!TYPE_LANG_SPECIFIC (TYPE)->objc_info) \
TYPE_LANG_SPECIFIC (TYPE)->objc_info \
ALLOC_OBJC_TYPE_LANG_SPECIFIC(TYPE); \
if (!TYPE_OBJC_INFO (TYPE)) \
TYPE_OBJC_INFO (TYPE) \
= make_tree_vec (OBJC_INFO_SLOT_ELTS); \
} \
while (0)
#define DUP_TYPE_OBJC_INFO(DST, SRC) \
do \
{ \
TYPE_LANG_SPECIFIC (DST) \
= ALLOC_OBJC_TYPE_LANG_SPECIFIC; \
ALLOC_OBJC_TYPE_LANG_SPECIFIC(DST); \
if (TYPE_LANG_SPECIFIC (SRC)) \
memcpy (TYPE_LANG_SPECIFIC (DST), \
TYPE_LANG_SPECIFIC (SRC), \
SIZEOF_OBJC_TYPE_LANG_SPECIFIC); \
TYPE_LANG_SPECIFIC (DST)->objc_info \
TYPE_OBJC_INFO (DST) \
= make_tree_vec (OBJC_INFO_SLOT_ELTS); \
} \
while (0)
/* The following two macros must be overridden (in objcp/objcp-decl.h)
for Objective-C++. */
#define ALLOC_OBJC_TYPE_LANG_SPECIFIC GGC_CNEW (struct lang_type)
#define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
#define TYPED_OBJECT(TYPE) \
(TREE_CODE (TYPE) == RECORD_TYPE \
&& TYPE_HAS_OBJC_INFO (TYPE) \
......@@ -170,6 +172,7 @@ struct imp_entry GTY(())
tree imp_template;
tree class_decl; /* _OBJC_CLASS_<my_name>; */
tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
BOOL_BITFIELD has_cxx_cdtors : 1;
};
extern GTY(()) struct imp_entry *imp_list;
......@@ -191,6 +194,7 @@ enum objc_tree_index
OCTI_SELF_DECL,
OCTI_UMSG_DECL,
OCTI_UMSG_FAST_DECL,
OCTI_UMSG_SUPER_DECL,
OCTI_UMSG_STRET_DECL,
OCTI_UMSG_SUPER_STRET_DECL,
......@@ -241,6 +245,9 @@ enum objc_tree_index
OCTI_UUCLS_SUPER_REF,
OCTI_METH_TEMPL,
OCTI_IVAR_TEMPL,
OCTI_METH_LIST_TEMPL,
OCTI_METH_PROTO_LIST_TEMPL,
OCTI_IVAR_LIST_TEMPL,
OCTI_SYMTAB_TEMPL,
OCTI_MODULE_TEMPL,
OCTI_SUPER_TEMPL,
......@@ -278,6 +285,11 @@ enum objc_tree_index
OCTI_CATCH_TYPE,
OCTI_EXECCLASS_DECL,
OCTI_ASSIGN_IVAR_DECL,
OCTI_ASSIGN_IVAR_FAST_DECL,
OCTI_ASSIGN_GLOBAL_DECL,
OCTI_ASSIGN_STRONGCAST_DECL,
OCTI_MAX
};
......@@ -297,6 +309,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define self_decl objc_global_trees[OCTI_SELF_DECL]
#define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
#define umsg_fast_decl objc_global_trees[OCTI_UMSG_FAST_DECL]
#define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
#define umsg_stret_decl objc_global_trees[OCTI_UMSG_STRET_DECL]
#define umsg_super_stret_decl objc_global_trees[OCTI_UMSG_SUPER_STRET_DECL]
......@@ -408,8 +421,19 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define execclass_decl objc_global_trees[OCTI_EXECCLASS_DECL]
#define objc_assign_ivar_decl objc_global_trees[OCTI_ASSIGN_IVAR_DECL]
#define objc_assign_ivar_fast_decl \
objc_global_trees[OCTI_ASSIGN_IVAR_FAST_DECL]
#define objc_assign_global_decl objc_global_trees[OCTI_ASSIGN_GLOBAL_DECL]
#define objc_assign_strong_cast_decl \
objc_global_trees[OCTI_ASSIGN_STRONGCAST_DECL]
#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
#define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
#define objc_method_list_ptr objc_global_trees[OCTI_METH_LIST_TEMPL]
#define objc_method_proto_list_ptr \
objc_global_trees[OCTI_METH_PROTO_LIST_TEMPL]
#define objc_ivar_list_ptr objc_global_trees[OCTI_IVAR_LIST_TEMPL]
#define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
#define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
#define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment