From: Iain Sandoe Date: Sun, 1 Mar 2026 00:12:04 +0000 (+0000) Subject: Objective-C,C++: Rework metadata generation [PR124260]. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6317befec95f7829da7cb27870279d5d284e96f0;p=thirdparty%2Fgcc.git Objective-C,C++: Rework metadata generation [PR124260]. Objective-C metadata communicates the properties of a compiled module to the runtime (for example the structure of classes). These data are compile-time literals, and (from the perspective of the compiler) read-only. However, they are not compile-time constants, and may not be placed into read-only memory - since the runtime will update them as needed. They must be preserved even if (at LTO-time) they might appear to be unused - for the same reason, the runtime does use them. Throughout the implementation these are represented by CONSTRUCTORS and the problem reported was that these were lacking suitable indices (which might be a numerical constant in the case of arrays, or a ref to a structure member in the case of structure intializer). Further the initializers should be typed appropriately. We also take this opportunity to identify that we are building metdata objects by renaming the internal APIs accordingly. While this change is relatively large, it is a repetitive one - add the indices and type information (and to use the renamed APIs for this). PR objc/124260 gcc/objc/ChangeLog: * objc-act.cc (objc_build_constructor): Check sanity of arguments. Remove special-casing for Objective-C++. * objc-gnu-runtime-abi-01.cc (build_selector_table_decl, gnu_runtime_abi_01_class_decl,gnu_runtime_abi_01_metaclass_decl, gnu_runtime_abi_01_category_decl, gnu_runtime_abi_01_protocol_decl, gnu_runtime_abi_01_string_decl, gnu_runtime_abi_01_build_typed_selector_reference, gnu_runtime_abi_01_get_protocol_reference, gnu_runtime_abi_01_build_const_string_constructor, generate_classref_translation_entry, handle_impent, build_protocol_initializer, generate_protocol_list, generate_v1_meth_descriptor_table, generate_protocols, generate_dispatch_table, build_category_initializer,generate_category, build_shared_structure_initializer, generate_ivars_list, generate_class_structures, handle_class_ref, build_gnu_selector_translation_table,generate_static_references, init_def_list, init_objc_symtab, generate_objc_symtab_decl): Use revised names for meta-data decl start/finish. Add integer indicies to array and field ids to aggregate constructors. * objc-next-runtime-abi-01.cc (next_runtime_abi_01_class_decl, next_runtime_abi_01_metaclass_decl, next_runtime_abi_01_category_decl, next_runtime_abi_01_protocol_decl, next_runtime_abi_01_string_decl, build_class_reference_decl, build_selector_reference_decl, build_objc_method_call, next_runtime_abi_01_get_protocol_reference, next_runtime_abi_01_build_const_string_constructor, generate_v1_meth_descriptor_table, generate_v1_objc_protocol_extension, build_v1_property_table_initializer, generate_v1_property_table, generate_v1_protocol_list, build_v1_protocol_initializer, generate_v1_protocols, generate_dispatch_table, build_v1_category_initializer, generate_v1_category, generate_objc_class_ext, build_v1_shared_structure_initializer, generate_ivars_list, generate_v1_class_structs, init_def_list, init_objc_symtab, generate_objc_symtab_decl, generate_classref_translation_entry, next_sjlj_build_try_catch_finally): Likewise. * objc-next-runtime-abi-02.cc (create_extern_decl) Renamed to create_extern_meta. (create_hidden_decl): Renamed to create_hidden_meta. (create_global_decl): Renamed to create_global_meta. (next_runtime_02_initialize, next_runtime_abi_02_class_decl, next_runtime_abi_02_metaclass_decl, next_runtime_abi_02_category_decl, next_runtime_abi_02_protocol_decl, next_runtime_abi_02_string_decl, build_v2_class_reference_decl, build_selector_reference_decl, build_v2_message_reference_decl, build_v2_protocollist_ref_decl, objc_v2_build_ivar_ref, build_v2_superclass_ref_decl, next_runtime_abi_02_setup_const_string_class_decl, next_runtime_abi_02_build_const_string_constructor, build_v2_message_ref_translation_table, build_v2_classrefs_table, build_v2_super_classrefs_table, build_v2_address_table, build_v2_protocol_list_translation_table, build_v2_protocol_list_address_table, generate_v2_protocol_list, build_v2_descriptor_table_initializer, generate_v2_meth_descriptor_table, generate_v2_meth_type_list, build_v2_property_table_initializer, generate_v2_property_table, build_v2_protocol_initializer, generate_v2_protocols, generate_v2_dispatch_table, build_v2_category_initializer, generate_v2_category, ivar_offset_ref, build_v2_ivar_list_initializer, generate_v2_ivars_list, build_v2_class_t_initializer, build_v2_class_ro_t_initializer, generate_v2_class_structs, build_v2_ivar_offset_ref_table, objc_generate_v2_next_metadata, objc2_build_ehtype_initializer, build_ehtype, build_v2_eh_catch_objects, next_runtime_02_eh_type):Use revised names for meta-data decl start/finish. Add integer indicies to array and field ids to aggregate constructors. * objc-runtime-shared-support.cc (build_sized_array_type): Update to use newer APIs. (start_var_decl): Renamed to start_meta_decl. Updated to handle constructors that have indices and are typed. (finish_var_decl): Renamed to finish_meta_decl. Updated to handle constructors that have indices and are typed. (build_method_list_template, build_descriptor_table_initializer, build_dispatch_table_initializer, init_module_descriptor, build_module_descriptor, build_ivar_list_initializer, build_next_selector_translation_table, generate_strings): Use revised names for meta-data decl start/finish. Add integer indicies to array and field ids to aggregate constructors. * objc-runtime-shared-support.h (start_var_decl): Renamed to start_meta_decl. (finish_var_decl): Renamed to finish_meta_decl. (first_type_field, next_type_field): New. gcc/objcp/ChangeLog: * objcp-decl.h (finish_decl): Update to set the flag indicating that the constructor is a constant init. Signed-off-by: Iain Sandoe --- diff --git a/gcc/objc/objc-act.cc b/gcc/objc/objc-act.cc index f41a8b42b6d..3ed82fe823e 100644 --- a/gcc/objc/objc-act.cc +++ b/gcc/objc/objc-act.cc @@ -3386,17 +3386,12 @@ objc_build_string_object (tree string) tree objc_build_constructor (tree type, vec *elts) { + gcc_checking_assert (!elts || (*elts)[0].index); tree constructor = build_constructor (type, elts); TREE_CONSTANT (constructor) = 1; TREE_STATIC (constructor) = 1; TREE_READONLY (constructor) = 1; - -#ifdef OBJCPLUS - /* If we know the initializer, then set the type to what C++ expects. */ - if (elts && !(*elts)[0].index) - TREE_TYPE (constructor) = init_list_type_node; -#endif return constructor; } diff --git a/gcc/objc/objc-gnu-runtime-abi-01.cc b/gcc/objc/objc-gnu-runtime-abi-01.cc index 333882d1344..836b4ae92f3 100644 --- a/gcc/objc/objc-gnu-runtime-abi-01.cc +++ b/gcc/objc/objc-gnu-runtime-abi-01.cc @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "stringpool.h" #include "attribs.h" +#include "stor-layout.h" #ifdef OBJCPLUS #include "cp/cp-tree.h" @@ -495,9 +496,11 @@ build_selector_table_decl (void) tree temp; build_selector_template (); - temp = build_array_type (objc_selector_template, NULL_TREE); - UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE"); + /* We need a forward reference, but do not know the real size at this + point. */ + temp = build_sized_array_type (objc_selector_template, 1); + UOBJC_SELECTOR_TABLE_decl = start_meta_decl (temp, "_OBJC_SELECTOR_TABLE"); /* Squash `defined but not used' warning check_global_declaration. */ TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1; OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base); @@ -520,7 +523,7 @@ gnu_runtime_abi_01_class_decl (tree klass) char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_Class_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_class_template, buf); + decl = start_meta_decl (objc_class_template, buf); OBJCMETA (decl, objc_meta, meta_base); return decl; } @@ -532,7 +535,7 @@ gnu_runtime_abi_01_metaclass_decl (tree klass) char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_class_template, buf); + decl = start_meta_decl (objc_class_template, buf); OBJCMETA (decl, objc_meta, meta_base); return decl; } @@ -545,7 +548,7 @@ gnu_runtime_abi_01_category_decl (tree klass) snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s", IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)), IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_category_template, buf); + decl = start_meta_decl (objc_category_template, buf); OBJCMETA (decl, objc_meta, meta_base); return decl; } @@ -559,7 +562,7 @@ gnu_runtime_abi_01_protocol_decl (tree p) /* static struct _objc_protocol _OBJC_Protocol_; */ snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - decl = start_var_decl (objc_protocol_template, buf); + decl = start_meta_decl (objc_protocol_template, buf); OBJCMETA (decl, objc_meta, meta_base); return decl; } @@ -568,7 +571,7 @@ static tree gnu_runtime_abi_01_string_decl (tree type, const char *name, string_section where ATTRIBUTE_UNUSED) { - tree decl = start_var_decl (type, name); + tree decl = start_meta_decl (type, name); OBJCMETA (decl, objc_meta, meta_base); return decl; } @@ -652,7 +655,7 @@ gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident, return_at_index: expr = build_unary_op (loc, ADDR_EXPR, build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl, - build_int_cst (NULL_TREE, index)), + size_int (index)), 1); return convert (objc_selector_type, expr); } @@ -760,6 +763,7 @@ gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p) if (!PROTOCOL_FORWARD_DECL (p)) PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p); + TREE_ADDRESSABLE (PROTOCOL_FORWARD_DECL (p)) = true; expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); /* ??? Ideally we'd build the reference with objc_protocol_type directly, @@ -919,14 +923,15 @@ gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string, vec *v = NULL; /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */ - fields = TYPE_FIELDS (internal_const_str_type); + fields = first_type_field (internal_const_str_type); CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0)); - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); + TREE_ADDRESSABLE (string) = true; CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, ADDR_EXPR, string, 1)); - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length)); constructor = objc_build_constructor (internal_const_str_type, v); @@ -1030,7 +1035,7 @@ generate_classref_translation_entry (tree chain) but will be optimized away unless we force it. */ DECL_PRESERVE_P (decl) = 1; OBJCMETA (decl, objc_meta, meta_base); - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); return; } @@ -1077,23 +1082,18 @@ handle_impent (struct imp_entry *impent) } { - tree decl, init; - - init = integer_zero_node; - decl = build_decl (input_location, - VAR_DECL, get_identifier (string), TREE_TYPE (init)); - TREE_PUBLIC (decl) = 1; - TREE_READONLY (decl) = 1; - TREE_USED (decl) = 1; - TREE_CONSTANT (decl) = 1; - DECL_CONTEXT (decl) = NULL_TREE; - DECL_ARTIFICIAL (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */ - /* We must force the reference. */ - DECL_PRESERVE_P (decl) = 1; - - finish_var_decl(decl, init) ; + tree decl = start_meta_decl (integer_type_node, string); + TREE_READONLY (decl) = true; + TREE_PUBLIC (decl) = true; + TREE_USED (decl) = true; + /* We must keep this even if LTO can see it is not directly used. */ + DECL_PRESERVE_P (decl) = true; + DECL_IGNORED_P (decl) = false; +#ifdef OBJCPLUS + DECL_THIS_STATIC (decl) = false; +#endif + tree init = build_zero_cst (integer_type_node); + finish_meta_decl (decl, init) ; } } @@ -1101,35 +1101,36 @@ tree build_protocol_initializer (tree type, tree protocol_name, tree protocol_list, tree inst_methods, tree class_methods) { - tree expr, ttyp; - location_t loc; vec *inits = NULL; - /* TODO: pass the loc in or find it from args. */ - loc = input_location; - ttyp = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))); + tree ttyp = build_pointer_type (xref_tag (RECORD_TYPE, + get_identifier (UTAG_CLASS))); /* Filling the "isa" in with a version allows the runtime system to detect this ... */ - expr = build_int_cst (ttyp, PROTOCOL_VERSION); - - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); - - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list); + tree expr = build_int_cst (ttyp, PROTOCOL_VERSION); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_list); - ttyp = objc_method_proto_list_ptr; + /* TODO: pass the loc in or find it from args. */ + location_t loc = input_location; + ttyp = objc_method_proto_list_ptr; if (inst_methods) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); else expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); if (class_methods) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); else expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); return objc_build_constructor (type, inits); } @@ -1137,11 +1138,7 @@ build_protocol_initializer (tree type, tree protocol_name, tree protocol_list, static tree generate_protocol_list (tree i_or_p, tree klass_ctxt) { - tree array_type, ptype, refs_decl, lproto, e, plist; - vec *v = NULL; - char buf[BUFSIZE]; - int size = 0; - + tree plist; switch (TREE_CODE (i_or_p)) { case CLASS_INTERFACE_TYPE: @@ -1156,17 +1153,22 @@ generate_protocol_list (tree i_or_p, tree klass_ctxt) } /* Compute size. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + int size = 0; + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) size++; /* Build initializer. */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); - e = build_int_cst (build_pointer_type (objc_protocol_template), size); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + vec *v = NULL; + unsigned n = 0; + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, build_int_cst (NULL_TREE, 0)); + tree e = build_int_cst (build_pointer_type (objc_protocol_template), size); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, e); + + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) { tree pval = TREE_VALUE (lproto); @@ -1176,12 +1178,13 @@ generate_protocol_list (tree i_or_p, tree klass_ctxt) tree fwref = PROTOCOL_FORWARD_DECL (pval); location_t loc = DECL_SOURCE_LOCATION (fwref) ; e = build_unary_op (loc, ADDR_EXPR, fwref, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, e); } } /* static struct objc_protocol *refs[n]; */ - + char buf[BUFSIZE]; switch (TREE_CODE (i_or_p)) { case PROTOCOL_INTERFACE_TYPE: @@ -1201,12 +1204,11 @@ generate_protocol_list (tree i_or_p, tree klass_ctxt) gcc_unreachable (); } - ptype = build_pointer_type (objc_protocol_template); - array_type = build_sized_array_type (ptype, size + 3); - refs_decl = start_var_decl (array_type, buf); + tree ptype = build_pointer_type (objc_protocol_template); + tree array_type = build_sized_array_type (ptype, size + 3); + tree refs_decl = start_meta_decl (array_type, buf); OBJCMETA (refs_decl, objc_meta, meta_base); - finish_var_decl (refs_decl, - objc_build_constructor (TREE_TYPE (refs_decl), v)); + finish_meta_decl (refs_decl, objc_build_constructor (array_type, v)); return refs_decl; } @@ -1214,33 +1216,31 @@ generate_protocol_list (tree i_or_p, tree klass_ctxt) static tree generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix) { - tree method_list_template, initlist, decl; - int size; - vec *v = NULL; - char buf[BUFSIZE]; - if (!chain || !prefix) return NULL_TREE; if (!objc_method_prototype_template) objc_method_prototype_template = build_method_prototype_template (); - size = list_length (chain); - method_list_template = - build_method_prototype_list_template (objc_method_prototype_template, - size); + int size = list_length (chain); + tree method_list_template + = build_method_prototype_list_template (objc_method_prototype_template, + size); + char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "%s_%s", prefix, IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); - decl = start_var_decl (method_list_template, buf); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); - initlist = - build_descriptor_table_initializer (objc_method_prototype_template, - chain); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + tree decl = start_meta_decl (method_list_template, buf); + vec *v = NULL; + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, size)); + tree initlist + = build_descriptor_table_initializer (objc_method_prototype_template, + chain); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); OBJCMETA (decl, objc_meta, meta_base); - finish_var_decl (decl, objc_build_constructor (method_list_template, v)); + finish_meta_decl (decl, objc_build_constructor (method_list_template, v)); return decl; } @@ -1341,14 +1341,13 @@ generate_protocols (void) /* static struct objc_protocol _OBJC_PROTOCOL_; */ protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); - + tree prot_ptr = build_pointer_type (objc_protocol_template); if (refs_decl) - refs_expr = convert (build_pointer_type (build_pointer_type - (objc_protocol_template)), - build_unary_op (input_location, - ADDR_EXPR, refs_decl, 0)); + refs_expr + = convert (prot_ptr, build_unary_op (input_location, ADDR_EXPR, + refs_decl, 0)); else - refs_expr = build_int_cst (NULL_TREE, 0); + refs_expr = build_zero_cst (prot_ptr); /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set by generate_method_descriptors, which is called above. */ @@ -1356,34 +1355,33 @@ generate_protocols (void) protocol_name_expr, refs_expr, UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl); - finish_var_decl (decl, initlist); + finish_meta_decl (decl, initlist); } } static tree generate_dispatch_table (tree chain, const char *name) { - tree decl, method_list_template, initlist; - vec *v = NULL; - int size = list_length (chain); - if (!objc_method_template) objc_method_template = build_method_template (); - method_list_template = build_method_list_template (objc_method_template, - size); - initlist = build_dispatch_table_initializer (objc_method_template, chain); - - decl = start_var_decl (method_list_template, name); + int size = list_length (chain); + tree method_list_template + = build_method_list_template (objc_method_template, size); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (integer_type_node, size)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + tree decl = start_meta_decl (method_list_template, name); + vec *v = NULL; + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, integer_zero_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (integer_type_node, size)); + tree initlist + = build_dispatch_table_initializer (objc_method_template, chain); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); OBJCMETA (decl, objc_meta, meta_base); - finish_var_decl (decl, - objc_build_constructor (TREE_TYPE (decl), v)); + finish_meta_decl (decl, objc_build_constructor (TREE_TYPE (decl), v)); return decl; } @@ -1394,36 +1392,38 @@ build_category_initializer (tree type, tree cat_name, tree class_name, tree inst_methods, tree class_methods, tree protocol_list) { - tree expr, ltyp; - location_t loc; vec *v = NULL; + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, cat_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, class_name); + tree ltyp = objc_method_list_ptr; /* TODO: pass the loc in or find it from args. */ - /* TODO: pass the loc in or find it from args. */ - loc = UNKNOWN_LOCATION; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name); - - ltyp = objc_method_list_ptr; + location_t loc = UNKNOWN_LOCATION; + tree expr; if (inst_methods) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); else expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (class_methods) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); else expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* protocol_list = */ ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); if (protocol_list) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); return objc_build_constructor (type, v); } @@ -1477,7 +1477,7 @@ generate_category (struct imp_entry *impent) inst_methods, class_methods, protocol_decl); /* Finish and initialize the forward decl. */ - finish_var_decl (cat_decl, initlist); + finish_meta_decl (cat_decl, initlist); impent->class_decl = cat_decl; } @@ -1503,77 +1503,85 @@ build_shared_structure_initializer (tree type, tree isa, tree super, tree dispatch_table, tree ivar_list, tree protocol_list) { - tree expr, ltyp; vec *v = NULL; /* isa = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, isa); /* super_class = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, super); /* name = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, default_conversion (name)); /* version = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (long_integer_type_node, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + build_int_cst (long_integer_type_node, 0)); /* info = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (long_integer_type_node, status)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + build_int_cst (long_integer_type_node, status)); /* instance_size = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - convert (long_integer_type_node, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, convert (long_integer_type_node, size)); /* objc_ivar_list = */ - if (!ivar_list) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (objc_ivar_list_ptr, 0)); - else + fields = next_type_field (fields); + if (ivar_list) { - expr = convert (objc_ivar_list_ptr, - build_unary_op (input_location, ADDR_EXPR, - ivar_list, 0)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree expr = convert (objc_ivar_list_ptr, + build_unary_op (input_location, ADDR_EXPR, + ivar_list, 0)); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); } + else + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (objc_ivar_list_ptr)); /* objc_method_list = */ - if (!dispatch_table) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - convert (objc_method_list_ptr, null_pointer_node)); - else - { - expr = convert (objc_method_list_ptr, - build_unary_op (input_location, ADDR_EXPR, - dispatch_table, 0)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + if (dispatch_table) + { + tree expr = convert (objc_method_list_ptr, + build_unary_op (input_location, ADDR_EXPR, + dispatch_table, 0)); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); } + else + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (objc_method_list_ptr)); /* dtable = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0)); /* subclass_list = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0)); /* sibling_class = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0)); /* protocol_list = */ - ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); - if (! protocol_list) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0)); - else + tree ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); + fields = next_type_field (fields); + if (protocol_list) { - expr = convert (ltyp, - build_unary_op (input_location, ADDR_EXPR, - protocol_list, 0)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree expr = convert (ltyp, build_unary_op (input_location, ADDR_EXPR, + protocol_list, 0)); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); } + else + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (ltyp)); /* gc_object_type = NULL */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (TREE_TYPE (fields))); return objc_build_constructor (type, v); } @@ -1582,31 +1590,27 @@ build_shared_structure_initializer (tree type, tree isa, tree super, static tree generate_ivars_list (tree chain, const char *name) { - tree initlist, ivar_list_template, decl; - int size; - vec *inits = NULL; - if (!chain) return NULL_TREE; if (!objc_ivar_template) objc_ivar_template = build_ivar_template (); - size = ivar_list_length (chain); - + int size = ivar_list_length (chain); generating_instance_variables = 1; - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); + tree ivar_list_template = build_ivar_list_template (objc_ivar_template, size); + tree initlist = build_ivar_list_initializer (objc_ivar_template, chain); generating_instance_variables = 0; - decl = start_var_decl (ivar_list_template, name); - - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); + tree decl = start_meta_decl (ivar_list_template, name); + vec *inits = NULL; + tree fields = first_type_field (ivar_list_template); + CONSTRUCTOR_APPEND_ELT (inits, fields, build_int_cst (NULL_TREE, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, initlist); OBJCMETA (decl, objc_meta, meta_base); - finish_var_decl (decl, - objc_build_constructor (TREE_TYPE (decl), inits)); + finish_meta_decl (decl, objc_build_constructor (ivar_list_template, inits)); return decl; } @@ -1710,7 +1714,7 @@ generate_class_structures (struct imp_entry *impent) CLS_META, class_methods, class_ivars, protocol_decl); - finish_var_decl (meta_decl, initlist); + finish_meta_decl (meta_decl, initlist); impent->meta_decl = meta_decl; /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ @@ -1718,8 +1722,9 @@ generate_class_structures (struct imp_entry *impent) { snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s", IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); - inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context), - buf); + inst_methods + = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context), + buf); } if ((chain = CLASS_IVARS (impent->imp_template))) @@ -1740,7 +1745,7 @@ generate_class_structures (struct imp_entry *impent) CLS_FACTORY | cls_flags, inst_methods, inst_ivars, protocol_decl); - finish_var_decl (class_decl, initlist); + finish_meta_decl (class_decl, initlist); impent->class_decl = class_decl; } @@ -1763,24 +1768,17 @@ handle_class_ref (tree chain) DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; DECL_CONTEXT (decl) = NULL_TREE; - finish_var_decl (decl, 0); + finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE); /* Make a decl for the address. */ sprintf (string, "__objc_class_ref_%s", name); - exp = build1 (ADDR_EXPR, string_type_node, decl); - decl = build_decl (input_location, - VAR_DECL, get_identifier (string), string_type_node); - TREE_STATIC (decl) = 1; + decl = start_meta_decl (ptr_type_node, name); TREE_USED (decl) = 1; DECL_READ_P (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; - /* We must force the reference. */ DECL_PRESERVE_P (decl) = 1; - - DECL_CONTEXT (decl) = NULL_TREE; - finish_var_decl (decl, exp); + exp = build1 (ADDR_EXPR, ptr_type_node, decl); + finish_meta_decl (decl, exp); } static tree @@ -1806,16 +1804,15 @@ get_proto_encoding (tree proto) static void build_gnu_selector_translation_table (void) { - tree chain, expr; - vec *inits = NULL; - vec *v ; - /* Cause the selector table (previously forward-declared) to be actually output. */ - for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) + tree f1 = first_type_field (objc_selector_template); + tree f2 = next_type_field (f1); + vec *inits = NULL; + unsigned n = 0; + for (tree chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) { - tree encoding; if (warn_selector) { /* TODO: improve on the location for the diagnostic. */ @@ -1823,85 +1820,92 @@ build_gnu_selector_translation_table (void) diagnose_missing_method (TREE_VALUE (chain), loc); } - v = NULL; - expr = build_selector (TREE_VALUE (chain)); - encoding = get_proto_encoding (TREE_PURPOSE (chain)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding); + vec *v = NULL; + tree expr = build_selector (TREE_VALUE (chain)); + tree encoding = get_proto_encoding (TREE_PURPOSE (chain)); + CONSTRUCTOR_APPEND_ELT (v, f1, expr); + CONSTRUCTOR_APPEND_ELT (v, f2, encoding); expr = objc_build_constructor (objc_selector_template, v); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, expr); } /* each element in the chain */ /* List terminator. */ - v = NULL; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - expr = objc_build_constructor (objc_selector_template, v); - - 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); + vec *v = NULL; + CONSTRUCTOR_APPEND_ELT (v, f1, build_zero_cst (TREE_TYPE (f1))); + CONSTRUCTOR_APPEND_ELT (v, f2, build_zero_cst (TREE_TYPE (f2))); + tree expr = objc_build_constructor (objc_selector_template, v); + + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, expr); + /* Now we know the size of the array. */ + tree type = build_sized_array_type (objc_selector_template, n); + TREE_TYPE (UOBJC_SELECTOR_TABLE_decl) = type; + relayout_decl (UOBJC_SELECTOR_TABLE_decl); + expr = objc_build_constructor (type, inits); + finish_meta_decl (UOBJC_SELECTOR_TABLE_decl, expr); } -/* Output references to all statically allocated objects. Return the DECL - for the array built. */ +/* Output references to all statically allocated objects. */ static void generate_static_references (void) { - 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_class; - char buf[BUFSIZE]; vec *decls = NULL; - - for (cl_chain = objc_static_instances, num_class = 0; - cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) + int num_class = 0; + for (tree cl_chain = objc_static_instances; + cl_chain; cl_chain = TREE_CHAIN (cl_chain)) { vec *v = NULL; - for (in_chain = TREE_PURPOSE (cl_chain); - in_chain; in_chain = TREE_CHAIN (in_chain)); - - snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class); - decl = start_var_decl (type, buf); - + /* Inner index (num_class is the outer). */ + unsigned n = 0; /* Output {class_name, ...}. */ - klass = TREE_VALUE (cl_chain); - class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + tree klass = TREE_VALUE (cl_chain); + tree class_name + = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, build_unary_op (input_location, ADDR_EXPR, class_name, 1)); /* Output {..., instance, ...}. */ - for (in_chain = TREE_PURPOSE (cl_chain); + for (tree in_chain = TREE_PURPOSE (cl_chain); in_chain; in_chain = TREE_CHAIN (in_chain)) { - expr = build_unary_op (input_location, - ADDR_EXPR, TREE_VALUE (in_chain), 1); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree expr = build_unary_op (input_location, + ADDR_EXPR, TREE_VALUE (in_chain), 1); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); } /* Output {..., NULL}. */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, null_pointer_node); - expr = objc_build_constructor (TREE_TYPE (decl), v); + tree inner = build_sized_array_type (ptr_type_node, n); + char buf[BUFSIZE]; + snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class); + tree decl = start_meta_decl (inner, buf); + + tree expr = objc_build_constructor (inner, v); OBJCMETA (decl, objc_meta, meta_base); - finish_var_decl (decl, expr); - CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, + finish_meta_decl (decl, expr); + idx = build_int_cst (unsigned_type_node, num_class++); + CONSTRUCTOR_APPEND_ELT (decls, idx, build_unary_op (input_location, ADDR_EXPR, decl, 1)); } - 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"); + tree idx = build_int_cst (unsigned_type_node, num_class++); + CONSTRUCTOR_APPEND_ELT (decls, idx, null_pointer_node); + + tree outer = build_sized_array_type (ptr_type_node, num_class); + tree expr = objc_build_constructor (outer, decls); + static_instances_decl = start_meta_decl (outer, "_OBJC_STATIC_INSTANCES"); OBJCMETA (static_instances_decl, objc_meta, meta_base); - finish_var_decl (static_instances_decl, expr); + finish_meta_decl (static_instances_decl, expr); } /* Create the initial value for the `defs' field of _objc_symtab. @@ -1910,42 +1914,44 @@ generate_static_references (void) static tree init_def_list (tree type) { - tree expr; - struct imp_entry *impent; - location_t loc; vec *v = NULL; + unsigned n = 0; if (imp_count) - for (impent = imp_list; impent; impent = impent->next) + for (struct imp_entry *impent = imp_list; impent; impent = impent->next) { if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) { - loc = DECL_SOURCE_LOCATION (impent->class_decl); - expr = build_unary_op (loc, - ADDR_EXPR, impent->class_decl, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + location_t loc = DECL_SOURCE_LOCATION (impent->class_decl); + tree expr = build_unary_op (loc, + ADDR_EXPR, impent->class_decl, 0); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); } } if (cat_count) - for (impent = imp_list; impent; impent = impent->next) + for (struct imp_entry *impent = imp_list; impent; impent = impent->next) { if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) { - loc = DECL_SOURCE_LOCATION (impent->class_decl); - expr = build_unary_op (loc, - ADDR_EXPR, impent->class_decl, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + location_t loc = DECL_SOURCE_LOCATION (impent->class_decl); + tree expr = build_unary_op (loc, + ADDR_EXPR, impent->class_decl, 0); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); } } - loc = UNKNOWN_LOCATION; + location_t loc = UNKNOWN_LOCATION; /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */ + tree expr; if (static_instances_decl) expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0); else - expr = integer_zero_node; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = null_pointer_node; + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); return objc_build_constructor (type, v); } @@ -1998,43 +2004,38 @@ build_objc_symtab_template (void) static tree init_objc_symtab (tree type) { - tree field, expr, ltyp; - location_t loc; vec *v = NULL; - loc = UNKNOWN_LOCATION; - /* sel_ref_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (long_integer_type_node, 0)); /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - - ltyp = build_pointer_type (objc_selector_type); + location_t loc = UNKNOWN_LOCATION; + tree ltyp = build_pointer_type (objc_selector_type); + tree expr; if (sel_ref_chain) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, UOBJC_SELECTOR_TABLE_decl, 1)); else expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* cls_def_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (short_integer_type_node, imp_count)); /* cat_def_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (short_integer_type_node, cat_count)); /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - - field = TYPE_FIELDS (type); - field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field)))); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field))); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, init_def_list (TREE_TYPE (fields))); return objc_build_constructor (type, v); } @@ -2046,10 +2047,10 @@ static void generate_objc_symtab_decl (void) { build_objc_symtab_template (); - UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS"); + UOBJC_SYMBOLS_decl = start_meta_decl (objc_symtab_template, "_OBJC_SYMBOLS"); OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base); - finish_var_decl (UOBJC_SYMBOLS_decl, - init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); + finish_meta_decl (UOBJC_SYMBOLS_decl, + init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); } static void @@ -2180,7 +2181,7 @@ make_err_class: IDENTIFIER_POINTER (ident)); /* We have to finalize this var here, because this might be called after all the other metadata strings have been emitted. */ - finish_var_decl (decl, str); + finish_meta_decl (decl, str); } return eh_id; } diff --git a/gcc/objc/objc-next-runtime-abi-01.cc b/gcc/objc/objc-next-runtime-abi-01.cc index de115694ead..980b6bdc545 100644 --- a/gcc/objc/objc-next-runtime-abi-01.cc +++ b/gcc/objc/objc-next-runtime-abi-01.cc @@ -603,7 +603,7 @@ next_runtime_abi_01_class_decl (tree klass) char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_Class_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_class_template, buf); + decl = start_meta_decl (objc_class_template, buf); OBJCMETA (decl, objc_meta, meta_class); return decl; } @@ -615,7 +615,7 @@ next_runtime_abi_01_metaclass_decl (tree klass) char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_class_template, buf); + decl = start_meta_decl (objc_class_template, buf); OBJCMETA (decl, objc_meta, meta_metaclass); return decl; } @@ -628,7 +628,7 @@ next_runtime_abi_01_category_decl (tree klass) snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s", IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)), IDENTIFIER_POINTER (CLASS_NAME (klass))); - decl = start_var_decl (objc_category_template, buf); + decl = start_meta_decl (objc_category_template, buf); OBJCMETA (decl, objc_meta, meta_category); return decl; } @@ -643,7 +643,7 @@ next_runtime_abi_01_protocol_decl (tree p) snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - decl = start_var_decl (objc_protocol_template, buf); + decl = start_meta_decl (objc_protocol_template, buf); OBJCMETA (decl, objc_meta, meta_protocol); return decl; } @@ -651,7 +651,7 @@ next_runtime_abi_01_protocol_decl (tree p) static tree next_runtime_abi_01_string_decl (tree type, const char *name, string_section where) { - tree var = start_var_decl (type, name); + tree var = start_meta_decl (type, name); switch (where) { case class_names: @@ -684,7 +684,7 @@ build_class_reference_decl (void) char buf[BUFSIZE]; sprintf (buf, "_OBJC_ClassRefs_%d", class_reference_idx++); - decl = start_var_decl (objc_class_type, buf); + decl = start_meta_decl (objc_class_type, buf); return decl; } @@ -781,7 +781,7 @@ build_selector_reference_decl (tree ident) *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ t++; } - decl = start_var_decl (objc_selector_type, buf); + decl = start_meta_decl (objc_selector_type, buf); OBJCMETA (decl, objc_meta, meta_sel_refs); return decl; } @@ -873,6 +873,7 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype, ? umsg_fast_decl : umsg_decl) : umsg_nonnil_decl)); + TREE_ADDRESSABLE (sender) = true; method = build_fold_addr_expr_loc (loc, sender); /* Pass the object to the method. */ @@ -916,6 +917,7 @@ next_runtime_abi_01_get_protocol_reference (location_t loc, tree p) if (!PROTOCOL_FORWARD_DECL (p)) PROTOCOL_FORWARD_DECL (p) = next_runtime_abi_01_protocol_decl (p); + TREE_ADDRESSABLE (PROTOCOL_FORWARD_DECL (p)) = true; expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); return convert (objc_protocol_type, expr); } @@ -1011,22 +1013,23 @@ static tree next_runtime_abi_01_build_const_string_constructor (location_t loc, tree string, int length) { - tree constructor, fields; vec *v = NULL; /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */ - fields = TYPE_FIELDS (internal_const_str_type); + tree fields = first_type_field (internal_const_str_type); + TREE_ADDRESSABLE (string_class_decl) = true; CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, ADDR_EXPR, string_class_decl, 0)); - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); + TREE_ADDRESSABLE (string) = true; CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, ADDR_EXPR, string, 1)); /* ??? check if this should be long. */ - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length)); - constructor = objc_build_constructor (internal_const_str_type, v); + tree constructor = objc_build_constructor (internal_const_str_type, v); tree var = objc_build_decl (loc, CONST_DECL, NULL, TREE_TYPE (constructor)); DECL_INITIAL (var) = constructor; @@ -1150,34 +1153,33 @@ static tree generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix, tree attr) { - tree method_list_template, initlist, decl; - int size; - vec *v = NULL; - char buf[BUFSIZE]; - if (!chain || !prefix) return NULL_TREE; if (!objc_method_prototype_template) objc_method_prototype_template = build_method_prototype_template (); - size = list_length (chain); - method_list_template = - build_method_prototype_list_template (objc_method_prototype_template, - size); + int size = list_length (chain); + tree method_list_template + = build_method_prototype_list_template (objc_method_prototype_template, + size); + char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "%s_%s", prefix, IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); - decl = start_var_decl (method_list_template, buf); + tree decl = start_meta_decl (method_list_template, buf); + vec *v = NULL; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); - initlist = - build_descriptor_table_initializer (objc_method_prototype_template, - chain); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, size)); + tree initlist + = build_descriptor_table_initializer (objc_method_prototype_template, + chain); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); /* Get into the right section. */ OBJCMETA (decl, objc_meta, attr); - finish_var_decl (decl, objc_build_constructor (method_list_template, v)); + finish_meta_decl (decl, objc_build_constructor (method_list_template, v)); return decl; } @@ -1191,58 +1193,70 @@ generate_v1_objc_protocol_extension (tree proto_interface, tree opt_class_meth, tree instance_props) { - int size; - location_t loc; - vec *v = NULL; - tree decl, expr; - char buf[BUFSIZE]; - - /* If there are no extensions, then don't bother... */ + /* If there are no extensions, then nothing to do. */ if (!opt_instance_meth && !opt_class_meth && !instance_props) return NULL_TREE; if (!objc_protocol_extension_template) build_v1_objc_protocol_extension_template (); + vec *v = NULL; /* uint32_t size */ - size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_protocol_extension_template)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); + int size + = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_protocol_extension_template)); + tree fields = first_type_field (objc_protocol_extension_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (integer_type_node, size)); /* Try for meaningful diagnostics. */ - loc = DECL_SOURCE_LOCATION (PROTOCOL_FORWARD_DECL (proto_interface)); + location_t loc + = DECL_SOURCE_LOCATION (PROTOCOL_FORWARD_DECL (proto_interface)); /* struct objc_method_list *optional_instance_methods; */ + tree expr; if (opt_instance_meth) - expr = convert (objc_method_list_ptr, - build_unary_op (loc, ADDR_EXPR, opt_instance_meth, 0)); + { + TREE_ADDRESSABLE (opt_instance_meth) = true; + expr = convert (objc_method_list_ptr, + build_unary_op (loc, ADDR_EXPR, opt_instance_meth, 0)); + } else - expr = convert (objc_method_list_ptr, null_pointer_node); + expr = build_zero_cst (objc_method_list_ptr); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* struct objc_method_list *optional_class_methods; */ if (opt_class_meth) - expr = convert (objc_method_list_ptr, - build_unary_op (loc, ADDR_EXPR, opt_class_meth, 0)); + { + TREE_ADDRESSABLE (opt_class_meth) = true; + expr = convert (objc_method_list_ptr, + build_unary_op (loc, ADDR_EXPR, opt_class_meth, 0)); + } else - expr = convert (objc_method_list_ptr, null_pointer_node); + expr = build_zero_cst (objc_method_list_ptr); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* struct objc_prop_list *instance_properties; */ if (instance_props) + { + TREE_ADDRESSABLE (instance_props) = true; expr = convert (objc_prop_list_ptr, build_unary_op (loc, ADDR_EXPR, instance_props, 0)); + } else - expr = convert (objc_prop_list_ptr, null_pointer_node); + expr = build_zero_cst (objc_prop_list_ptr); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); + char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_ProtocolExt_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (proto_interface))); - decl = start_var_decl (objc_protocol_extension_template, buf); + tree decl = start_meta_decl (objc_protocol_extension_template, buf); expr = objc_build_constructor (TREE_TYPE (decl), v); OBJCMETA (decl, objc_meta, meta_protocol_extension); - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); return decl; } @@ -1284,30 +1298,33 @@ static tree build_v1_property_table_initializer (tree type, tree context) { tree x; - vec *inits = NULL; - if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE) x = CLASS_PROPERTY_DECL (context); else x = IMPL_PROPERTY_DECL (context); + vec *inits = NULL; + unsigned n = 0; for (; x; x = TREE_CHAIN (x)) { vec *elemlist = NULL; - tree attribute, name_ident = PROPERTY_NAME (x); - - CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, + tree name_ident = PROPERTY_NAME (x); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (elemlist, fields, add_objc_string (name_ident, prop_names_attr)); - attribute = objc_v2_encode_prop_attr (x); - CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, + tree attribute = objc_v2_encode_prop_attr (x); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (elemlist, fields, add_objc_string (attribute, prop_names_attr)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, elemlist)); } - return objc_build_constructor (build_array_type (type, 0),inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } /* This routine builds the 'struct _prop_list_t' variable declaration and @@ -1318,12 +1335,8 @@ build_v1_property_table_initializer (tree type, tree context) static tree generate_v1_property_table (tree context, tree klass_ctxt) { - tree x, decl, initlist, property_list_template; bool is_proto = false; - vec *inits = NULL; - int init_val, size = 0; - char buf[BUFSIZE]; - + tree x; if (context) { gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE); @@ -1333,6 +1346,7 @@ generate_v1_property_table (tree context, tree klass_ctxt) else x = IMPL_PROPERTY_DECL (klass_ctxt); + int size = 0; for (; x; x = TREE_CHAIN (x)) size++; @@ -1342,14 +1356,15 @@ generate_v1_property_table (tree context, tree klass_ctxt) if (!objc_v1_property_template) objc_v1_property_template = build_v1_property_template (); - property_list_template = + tree property_list_template = build_v1_property_list_template (objc_v1_property_template, size); - initlist = build_v1_property_table_initializer (objc_v1_property_template, - is_proto ? context - : klass_ctxt); + tree initlist + = build_v1_property_table_initializer (objc_v1_property_template, + is_proto ? context : klass_ctxt); - init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v1_property_template)); + char buf[BUFSIZE]; + int init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v1_property_template)); if (is_proto) snprintf (buf, BUFSIZE, "_OBJC_ProtocolPropList_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (context))); @@ -1357,24 +1372,26 @@ generate_v1_property_table (tree context, tree klass_ctxt) snprintf (buf, BUFSIZE, "_OBJC_ClassPropList_%s", IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))); - decl = start_var_decl (property_list_template, buf); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, init_val)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); + vec *inits = NULL; + tree decl = start_meta_decl (property_list_template, buf); + tree fields = first_type_field (property_list_template); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_int_cst (integer_type_node, init_val)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_int_cst (integer_type_node, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, initlist); x = objc_build_constructor (TREE_TYPE (decl), inits); OBJCMETA (decl, objc_meta, meta_proplist); - finish_var_decl (decl, x); + finish_meta_decl (decl, x); return decl; } static tree generate_v1_protocol_list (tree i_or_p, tree klass_ctxt) { - tree array_type, ptype, refs_decl, lproto, e, plist, attr; - int size = 0; - vec *v = NULL; - char buf[BUFSIZE]; - + tree plist; switch (TREE_CODE (i_or_p)) { case CLASS_INTERFACE_TYPE: @@ -1389,17 +1406,24 @@ generate_v1_protocol_list (tree i_or_p, tree klass_ctxt) } /* Compute size. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + int size = 0; + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) size++; /* Build initializer. */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); - e = build_int_cst (build_pointer_type (objc_protocol_template), size); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + vec *v = NULL; + /* FIXME this is taking liberties with assumptions about sizes of ints and + pointers. */ + unsigned n = 0; + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, build_int_cst (integer_type_node, 0)); + tree e = build_int_cst (build_pointer_type (objc_protocol_template), size); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, e); + + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) { tree pval = TREE_VALUE (lproto); @@ -1408,12 +1432,16 @@ generate_v1_protocol_list (tree i_or_p, tree klass_ctxt) { tree fwref = PROTOCOL_FORWARD_DECL (pval); location_t loc = DECL_SOURCE_LOCATION (fwref) ; + TREE_ADDRESSABLE (fwref) = true; e = build_unary_op (loc, ADDR_EXPR, fwref, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, e); } } /* static struct objc_protocol *refs[n]; */ + char buf[BUFSIZE]; + tree attr; switch (TREE_CODE (i_or_p)) { case PROTOCOL_INTERFACE_TYPE: @@ -1436,13 +1464,13 @@ generate_v1_protocol_list (tree i_or_p, tree klass_ctxt) gcc_unreachable (); } - ptype = build_pointer_type (objc_protocol_template); - array_type = build_sized_array_type (ptype, size + 3); - refs_decl = start_var_decl (array_type, buf); + tree ptype = build_pointer_type (objc_protocol_template); + tree array_type = build_sized_array_type (ptype, size + 3); + tree refs_decl = start_meta_decl (array_type, buf); OBJCMETA (refs_decl, objc_meta, attr); - finish_var_decl (refs_decl, - objc_build_constructor (TREE_TYPE (refs_decl), v)); + finish_meta_decl (refs_decl, + objc_build_constructor (TREE_TYPE (refs_decl), v)); return refs_decl; } @@ -1452,39 +1480,51 @@ build_v1_protocol_initializer (tree type, tree protocol_name, tree protocol_list tree inst_methods, tree class_methods, tree protocol_ext) { - tree expr, ttyp; - location_t loc; - vec *inits = NULL; - if (!objc_protocol_extension_template) build_v1_objc_protocol_extension_template (); /* TODO: find a better representation of location from the inputs. */ - loc = UNKNOWN_LOCATION; - ttyp = build_pointer_type (objc_protocol_extension_template); + location_t loc = UNKNOWN_LOCATION; + tree ttyp = build_pointer_type (objc_protocol_extension_template); /* Instead of jamming the protocol version number into the isa, we pass either a pointer to the protocol extension - or NULL. */ + tree expr; if (protocol_ext) - expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, protocol_ext, 0)); + { + TREE_ADDRESSABLE (protocol_ext) = true; + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, protocol_ext, 0)); + } else - expr = convert (ttyp, null_pointer_node); + expr = build_zero_cst (ttyp); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list); + vec *inits = NULL; + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_list); ttyp = objc_method_proto_list_ptr; if (inst_methods) - expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); + { + TREE_ADDRESSABLE (inst_methods) = true; + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); + } else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); if (class_methods) - expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); + { + TREE_ADDRESSABLE (class_methods) = true; + expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); + } else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); return objc_build_constructor (type, inits); } @@ -1625,10 +1665,13 @@ generate_v1_protocols (void) refs_type = build_pointer_type (build_pointer_type (objc_protocol_template)); if (refs_decl) - refs_expr = convert (refs_type, - build_unary_op (loc, ADDR_EXPR, refs_decl, 0)); + { + TREE_ADDRESSABLE (refs_decl) = true; + refs_expr = convert (refs_type, + build_unary_op (loc, ADDR_EXPR, refs_decl, 0)); + } else - refs_expr = convert (refs_type, null_pointer_node); + refs_expr = build_zero_cst (refs_type); if (flag_objc_abi < 1) { @@ -1638,8 +1681,8 @@ generate_v1_protocols (void) protocol_name_expr, refs_expr, UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl); - finish_var_decl (decl, initlist); - continue; + finish_meta_decl (decl, initlist); + continue; } /* else - V1 extensions. */ @@ -1658,38 +1701,37 @@ generate_v1_protocols (void) UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl, V1_ProtocolExt_decl); - finish_var_decl (decl, initlist); + finish_meta_decl (decl, initlist); } } static tree generate_dispatch_table (tree chain, const char *name, tree attr) { - tree decl, method_list_template, initlist; - vec *v = NULL; - int size; - + int size = 0; if (!chain || !name || !(size = list_length (chain))) return NULL_TREE; if (!objc_method_template) objc_method_template = build_method_template (); - method_list_template = build_method_list_template (objc_method_template, - size); - initlist = build_dispatch_table_initializer (objc_method_template, chain); + tree method_list_template + = build_method_list_template (objc_method_template, size); + tree initlist = build_dispatch_table_initializer (objc_method_template, chain); - decl = start_var_decl (method_list_template, name); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + vec *v = NULL; + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (TREE_TYPE (fields))); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (integer_type_node, size)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); + tree decl = start_meta_decl (method_list_template, name); OBJCMETA (decl, objc_meta, attr); - finish_var_decl (decl, - objc_build_constructor (TREE_TYPE (decl), v)); - + TREE_READONLY (decl) = true; + finish_meta_decl (decl, objc_build_constructor (method_list_template, v)); return decl; } @@ -1700,44 +1742,64 @@ build_v1_category_initializer (tree type, tree cat_name, tree class_name, tree protocol_list, tree property_list, location_t loc) { - tree expr, ltyp; vec *v = NULL; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, cat_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, class_name); - ltyp = objc_method_list_ptr; + tree expr; + tree ltyp = objc_method_list_ptr; if (inst_methods) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); + { + TREE_ADDRESSABLE (inst_methods) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (class_methods) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); + { + TREE_ADDRESSABLE (class_methods) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* protocol_list = */ ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); if (protocol_list) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); + { + TREE_ADDRESSABLE (protocol_list) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (flag_objc_abi >= 1) { int val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_category_template)); expr = build_int_cst (NULL_TREE, val); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); ltyp = objc_prop_list_ptr; if (property_list) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); + { + TREE_ADDRESSABLE (property_list) = true; + expr + = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); } return objc_build_constructor (type, v); @@ -1801,7 +1863,7 @@ generate_v1_category (struct imp_entry *impent) protocol_decl, V1_Property_decl, loc); - finish_var_decl (cat_decl, initlist); + finish_meta_decl (cat_decl, initlist); impent->class_decl = cat_decl; } @@ -1810,51 +1872,51 @@ generate_v1_category (struct imp_entry *impent) static tree generate_objc_class_ext (tree property_list, tree context) { - tree decl, expr, ltyp; - tree weak_ivar_layout_tree; - int size; - location_t loc; - vec *v = NULL; - char buf[BUFSIZE]; - - /* TODO: pass the loc in or find it from args. */ - loc = UNKNOWN_LOCATION; - /* const char *weak_ivar_layout TODO: Figure the ivar layouts out... */ - weak_ivar_layout_tree = NULL_TREE; - + tree weak_ivar_layout_tree = NULL_TREE; if (!property_list && !weak_ivar_layout_tree) return NULL_TREE; if (!objc_class_ext_template) build_objc_class_ext_template (); + vec *v = NULL; + tree fields = first_type_field (objc_class_ext_template); /* uint32_t size */ - size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_class_ext_template)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); + int size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_class_ext_template)); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (unsigned_type_node, size)); - ltyp = const_string_type_node; + tree expr; + tree ltyp = const_string_type_node; if (weak_ivar_layout_tree) expr = convert (ltyp, weak_ivar_layout_tree); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); + /* TODO: pass the loc in or find it from args. */ + location_t loc = UNKNOWN_LOCATION; /* struct _prop_list_t *properties; */ ltyp = objc_prop_list_ptr; if (property_list) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); + { + TREE_ADDRESSABLE (property_list) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); + char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_ClassExt_%s", IDENTIFIER_POINTER (CLASS_NAME (context))); - decl = start_var_decl (objc_class_ext_template, buf); + tree decl = start_meta_decl (objc_class_ext_template, buf); expr = objc_build_constructor (TREE_TYPE (decl), v); OBJCMETA (decl, objc_meta, meta_class_extension); - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); return decl; } @@ -1884,84 +1946,109 @@ build_v1_shared_structure_initializer (tree type, tree isa, tree super, tree dispatch_table, tree ivar_list, tree protocol_list, tree class_ext) { - tree expr, ltyp; - location_t loc; vec *v = NULL; - /* TODO: fish the location out of the input data. */ - loc = UNKNOWN_LOCATION; - /* isa = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, isa); /* super_class = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, super); /* name = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, default_conversion (name)); /* version = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (long_integer_type_node, 0)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + build_int_cst (long_integer_type_node, 0)); /* info = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_int_cst (long_integer_type_node, status)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + build_int_cst (long_integer_type_node, status)); /* instance_size = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - convert (long_integer_type_node, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + convert (long_integer_type_node, size)); /* objc_ivar_list = */ - ltyp = objc_ivar_list_ptr; + + /* TODO: fish the location out of the input data. */ + location_t loc = UNKNOWN_LOCATION; + tree ltyp = objc_ivar_list_ptr; + tree expr; if (ivar_list) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivar_list, 0)); + { + TREE_ADDRESSABLE (ivar_list) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivar_list, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* objc_method_list = */ ltyp = objc_method_list_ptr; if (dispatch_table) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, dispatch_table, 0)); + { + TREE_ADDRESSABLE (dispatch_table) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, dispatch_table, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); ltyp = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier ("objc_cache"))); /* method_cache = */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (ltyp)); /* protocol_list = */ ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); if (protocol_list) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); + { + TREE_ADDRESSABLE (protocol_list) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (flag_objc_abi >= 1) { /* TODO: figure out the ivar_layout stuff. */ - expr = convert (const_string_type_node, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (const_string_type_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (!objc_class_ext_template) build_objc_class_ext_template (); ltyp = build_pointer_type (objc_class_ext_template); if (class_ext) - expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_ext, 0)); + { + TREE_ADDRESSABLE (class_ext) = true; + expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_ext, 0)); + } else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); } else { /* sel_id = NULL */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (TREE_TYPE (fields))); /* gc_object_type = NULL */ - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_zero_cst (TREE_TYPE (fields))); } return objc_build_constructor (type, v); } @@ -1969,31 +2056,28 @@ build_v1_shared_structure_initializer (tree type, tree isa, tree super, static tree generate_ivars_list (tree chain, const char *name, tree attr) { - tree initlist, ivar_list_template, decl; - int size; - vec *inits = NULL; - if (!chain) return NULL_TREE; if (!objc_ivar_template) objc_ivar_template = build_ivar_template (); - size = ivar_list_length (chain); - + int size = ivar_list_length (chain); generating_instance_variables = 1; - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); + tree ivar_list_template = build_ivar_list_template (objc_ivar_template, size); + tree initlist = build_ivar_list_initializer (objc_ivar_template, chain); generating_instance_variables = 0; - decl = start_var_decl (ivar_list_template, name); - - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); + vec *inits = NULL; + tree fields = first_type_field (ivar_list_template); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_int_cst (integer_type_node, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, initlist); + tree decl = start_meta_decl (ivar_list_template, name); OBJCMETA (decl, objc_meta, attr); - finish_var_decl (decl, - objc_build_constructor (TREE_TYPE (decl), inits)); + finish_meta_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits)); return decl; } @@ -2102,7 +2186,7 @@ generate_v1_class_structs (struct imp_entry *impent) CLS_META, class_methods, class_ivars, protocol_decl, NULL_TREE); - finish_var_decl (meta_decl, initlist); + finish_meta_decl (meta_decl, initlist); impent->meta_decl = meta_decl; /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ @@ -2121,6 +2205,7 @@ generate_v1_class_structs (struct imp_entry *impent) inst_ivars = generate_ivars_list (chain, buf, meta_clai_vars); } + TREE_ADDRESSABLE (meta_decl) = true; initlist = build_v1_shared_structure_initializer (TREE_TYPE (class_decl), build_unary_op (loc, ADDR_EXPR, meta_decl, 0), @@ -2130,44 +2215,45 @@ generate_v1_class_structs (struct imp_entry *impent) CLS_FACTORY | cls_flags, inst_methods, inst_ivars, protocol_decl, class_ext_decl); - finish_var_decl (class_decl, initlist); + finish_meta_decl (class_decl, initlist); impent->class_decl = class_decl; } /* --- Output NeXT V1 Metadata --- */ /* Create the initial value for the `defs' field of _objc_symtab. - This is a CONSTRUCTOR. */ + This is a CONSTRUCTOR for an array. */ static tree init_def_list (tree type) { - tree expr; - location_t loc; - struct imp_entry *impent; vec *v = NULL; - + unsigned n = 0; if (imp_count) - for (impent = imp_list; impent; impent = impent->next) + for (struct imp_entry * impent = imp_list; impent; impent = impent->next) { if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) { - loc = DECL_SOURCE_LOCATION (impent->class_decl); - expr = build_unary_op (loc, + location_t loc = DECL_SOURCE_LOCATION (impent->class_decl); + TREE_ADDRESSABLE (impent->class_decl) = true; + tree expr = build_unary_op (loc, ADDR_EXPR, impent->class_decl, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); } } if (cat_count) - for (impent = imp_list; impent; impent = impent->next) + for (struct imp_entry *impent = imp_list; impent; impent = impent->next) { if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) { - loc = DECL_SOURCE_LOCATION (impent->class_decl); - expr = build_unary_op (loc, + location_t loc = DECL_SOURCE_LOCATION (impent->class_decl); + TREE_ADDRESSABLE (impent->class_decl) = true; + tree expr = build_unary_op (loc, ADDR_EXPR, impent->class_decl, 0); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (v, idx, expr); } } @@ -2225,35 +2311,30 @@ init_objc_symtab (tree type) vec *v = NULL; /* sel_ref_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (long_integer_type_node, 0)); /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, convert (build_pointer_type (objc_selector_type), integer_zero_node)); /* cls_def_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (short_integer_type_node, imp_count)); /* cat_def_cnt = { ..., 5, ... } */ - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (short_integer_type_node, cat_count)); /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - + fields = next_type_field (fields); if (imp_count || cat_count) - { - tree field = TYPE_FIELDS (type); - field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field)))); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field))); - } + CONSTRUCTOR_APPEND_ELT (v, fields, init_def_list (TREE_TYPE (fields))); return objc_build_constructor (type, v); } @@ -2265,12 +2346,12 @@ static void generate_objc_symtab_decl (void) { build_objc_symtab_template (); - UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_Symbols"); + UOBJC_SYMBOLS_decl = start_meta_decl (objc_symtab_template, "_OBJC_Symbols"); /* Allow the runtime to mark meta-data such that it can be assigned to target specific sections by the back-end. */ OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_symtab); - finish_var_decl (UOBJC_SYMBOLS_decl, - init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); + finish_meta_decl (UOBJC_SYMBOLS_decl, + init_objc_symtab (objc_symtab_template)); } /* Any target implementing NeXT ObjC m32 ABI has to ensure that objects @@ -2334,7 +2415,7 @@ generate_classref_translation_entry (tree chain) but will be optimized away unless we force it. */ DECL_PRESERVE_P (decl) = 1; OBJCMETA (decl, objc_meta, meta_class_reference); - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); return; } @@ -2723,7 +2804,7 @@ next_sjlj_build_try_catch_finally (struct objc_try_context **ctcp) /* Initialize rethrow_decl. */ t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl, - convert (objc_object_type, null_pointer_node)); + build_zero_cst (objc_object_type)); SET_EXPR_LOCATION (t, cur_try_context->try_locus); append_to_statement_list (t, &BIND_EXPR_BODY (bind)); @@ -2840,7 +2921,7 @@ make_err_class: IDENTIFIER_POINTER (ident)); /* We have to finalize this var here, because this might be called after all the other metadata strings have been emitted. */ - finish_var_decl (decl, str); + finish_meta_decl (decl, str); } return eh_id; } diff --git a/gcc/objc/objc-next-runtime-abi-02.cc b/gcc/objc/objc-next-runtime-abi-02.cc index 0ca1d86311c..1863192e80e 100644 --- a/gcc/objc/objc-next-runtime-abi-02.cc +++ b/gcc/objc/objc-next-runtime-abi-02.cc @@ -216,7 +216,9 @@ static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree, static bool next_runtime_abi_02_setup_const_string_class_decl (void); static tree next_runtime_abi_02_build_const_string_constructor (location_t, tree, int); -static tree create_extern_decl (tree, const char *); +static tree create_extern_meta (tree, const char *); +static tree create_global_meta (tree, const char *, bool = false); +static tree create_hidden_meta (tree, const char *, bool = false); static void objc_generate_v2_next_metadata (void); static bool objc2_objc_exception_attr (tree); @@ -467,16 +469,16 @@ static void next_runtime_02_initialize (void) NULL, NULL_TREE); TREE_NOTHROW (objc_v2_getprotocol_decl) = 0;*/ - UOBJC_V2_CACHE_decl = create_extern_decl (ptr_type_node, + UOBJC_V2_CACHE_decl = create_extern_meta (ptr_type_node, "_objc_empty_cache"); - - UOBJC_V2_VTABLE_decl = create_extern_decl (objc_v2_imp_type, + TREE_ADDRESSABLE (UOBJC_V2_CACHE_decl) = true; + UOBJC_V2_VTABLE_decl = create_extern_meta (objc_v2_imp_type, "_objc_empty_vtable"); + TREE_ADDRESSABLE (UOBJC_V2_VTABLE_decl) = true; /* id objc_getClass (const char *); */ - type = build_function_type_list (objc_object_type, - const_string_type_node, - NULL_TREE); + type = build_function_type_list (objc_object_type, const_string_type_node, + NULL_TREE); objc_get_class_decl = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); @@ -905,32 +907,33 @@ hash_name_enter (hash *hashlist, tree id) hashlist[slot] = obj; /* append to front */ } -/* Create a declaration "extern ;" - The var will need to be finalized (e.g. by calling finish_var_decl()). */ +/* Some of the Objective-C v2 meta-data is public. */ static tree -create_extern_decl (tree type, const char *name) +create_extern_meta (tree type, const char *name) { tree id = get_identifier (name); tree var = hash_name_lookup (extern_names, id); if (var) - return var; - /* New name. */ - var = start_var_decl (type, name); - TREE_STATIC (var) = 0; - DECL_EXTERNAL (var) = 1; - TREE_PUBLIC (var) = 1; + return var; + + /* New. */ + var = start_meta_decl (type, name); + TREE_STATIC (var) = false; + TREE_PUBLIC (var) = true; + DECL_EXTERNAL (var) = true; +#ifdef OBJCPLUS + DECL_THIS_STATIC (var) = false; +#endif hash_name_enter (extern_names, var); return var; } /* Create a globally visible definition for variable NAME of a given TYPE. The - finish_var_decl() routine will need to be called on it afterwards. */ -static tree -create_global_decl (tree type, const char *name, bool is_def = false); + finish_meta_decl() routine will need to be called on it afterwards. */ static tree -create_global_decl (tree type, const char *name, bool is_def) +create_global_meta (tree type, const char *name, bool is_def) { tree id = get_identifier (name); tree var = hash_name_lookup (extern_names, id); @@ -938,30 +941,32 @@ create_global_decl (tree type, const char *name, bool is_def) is_def = true; else { - var = start_var_decl (type, name); + var = start_meta_decl (type, name); hash_name_enter (extern_names, var); } + if (is_def) { DECL_EXTERNAL (var) = 0; TREE_STATIC (var) = 1; } TREE_PUBLIC (var) = 1; +#ifdef OBJCPLUS + DECL_THIS_STATIC (var) = false; +#endif return var; } /* Create a symbol with __attribute__ ((visibility ("hidden"))) attribute (private extern). */ -static tree -create_hidden_decl (tree type, const char *name, bool is_def = false); static tree -create_hidden_decl (tree type, const char *name, bool is_def) +create_hidden_meta (tree type, const char *name, bool is_def) { - tree decl = create_global_decl (type, name, is_def); - DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - return decl; + tree decl = create_global_meta (type, name, is_def); + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (decl) = 1; + return decl; } /* Irritatingly, we have a different superclass field name for ABI=2. */ @@ -986,7 +991,7 @@ next_runtime_abi_02_class_decl (tree klass) snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); /* ObjC2 classes are extern visible. */ - decl = create_global_decl (objc_v2_class_template, buf); + decl = create_global_meta (objc_v2_class_template, buf); OBJCMETA (decl, objc_meta, meta_class); return decl; } @@ -999,7 +1004,7 @@ next_runtime_abi_02_metaclass_decl (tree klass) snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (klass))); /* ObjC2 classes are extern visible. */ - decl = create_global_decl (objc_v2_class_template, buf); + decl = create_global_meta (objc_v2_class_template, buf); OBJCMETA (decl, objc_meta, meta_metaclass); return decl; } @@ -1012,7 +1017,7 @@ next_runtime_abi_02_category_decl (tree klass) snprintf (buf, BUFSIZE, "_OBJC_Category_%s_%s", IDENTIFIER_POINTER (CLASS_NAME (klass)), IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass))); - decl = start_var_decl (objc_v2_category_template, buf); + decl = start_meta_decl (objc_v2_category_template, buf); OBJCMETA (decl, objc_meta, meta_category); return decl; } @@ -1028,11 +1033,11 @@ next_runtime_abi_02_protocol_decl (tree p) IDENTIFIER_POINTER (PROTOCOL_NAME (p))); if (flag_next_runtime >= WEAK_PROTOCOLS_AFTER) { - decl = create_hidden_decl (objc_v2_protocol_template, buf); + decl = create_hidden_meta (objc_v2_protocol_template, buf); DECL_WEAK (decl) = true; } else - decl = start_var_decl (objc_v2_protocol_template, buf); + decl = start_meta_decl (objc_v2_protocol_template, buf); OBJCMETA (decl, objc_meta, meta_protocol); DECL_PRESERVE_P (decl) = 1; return decl; @@ -1041,7 +1046,7 @@ next_runtime_abi_02_protocol_decl (tree p) static tree next_runtime_abi_02_string_decl (tree type, const char *name, string_section where) { - tree var = start_var_decl (type, name); + tree var = start_meta_decl (type, name); switch (where) { case class_names: @@ -1080,7 +1085,7 @@ build_v2_class_reference_decl (tree ident) char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "_OBJC_ClassRef_%s", IDENTIFIER_POINTER (ident)); - decl = start_var_decl (objc_class_type, buf); + decl = start_meta_decl (objc_class_type, buf); OBJCMETA (decl, objc_meta, meta_class_ref); return decl; } @@ -1193,7 +1198,7 @@ build_selector_reference_decl (tree ident) *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ t++; } - decl = start_var_decl (objc_selector_type, buf); + decl = start_meta_decl (objc_selector_type, buf); OBJCMETA (decl, objc_meta, meta_sel_refs); return decl; } @@ -1246,7 +1251,7 @@ build_v2_message_reference_decl (tree sel_name, tree message_func_ident) *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ t++; } - decl = start_var_decl (objc_v2_message_ref_template, buf); + decl = start_meta_decl (objc_v2_message_ref_template, buf); OBJCMETA (decl, objc_meta, meta_mref); return decl; } @@ -1300,7 +1305,7 @@ build_v2_protocollist_ref_decl (tree protocol) snprintf (buf, BUFSIZE, "_OBJC_ProtocolRef_%s", IDENTIFIER_POINTER (protocol_ident)); /* TODO: other compiler versions make these hidden & weak. */ - decl = create_global_decl (objc_protocol_type, buf); + decl = create_global_meta (objc_protocol_type, buf); /* Let optimizer know that this decl is not removable. */ DECL_PRESERVE_P (decl) = 1; OBJCMETA (decl, objc_meta, meta_proto_ref); @@ -1419,7 +1424,7 @@ objc_v2_build_ivar_ref (tree datum, tree component) create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name), field); - offset = create_extern_decl (TREE_TYPE (size_zero_node), var_offset_name); + offset = create_extern_meta (TREE_TYPE (size_zero_node), var_offset_name); ftype = TREE_TYPE (field); @@ -1477,7 +1482,7 @@ build_v2_superclass_ref_decl (tree ident, bool inst) snprintf (buf, BUFSIZE, "_OBJC_%sSuperRef_%s", (inst?"":"Meta"), IDENTIFIER_POINTER (ident)); - decl = start_var_decl (objc_class_type, buf); + decl = start_meta_decl (objc_class_type, buf); OBJCMETA (decl, objc_meta, meta_superclass_ref); return decl; } @@ -1913,9 +1918,10 @@ next_runtime_abi_02_setup_const_string_class_decl (void) extern OBJC_CLASS_$_NSConstantString in its place. */ if (!string_class_decl) string_class_decl = - create_extern_decl (objc_v2_class_template, + create_extern_meta (objc_v2_class_template, IDENTIFIER_POINTER (constant_string_global_id)); - + if (string_class_decl) + TREE_ADDRESSABLE (string_class_decl) = true; return (string_class_decl != NULL_TREE); } @@ -1927,16 +1933,16 @@ next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string, vec *v = NULL; /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */ - fields = TYPE_FIELDS (internal_const_str_type); + fields = first_type_field (internal_const_str_type); CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, ADDR_EXPR, string_class_decl, 0)); - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, ADDR_EXPR, string, 1)); /* ??? check if this should be long. */ - fields = DECL_CHAIN (fields); + fields = next_type_field (fields); CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length)); constructor = objc_build_constructor (internal_const_str_type, v); @@ -2069,30 +2075,29 @@ newabi_append_ro (const char *name) static void build_v2_message_ref_translation_table (void) { - int count; - msgref_entry *ref; - if (!vec_safe_length (msgrefs)) return; + int count; + msgref_entry *ref; FOR_EACH_VEC_ELT (*msgrefs, count, ref) { - vec *initializer; - tree expr, constructor; tree struct_type = TREE_TYPE (ref->refdecl); location_t loc = DECL_SOURCE_LOCATION (ref->refdecl); + vec *initializer = NULL; - initializer = NULL; /* First 'IMP messenger' field... */ - expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0); + tree expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0); expr = convert (objc_v2_imp_type, expr); - CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr); + tree fields = first_type_field (struct_type); + CONSTRUCTOR_APPEND_ELT (initializer, fields, expr); /* ... then 'SEL name' field. */ expr = build_selector (ref->selname); - CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr); - constructor = objc_build_constructor (struct_type, initializer); - finish_var_decl (ref->refdecl, constructor); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initializer, fields, expr); + tree constructor = objc_build_constructor (struct_type, initializer); + finish_meta_decl (ref->refdecl, constructor); } } @@ -2102,12 +2107,11 @@ void build_v2_message_ref_translation_table (void) static void build_v2_classrefs_table (void) { - int count; - ident_data_tuple *ref; - if (!vec_safe_length (classrefs)) return; + int count; + ident_data_tuple *ref; FOR_EACH_VEC_ELT (*classrefs, count, ref) { tree expr = ref->ident; @@ -2118,13 +2122,13 @@ build_v2_classrefs_table (void) if (TREE_CODE (expr) == IDENTIFIER_NODE) { const char *name = objc_build_internal_classname (expr, false); - expr = create_extern_decl (objc_v2_class_template, name); + expr = create_extern_meta (objc_v2_class_template, name); expr = convert (objc_class_type, build_fold_addr_expr (expr)); } /* The runtime wants this, even if it appears unused, so we must force the output. */ DECL_PRESERVE_P (decl) = 1; - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); } } @@ -2152,10 +2156,10 @@ build_v2_super_classrefs_table (bool metaclass) if (TREE_CODE (expr) == IDENTIFIER_NODE) { const char * name = objc_build_internal_classname (expr, metaclass); - expr = create_extern_decl (objc_v2_class_template, name); + expr = create_extern_meta (objc_v2_class_template, name); expr = convert (objc_class_type, build_fold_addr_expr (expr)); } - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); } } @@ -2224,34 +2228,30 @@ has_load_impl (tree clsmeth) static void build_v2_address_table (vec *src, const char *nam, tree attr) { - int count=0; - tree type, decl, expr; - vec *initlist = NULL; - if (!vec_safe_length (src)) return; + vec *initlist = NULL; + int count=0; + tree decl, expr; FOR_EACH_VEC_ELT (*src, count, decl) { -#ifndef OBJCPLUS - tree purpose = build_int_cst (NULL_TREE, count); -#else - tree purpose = NULL_TREE; -#endif + tree idx = size_int (count); expr = convert (objc_class_type, build_fold_addr_expr (decl)); - CONSTRUCTOR_APPEND_ELT (initlist, purpose, expr); + CONSTRUCTOR_APPEND_ELT (initlist, idx, expr); } gcc_assert (count > 0); - type = build_array_type (objc_class_type, - build_index_type (build_int_cst (NULL_TREE, count - 1))); - decl = start_var_decl (type, nam); + + tree idx_type = build_index_type (size_int (count - 1)); + tree type = build_array_type (objc_class_type, idx_type); + decl = start_meta_decl (type, nam); /* The runtime wants this, even if it appears unused, so we must force the output. */ DECL_PRESERVE_P (decl) = 1; expr = objc_build_constructor (type, initlist); OBJCMETA (decl, objc_meta, attr); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); } /* Build decl = initializer; for each protocol referenced in @@ -2274,9 +2274,9 @@ build_v2_protocol_list_translation_table (void) gcc_assert (TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE); snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))); - expr = start_var_decl (objc_v2_protocol_template, buf); + expr = start_meta_decl (objc_v2_protocol_template, buf); expr = convert (objc_protocol_type, build_fold_addr_expr (expr)); - finish_var_decl (ref->refdecl, expr); + finish_meta_decl (ref->refdecl, expr); } /* TODO: Maybe we could explicitly delete the vec. now? */ } @@ -2318,16 +2318,16 @@ build_v2_protocol_list_address_table (void) IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))); if (flag_next_runtime >= WEAK_PROTOCOLS_AFTER) { - decl = create_hidden_decl (objc_protocol_type, buf, /*is def=*/true); + decl = create_hidden_meta (objc_protocol_type, buf, /*is def=*/true); DECL_WEAK (decl) = true; } else - decl = create_global_decl (objc_protocol_type, buf, /*is def=*/true); + decl = create_global_meta (objc_protocol_type, buf, /*is def=*/true); expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl)); OBJCMETA (decl, objc_meta, meta_label_protocollist); DECL_PRESERVE_P (decl) = 1; DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); } /* TODO: delete the vec. */ @@ -2340,11 +2340,7 @@ build_v2_protocol_list_address_table (void) static tree generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) { - tree refs_decl, lproto, e, plist, ptempl_p_t; - int size = 0; - vec *initlist = NULL; - char buf[BUFSIZE]; - + tree plist; if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) plist = CLASS_PROTOCOL_LIST (i_or_p); @@ -2354,18 +2350,21 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) gcc_unreachable (); /* Compute size. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + int size = 0; + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) size++; /* Build initializer. */ + vec *initlist = NULL; + tree ptempl_p_t = build_pointer_type (objc_v2_protocol_template); + tree e = build_int_cst (ptempl_p_t, size); + unsigned n = 0; + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (initlist, idx, e); - ptempl_p_t = build_pointer_type (objc_v2_protocol_template); - e = build_int_cst (ptempl_p_t, size); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) + for (tree lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) { tree pval = TREE_VALUE (lproto); @@ -2375,12 +2374,14 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) tree fwref = PROTOCOL_FORWARD_DECL (pval); location_t loc = DECL_SOURCE_LOCATION (fwref) ; e = build_unary_op (loc, ADDR_EXPR, fwref, 0); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e); + idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (initlist, idx, e); } } /* static struct protocol_list_t *list[size]; */ + char buf[BUFSIZE]; switch (TREE_CODE (i_or_p)) { case PROTOCOL_INTERFACE_TYPE: @@ -2400,14 +2401,14 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) gcc_unreachable (); } - refs_decl = start_var_decl (build_sized_array_type (ptempl_p_t, size+1), - buf); + tree refs_decl = start_meta_decl (build_sized_array_type (ptempl_p_t, size+1), + buf); /* ObjC2 puts all these in the base section. */ OBJCMETA (refs_decl, objc_meta, meta_base); DECL_PRESERVE_P (refs_decl) = 1; DECL_USER_ALIGN (refs_decl) = 1; - finish_var_decl (refs_decl, - objc_build_constructor (TREE_TYPE (refs_decl),initlist)); + finish_meta_decl (refs_decl, + objc_build_constructor (TREE_TYPE (refs_decl), initlist)); return refs_decl; } @@ -2422,23 +2423,30 @@ static tree build_v2_descriptor_table_initializer (tree type, tree entries) { vec *initlist = NULL; + unsigned n = 0; do { vec *eltlist = NULL; - CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (eltlist, fields, build_selector (METHOD_SEL_NAME (entries))); - CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (eltlist, fields, add_objc_string (METHOD_ENCODING (entries), meth_var_types)); - CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, null_pointer_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (eltlist, fields, build_zero_cst (TREE_TYPE (fields))); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, + tree idx = size_int (n); + CONSTRUCTOR_APPEND_ELT (initlist, idx, objc_build_constructor (type, eltlist)); entries = TREE_CHAIN (entries); + n++; } while (entries); - return objc_build_constructor (build_array_type (type, 0), initlist); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), initlist); } /* struct method_list_t @@ -2478,16 +2486,11 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol, const char *prefix, tree attr, vec& all_meths) { - tree method_list_template, initlist, decl; - int size, entsize; - vec *v = NULL; - char buf[BUFSIZE]; - if (!chain || !prefix) return NULL_TREE; tree method = chain; - size = 0; + int size = 0; while (method) { if (! METHOD_ENCODING (method)) @@ -2496,26 +2499,30 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol, method = TREE_CHAIN (method); size++; } + gcc_checking_assert (size); - gcc_assert (size); - method_list_template = build_v2_method_list_template (objc_method_template, - size); + tree method_list_template + = build_v2_method_list_template (objc_method_template, size); + char buf[BUFSIZE]; snprintf (buf, BUFSIZE, "%s_%s", prefix, IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); - decl = start_var_decl (method_list_template, buf); - - entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, entsize)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); - initlist = + tree decl = start_meta_decl (method_list_template, buf); + vec *v = NULL; + int entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template)); + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, entsize)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, size)); + tree initlist = build_v2_descriptor_table_initializer (objc_method_template, chain); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); /* Get into the right section. */ OBJCMETA (decl, objc_meta, attr); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, objc_build_constructor (method_list_template, v)); + finish_meta_decl (decl, objc_build_constructor (method_list_template, v)); return decl; } @@ -2531,17 +2538,20 @@ generate_v2_meth_type_list (vec& all_meths, tree protocol, char *nam; asprintf (&nam, "%s_%s", prefix, IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); - tree decl = start_var_decl (list_type, nam); + tree decl = start_meta_decl (list_type, nam); free (nam); - vec *v = NULL; + vec *v = NULL; for (unsigned i = 0; i < size; ++i) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - add_objc_string (METHOD_ENCODING (all_meths[i]), - meth_var_types)); + { + tree idx = size_int (i); + CONSTRUCTOR_APPEND_ELT (v, idx, + add_objc_string (METHOD_ENCODING (all_meths[i]), + meth_var_types)); + } OBJCMETA (decl, objc_meta, meta_base); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, objc_build_constructor (list_type, v)); + finish_meta_decl (decl, objc_build_constructor (list_type, v)); return decl; } @@ -2552,31 +2562,35 @@ static tree build_v2_property_table_initializer (tree type, tree context) { tree x; - vec *inits = NULL; if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE) x = CLASS_PROPERTY_DECL (context); else x = IMPL_PROPERTY_DECL (context); + vec *inits = NULL; + unsigned n = 0; for (; x; x = TREE_CHAIN (x)) { vec *elemlist = NULL; /* NOTE! sections where property name/attribute go MUST change later. */ tree attribute, name_ident = PROPERTY_NAME (x); - - CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (elemlist, fields, add_objc_string (name_ident, prop_names_attr)); attribute = objc_v2_encode_prop_attr (x); - CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (elemlist, fields, add_objc_string (attribute, prop_names_attr)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, elemlist)); } - return objc_build_constructor (build_array_type (type, 0),inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } /* This routine builds the following type: @@ -2617,12 +2631,8 @@ build_v2_property_list_template (tree list_type, int size) static tree generate_v2_property_table (tree context, tree klass_ctxt) { - tree x, decl, initlist, property_list_template; bool is_proto = false; - vec *inits = NULL; - int init_val, size = 0; - char buf[BUFSIZE]; - + tree x; if (context) { gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE); @@ -2632,21 +2642,22 @@ generate_v2_property_table (tree context, tree klass_ctxt) else x = IMPL_PROPERTY_DECL (klass_ctxt); + int size = 0; for (; x; x = TREE_CHAIN (x)) size++; if (size == 0) return NULL_TREE; - property_list_template = - build_v2_property_list_template (objc_v2_property_template, - size); + tree property_list_template + = build_v2_property_list_template (objc_v2_property_template, size); - initlist = build_v2_property_table_initializer (objc_v2_property_template, - is_proto ? context - : klass_ctxt); + tree initlist + = build_v2_property_table_initializer (objc_v2_property_template, + is_proto ? context : klass_ctxt); - init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_property_template)); + int init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_property_template)); + char buf[BUFSIZE]; if (is_proto) snprintf (buf, BUFSIZE, "_OBJC_ProtocolPropList_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (context))); @@ -2654,17 +2665,20 @@ generate_v2_property_table (tree context, tree klass_ctxt) snprintf (buf, BUFSIZE, "_OBJC_ClassPropList_%s", IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))); - decl = start_var_decl (property_list_template, buf); - - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, - build_int_cst (NULL_TREE, init_val)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, - build_int_cst (NULL_TREE, size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); + tree decl = start_meta_decl (property_list_template, buf); + vec *inits = NULL; + tree fields = first_type_field (property_list_template); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_int_cst (unsigned_type_node, init_val)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_int_cst (unsigned_type_node, size)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, initlist); OBJCMETA (decl, objc_meta, meta_base); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits)); + finish_meta_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits)); return decl; } @@ -2675,79 +2689,90 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list tree property_list, tree ext_meth_types, tree demangled_name, tree class_prop_list) { - tree expr, ttyp; - location_t loc; vec *inits = NULL; - /* TODO: find a better representation of location from the inputs. */ - loc = UNKNOWN_LOCATION; - /* This is NULL for the new ABI. */ - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, - convert (objc_object_type, null_pointer_node)); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (inits, fields, + build_zero_cst (objc_object_type)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, protocol_list); - ttyp = objc_method_proto_list_ptr; + /* TODO: find a better representation of location from the inputs. */ + location_t loc = UNKNOWN_LOCATION; + tree expr; + tree ttyp = objc_method_proto_list_ptr; if (inst_methods) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); if (class_methods) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); if (opt_ins_meth) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_ins_meth, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); if (opt_cls_meth) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_cls_meth, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); ttyp = objc_prop_list_ptr; if (property_list) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); /* const uint32_t size; = sizeof(struct protocol_t) */ expr = build_int_cst (integer_type_node, TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_protocol_template))); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); /* const uint32_t flags; = 0 */ - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, integer_zero_node); ttyp = build_pointer_type (string_type_node); if (ext_meth_types) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); ttyp = string_type_node; if (demangled_name) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); ttyp = objc_prop_list_ptr; if (class_prop_list) expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0)); else - expr = convert (ttyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); + expr = build_zero_cst (ttyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, expr); return objc_build_constructor (type, inits); } @@ -2834,7 +2859,7 @@ generate_v2_protocols (void) opt_inst_meth, opt_class_meth, props, ext_meth_types, demangled_name,class_prop_list); - finish_var_decl (decl, initlist); + finish_meta_decl (decl, initlist); objc_add_to_protocol_list (p, decl); all_meths.truncate (0); } @@ -2853,31 +2878,30 @@ generate_v2_protocols (void) static tree generate_v2_dispatch_table (tree chain, const char *name, tree attr) { - tree decl, method_list_template, initlist; - vec *v = NULL; - int size, init_val; - + int size = 0; if (!chain || !name || !(size = list_length (chain))) return NULL_TREE; - method_list_template - = build_v2_method_list_template (objc_method_template, size); - initlist - = build_dispatch_table_initializer (objc_method_template, chain); - - decl = start_var_decl (method_list_template, name); + tree method_list_template + = build_v2_method_list_template (objc_method_template, size); + tree initlist + = build_dispatch_table_initializer (objc_method_template, chain); - init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + tree decl = start_meta_decl (method_list_template, name); + vec *v = NULL; + int init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template)); + tree fields = first_type_field (method_list_template); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (integer_type_node, init_val)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (integer_type_node, size)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, initlist); OBJCMETA (decl, objc_meta, attr); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, - objc_build_constructor (TREE_TYPE (decl), v)); + finish_meta_decl (decl, objc_build_constructor (TREE_TYPE (decl), v)); return decl; } @@ -2888,39 +2912,44 @@ build_v2_category_initializer (tree type, tree cat_name, tree class_name, tree protocol_list, tree property_list, location_t loc) { - tree expr, ltyp; vec *v = NULL; + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (v, fields, cat_name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, class_name); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name); - - ltyp = objc_method_list_ptr; + tree ltyp = objc_method_list_ptr; + tree expr; if (inst_methods) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); if (class_methods) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* protocol_list = */ ltyp = build_pointer_type (objc_v2_protocol_template); if (protocol_list) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); ltyp = objc_prop_list_ptr; if (property_list) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); return objc_build_constructor (type, v); } @@ -2948,7 +2977,7 @@ generate_v2_category (struct imp_entry *impent) DECL_PRESERVE_P (t) = 1; snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (cat))); - class_name_expr = create_extern_decl (objc_v2_class_template, buf); + class_name_expr = create_extern_meta (objc_v2_class_template, buf); class_name_expr = build_fold_addr_expr (class_name_expr); cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); @@ -2989,7 +3018,7 @@ generate_v2_category (struct imp_entry *impent) inst_methods, class_methods, protocol_decl, props, loc); - finish_var_decl (cat_decl, initlist); + finish_meta_decl (cat_decl, initlist); impent->class_decl = cat_decl; /* Add to list of pointers in __category_list section. */ @@ -3035,9 +3064,9 @@ ivar_offset_ref (tree class_name, tree field_decl) /* We come here if we don't find a match or at the start. */ global_var = (TREE_PUBLIC (field_decl) || TREE_PROTECTED (field_decl)); if (global_var) - decl = create_global_decl (TREE_TYPE (size_zero_node), buf); + decl = create_global_meta (TREE_TYPE (size_zero_node), buf); else - decl = create_hidden_decl (TREE_TYPE (size_zero_node), buf); + decl = create_hidden_meta (TREE_TYPE (size_zero_node), buf); /* Identify so that we can indirect these where the ABI requires. */ OBJCMETA (decl, objc_meta, meta_ivar_ref); @@ -3057,13 +3086,9 @@ static tree build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) { vec *inits = NULL; - + unsigned n = 0; do { - vec *ivar = NULL; - int val; - tree id; - /* Unnamed bitfields are ignored. */ if (!DECL_NAME (field_decl)) { @@ -3071,36 +3096,42 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) continue; } + vec *ivar = NULL; /* Set offset. */ - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (ivar, fields, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl), 0)); /* Set name. */ - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (ivar, fields, add_objc_string (DECL_NAME (field_decl), meth_var_names)); /* Set type. */ - id = add_objc_string (encode_field_decl (field_decl), - meth_var_types); - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id); + tree id = add_objc_string (encode_field_decl (field_decl), + meth_var_types); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (ivar, fields, id); /* Set alignment. */ - val = DECL_ALIGN_UNIT (field_decl); + int val = DECL_ALIGN_UNIT (field_decl); val = exact_log2 (val); - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (ivar, fields, build_int_cst (integer_type_node, val)); /* Set size. */ val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl)); - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (ivar, fields, build_int_cst (integer_type_node, val)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, - objc_build_constructor (type, ivar)); + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, ivar)); do field_decl = DECL_CHAIN (field_decl); @@ -3108,7 +3139,8 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) } while (field_decl); - return objc_build_constructor (build_array_type (type, 0), inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } /* @@ -3151,30 +3183,32 @@ build_v2_ivar_list_t_template (tree list_type, int size) static tree generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ) { - tree decl, initlist, ivar_list_template; - vec *inits = NULL; - int size, ivar_t_size; - + int size = 0; if (!chain || !name || !(size = ivar_list_length (chain))) return NULL_TREE; generating_instance_variables = 1; - ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_template, - size); + tree ivar_list_template + = build_v2_ivar_list_t_template (objc_v2_ivar_template, size); - initlist = build_v2_ivar_list_initializer (CLASS_NAME (templ), - objc_v2_ivar_template, chain); - ivar_t_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_ivar_template)); + tree initlist + = build_v2_ivar_list_initializer (CLASS_NAME (templ), + objc_v2_ivar_template, chain); + int ivar_t_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_ivar_template)); - decl = start_var_decl (ivar_list_template, name); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + tree decl = start_meta_decl (ivar_list_template, name); + vec *inits = NULL; + tree fields = first_type_field (ivar_list_template); + CONSTRUCTOR_APPEND_ELT (inits, fields, build_int_cst (integer_type_node, ivar_t_size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, build_int_cst (integer_type_node, size)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (inits, fields, initlist); OBJCMETA (decl, objc_meta, attr); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits)); + finish_meta_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits)); generating_instance_variables = 0; return decl; } @@ -3189,25 +3223,32 @@ build_v2_class_t_initializer (tree type, tree isa, tree superclass, vec *initlist = NULL; /* isa */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa); + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (initlist, fields, isa); /* superclass */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, superclass); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, superclass); /* cache */ + tree expr = null_pointer_node; if (cache) - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cache); - else - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node); + expr = cache; + + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* vtable */ + expr = null_pointer_node; if (vtable) - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, vtable); - else - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node); + expr = vtable; + + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* ro */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, ro); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, ro); return objc_build_constructor (type, initlist); } @@ -3222,79 +3263,87 @@ build_v2_class_ro_t_initializer (tree type, tree name, tree baseMethods, tree baseProtocols, tree ivars, tree property_list) { - tree expr, unsigned_char_star, ltyp; - location_t loc; vec *initlist = NULL; - /* TODO: fish out the real location from somewhere. */ - loc = UNKNOWN_LOCATION; - /* flags */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (initlist, fields, build_int_cst (integer_type_node, flags)); /* instanceStart */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, build_int_cst (integer_type_node, instanceStart)); /* instanceSize */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, build_int_cst (integer_type_node, instanceSize)); /* This ABI is currently only used on m64 NeXT. We always explicitly declare the alignment padding. */ /* reserved, pads alignment. */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, - integer_zero_node); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, integer_zero_node); /* ivarLayout */ - unsigned_char_star = build_pointer_type (unsigned_char_type_node); + tree unsigned_char_star = build_pointer_type (unsigned_char_type_node); + tree expr; if (ivarLayout) expr = ivarLayout; else - expr = convert (unsigned_char_star, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr); + expr = build_zero_cst (unsigned_char_star); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* name */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, default_conversion (name)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, default_conversion (name)); + /* TODO: fish out the real location from somewhere. */ + location_t loc = UNKNOWN_LOCATION; /* baseMethods */ - ltyp = objc_method_list_ptr; + tree ltyp = objc_method_list_ptr; if (baseMethods) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseMethods, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* baseProtocols */ ltyp = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (UTAG_V2_PROTOCOL_LIST))); + get_identifier (UTAG_V2_PROTOCOL_LIST))); if (baseProtocols) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseProtocols, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* ivars */ ltyp = objc_v2_ivar_list_ptr; if (ivars) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivars, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); /* TODO: We don't yet have the weak/strong stuff... */ /* weakIvarLayout */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, - convert (unsigned_char_star, null_pointer_node)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, + build_zero_cst (unsigned_char_star)); /* property list */ ltyp = objc_prop_list_ptr; if (property_list) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, expr); return objc_build_constructor (type, initlist); } @@ -3376,7 +3425,7 @@ generate_v2_class_structs (struct imp_entry *impent) create extern if not already declared. */ snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (my_root_int))); - root_expr = create_extern_decl (objc_v2_class_template, buf); + root_expr = create_extern_meta (objc_v2_class_template, buf); root_expr = build_fold_addr_expr (root_expr); /* Install class `isa' and `super' pointers at runtime. */ @@ -3385,20 +3434,21 @@ generate_v2_class_structs (struct imp_entry *impent) /* Similarly, for OBJC_CLASS_$_... */ snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (interface))); - class_superclass_expr = create_extern_decl (objc_v2_class_template, buf); + class_superclass_expr = create_extern_meta (objc_v2_class_template, buf); class_superclass_expr = build_fold_addr_expr (class_superclass_expr); /* ... and for OBJC_METACLASS_$_. */ snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (interface))); - metaclass_superclass_expr = create_extern_decl (objc_v2_class_template, buf); + metaclass_superclass_expr = create_extern_meta (objc_v2_class_template, buf); metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr); } else { /* Root class. */ root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0); + class_superclass_expr + = build_zero_cst (build_pointer_type (objc_v2_class_template)); metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0); - class_superclass_expr = build_int_cst (NULL_TREE, 0); flags |= 0x02; /* RO_ROOT: it is also a root meta class. */ } @@ -3411,11 +3461,12 @@ generate_v2_class_structs (struct imp_entry *impent) else protocol_decl = 0; - name_expr = add_objc_string (CLASS_NAME (impent->imp_template), - class_names); + name_expr = add_objc_string (CLASS_NAME (impent->imp_template), class_names); if (CLASS_CLS_METHODS (impent->imp_context)) { + CLASS_CLS_METHODS (impent->imp_context) + = nreverse (CLASS_CLS_METHODS (impent->imp_context)); snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s", IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); class_methods = @@ -3438,7 +3489,7 @@ generate_v2_class_structs (struct imp_entry *impent) /* So now build the META CLASS structs. */ /* static struct class_ro_t _OBJC_METACLASS_Foo = { ... }; */ - decl = start_var_decl (objc_v2_class_ro_template, + decl = start_meta_decl (objc_v2_class_ro_template, newabi_append_ro (IDENTIFIER_POINTER (DECL_NAME (metaclass_decl)))); /* TODO: ivarLayout needs t be built. */ @@ -3450,8 +3501,8 @@ generate_v2_class_structs (struct imp_entry *impent) class_ivars, NULL_TREE); /* The ROs sit in the default const section. */ OBJCMETA (decl, objc_meta, meta_base); - DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, initlist); + DECL_USER_ALIGN (decl) = true; + finish_meta_decl (decl, initlist); /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */ initlist = @@ -3463,7 +3514,7 @@ generate_v2_class_structs (struct imp_entry *impent) build_fold_addr_expr (UOBJC_V2_VTABLE_decl)); /* The class section attributes are set when they are created. */ DECL_USER_ALIGN (metaclass_decl) = 1; - finish_var_decl (metaclass_decl, initlist); + finish_meta_decl (metaclass_decl, initlist); impent->meta_decl = metaclass_decl; /* So now build the CLASS structs. */ @@ -3480,6 +3531,8 @@ generate_v2_class_structs (struct imp_entry *impent) if (CLASS_NST_METHODS (impent->imp_context)) { + CLASS_NST_METHODS (impent->imp_context) + = nreverse (CLASS_NST_METHODS (impent->imp_context)); snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s", IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); inst_methods = @@ -3530,7 +3583,7 @@ generate_v2_class_structs (struct imp_entry *impent) : instanceSize; /* static struct class_ro_t _OBJC_CLASS_Foo = { ... }; */ - decl = start_var_decl (objc_v2_class_ro_template, + decl = start_meta_decl (objc_v2_class_ro_template, newabi_append_ro (IDENTIFIER_POINTER (DECL_NAME (class_decl)))); @@ -3542,8 +3595,8 @@ generate_v2_class_structs (struct imp_entry *impent) inst_ivars, props); /* The ROs sit in the default const section. */ OBJCMETA (decl, objc_meta, meta_base); - DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, initlist); + DECL_USER_ALIGN (decl) = true; + finish_meta_decl (decl, initlist); /* static struct class_t _OBJC_CLASS_Foo = { ... }; */ initlist = build_v2_class_t_initializer (TREE_TYPE (class_decl), @@ -3555,7 +3608,7 @@ generate_v2_class_structs (struct imp_entry *impent) /* The class section attributes are set when they are created. */ DECL_USER_ALIGN (class_decl) = 1; - finish_var_decl (class_decl, initlist); + finish_meta_decl (class_decl, initlist); impent->class_decl = class_decl; objc_v2_add_to_class_list (class_decl); @@ -3579,7 +3632,7 @@ build_v2_ivar_offset_ref_table (void) return; FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref) - finish_var_decl (ref->decl, ref->offset); + finish_meta_decl (ref->decl, ref->offset); } static void @@ -3590,7 +3643,7 @@ objc_generate_v2_next_metadata (void) /* FIXME: Make sure that we generate no metadata if there is nothing to put into it. */ - gcc_assert (!objc_static_instances); /* Not for NeXT */ + gcc_checking_assert (!objc_static_instances); /* Not for NeXT */ build_metadata_templates (); @@ -3681,9 +3734,6 @@ build_v2_ehtype_template (void) static tree objc2_build_ehtype_initializer (tree name, tree cls) { - vec *initlist = NULL; - tree addr, offs; - /* This is done the same way as c++, missing the two first entries in the parent vtable. NOTE: there is a fix-me in the Apple/NeXT runtime source about this so, perhaps, this will change at some @@ -3691,23 +3741,28 @@ objc2_build_ehtype_initializer (tree name, tree cls) /* _objc_ehtype_vtable + 2*sizeof(void*) */ if (!next_v2_ehvtable_decl) { - next_v2_ehvtable_decl = - start_var_decl (ptr_type_node, TAG_NEXT_EHVTABLE_NAME); + next_v2_ehvtable_decl + = start_meta_decl (ptr_type_node, TAG_NEXT_EHVTABLE_NAME); TREE_STATIC (next_v2_ehvtable_decl) = 0; DECL_EXTERNAL (next_v2_ehvtable_decl) = 1; TREE_PUBLIC (next_v2_ehvtable_decl) = 1; } - addr = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node); - offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node))); + tree addr + = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node); + tree offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node))); addr = fold_build_pointer_plus (addr, offs); - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr); + vec *initlist = NULL; + tree fields = first_type_field (objc_v2_ehtype_template); + CONSTRUCTOR_APPEND_ELT (initlist, fields, addr); /* className */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, name); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, name); /* cls */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cls); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (initlist, fields, cls); return objc_build_constructor (objc_v2_ehtype_template, initlist); } @@ -3721,16 +3776,16 @@ build_ehtype (tree name, const char *eh_name, bool weak) /* Extern ref. for the class. ??? Maybe we can look this up somewhere. */ class_name_expr = - create_extern_decl (objc_v2_class_template, + create_extern_meta (objc_v2_class_template, objc_build_internal_classname (name, false)); class_name_expr = build_fold_addr_expr (class_name_expr); - ehtype_decl = create_global_decl (objc_v2_ehtype_template, eh_name); + ehtype_decl = create_global_meta (objc_v2_ehtype_template, eh_name); if (weak) DECL_WEAK (ehtype_decl) = 1; inits = objc2_build_ehtype_initializer (name_expr, class_name_expr); OBJCMETA (ehtype_decl, objc_meta, meta_ehtype); DECL_USER_ALIGN (ehtype_decl) = 1; - finish_var_decl (ehtype_decl, inits); + finish_meta_decl (ehtype_decl, inits); return ehtype_decl; } @@ -3781,7 +3836,7 @@ static void build_v2_eh_catch_objects (void) snprintf (buf, BUFSIZE, "OBJC_EHTYPE_$_%s", IDENTIFIER_POINTER (ref->ident)); if (!impl && excpt) /* The User says this class has a catcher already. */ - ref->data = create_extern_decl (objc_v2_ehtype_template, buf); + ref->data = create_extern_meta (objc_v2_ehtype_template, buf); else /* Create a catcher, weak if it wasn't marked. */ ref->data = build_ehtype (ref->ident, buf, !excpt); @@ -3822,7 +3877,7 @@ next_runtime_02_eh_type (tree type) /* This is provided by the Apple/NeXT libobjc.dylib so we need only to reference it. */ next_v2_EHTYPE_id_decl = - start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id"); + start_meta_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id"); DECL_EXTERNAL (next_v2_EHTYPE_id_decl) = 1; TREE_PUBLIC (next_v2_EHTYPE_id_decl) = 1; TREE_STATIC (next_v2_EHTYPE_id_decl) = 0; @@ -3848,7 +3903,6 @@ next_runtime_02_eh_type (tree type) t = lookup_ehtype_ref (t); if (!t) goto err_mark_in; - return build_fold_addr_expr (t); err_mark_in: diff --git a/gcc/objc/objc-runtime-shared-support.cc b/gcc/objc/objc-runtime-shared-support.cc index d75b21c98d7..7e1c77d500d 100644 --- a/gcc/objc/objc-runtime-shared-support.cc +++ b/gcc/objc/objc-runtime-shared-support.cc @@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see #endif #include "c-family/c-objc.h" #include "objc-act.h" +#include "cgraph.h" +#include "stor-layout.h" /* 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. */ @@ -81,7 +83,7 @@ objc_finish_struct (tree type, tree fieldlist) tree build_sized_array_type (tree base_type, int size) { - tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1)); + tree index_type = build_index_type (size_int (size - 1)); return build_array_type (base_type, index_type); } @@ -106,34 +108,56 @@ add_field_decl (tree type, const char *name, tree **chain) return field; } -/* Create a global, static declaration for variable NAME of a given TYPE. The - finish_var_decl() routine will need to be called on it afterwards. */ +/* Objective-C Metadata decls (not-really variables, but we cannot use + CONST_DECL yet - as that has limitations with address fields). + Create a global, static declaration for variable NAME of a given TYPE. The + finish_meta_decl() routine will need to be called on it afterwards. */ tree -start_var_decl (tree type, const char *name) +start_meta_decl (tree type, const char *name) { +#ifdef OBJCPLUS + if (flag_next_runtime) + /* Meta-data for the NeXT runtime is expected to be 'extern "C"'. */ + push_lang_context (lang_name_c); +#endif tree name_id = get_identifier (name); tree var = objc_build_decl (input_location, VAR_DECL, name_id, type); - DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */ - TREE_STATIC (var) = 1; - DECL_IGNORED_P (var) = 1; - DECL_ARTIFICIAL (var) = 1; + TREE_STATIC (var) = true; + DECL_IGNORED_P (var) = true; + DECL_ARTIFICIAL (var) = true; + DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */ DECL_CONTEXT (var) = NULL_TREE; #ifdef OBJCPLUS - /* Meta-data for the NeXT runtime is expected to be 'extern "C"'. */ + /* Make sure that we don't stick in a mangled name for NeXT cases. */ if (flag_next_runtime) - SET_DECL_ASSEMBLER_NAME (var, name_id); - DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */ + { + SET_DECL_ASSEMBLER_NAME (var, DECL_NAME (var)); + pop_lang_context (); + } #endif return var; } -/* Finish off the variable declaration created by start_var_decl(). */ +/* Finish off the declaration created by start_meta_decl(). */ void -finish_var_decl (tree var, tree initializer) +finish_meta_decl (tree var, tree initializer) { + gcc_checking_assert (!initializer || really_constant_p (initializer)); +#if OBJCPLUS + DECL_INITIAL (var) = initializer; + if (initializer) + { + DECL_INITIALIZED_P (var) = true; + DECL_NONTRIVIALLY_INITIALIZED_P (var) = true; + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true; + } + layout_decl (var, 0); + varpool_node::finalize_decl (var); +#else finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE); +#endif } /* Just a handy wrapper for add_objc_string. */ @@ -233,7 +257,7 @@ build_method_list_template (tree list_type, int size) tree objc_ivar_list_record; tree array_type, decls, *chain = NULL; - objc_ivar_list_record = objc_start_struct (NULL_TREE); + objc_ivar_list_record = objc_start_struct (NULL); /* struct _objc__method_prototype_list *method_next; */ decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain); @@ -345,24 +369,29 @@ build_descriptor_table_initializer (tree type, tree entries) { vec *inits = NULL; + unsigned n = 0; do { vec *elts = NULL; - CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, + tree fields = first_type_field (type); + CONSTRUCTOR_APPEND_ELT (elts, fields, build_selector (METHOD_SEL_NAME (entries))); - CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (elts, fields, add_objc_string (METHOD_ENCODING (entries), meth_var_types)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, elts)); entries = DECL_CHAIN (entries); } while (entries); - return objc_build_constructor (build_array_type (type, 0), inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } tree @@ -370,36 +399,40 @@ build_dispatch_table_initializer (tree type, tree entries) { vec *inits = NULL; + unsigned n = 0; do { vec *elems = NULL; - tree expr; - CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, + tree fields = TYPE_FIELDS (type); + CONSTRUCTOR_APPEND_ELT (elems, fields, 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); + METHOD_ENCODING (entries) = encode_method_prototype (entries); - CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (elems, fields, add_objc_string (METHOD_ENCODING (entries), meth_var_types)); - expr = convert (ptr_type_node, - build_unary_op (input_location, ADDR_EXPR, - METHOD_DEFINITION (entries), 1)); - CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr); + tree expr = convert (ptr_type_node, + build_unary_op (input_location, ADDR_EXPR, + METHOD_DEFINITION (entries), 1)); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (elems, fields, expr); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, elems)); entries = DECL_CHAIN (entries); } while (entries); - return objc_build_constructor (build_array_type (type, 0), inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } /* Used only by build_*_selector_translation_table (). */ @@ -428,40 +461,42 @@ diagnose_missing_method (tree meth, location_t here) static tree init_module_descriptor (tree type, long vers) { - tree expr, ltyp; - location_t loc; vec *v = NULL; - /* No really useful place to point to. */ - loc = UNKNOWN_LOCATION; - /* version = { 1, ... } */ - expr = build_int_cst (long_integer_type_node, vers); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + tree expr = build_int_cst (long_integer_type_node, vers); + tree fields = TYPE_FIELDS (type); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* size = { ..., sizeof (struct _objc_module), ... } */ expr = convert (long_integer_type_node, size_in_bytes (objc_module_template)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* Don't provide any file name for security reasons. */ /* name = { ..., "", ... } */ expr = add_objc_string (get_identifier (""), class_names); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); /* symtab = { ..., _OBJC_SYMBOLS, ... } */ - ltyp = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (UTAG_SYMTAB))); + tree ltyp = build_pointer_type (xref_tag (RECORD_TYPE, + get_identifier (UTAG_SYMTAB))); + + /* No really useful place to point to. */ + location_t loc = UNKNOWN_LOCATION; if (UOBJC_SYMBOLS_decl) expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, UOBJC_SYMBOLS_decl, 0)); else - expr = convert (ltyp, null_pointer_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); + expr = build_zero_cst (ltyp); + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, expr); return objc_build_constructor (type, v); } @@ -498,7 +533,11 @@ build_module_descriptor (long vers, tree attr) objc_finish_struct (objc_module_template, decls); /* Create an instance of "_objc_module". */ - UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_Module"); + UOBJC_MODULES_decl = start_meta_decl (objc_module_template, "_OBJC_Module"); + +#ifdef OBJCPLUS + pop_lang_context (); +#endif /* This is the root of the metadata for defined classes and categories, it is referenced by the runtime and, therefore, needed. */ @@ -512,13 +551,10 @@ build_module_descriptor (long vers, tree attr) if (attr) DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr; - finish_var_decl (UOBJC_MODULES_decl, + TREE_ADDRESSABLE (UOBJC_MODULES_decl) = true; + finish_meta_decl (UOBJC_MODULES_decl, init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl), vers)); - -#ifdef OBJCPLUS - pop_lang_context (); -#endif } tree @@ -526,34 +562,40 @@ build_ivar_list_initializer (tree type, tree field_decl) { vec *inits = NULL; + unsigned n = 0; for (; field_decl; field_decl = DECL_CHAIN (field_decl)) if (TREE_CODE (field_decl) == FIELD_DECL) { vec *ivar = NULL; - tree id; /* Set name. */ + tree fields = TYPE_FIELDS (type); if (DECL_NAME (field_decl)) - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + CONSTRUCTOR_APPEND_ELT (ivar, fields, add_objc_string (DECL_NAME (field_decl), meth_var_names)); else /* Unnamed bit-field ivar (yuck). */ - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, + CONSTRUCTOR_APPEND_ELT (ivar, fields, build_int_cst (NULL_TREE, 0)); /* Set type. */ - id = add_objc_string (encode_field_decl (field_decl), + fields = next_type_field (fields); + tree id = add_objc_string (encode_field_decl (field_decl), meth_var_types); - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id); + CONSTRUCTOR_APPEND_ELT (ivar, fields, id); /* Set offset. */ - CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl)); - CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, + fields = next_type_field (fields); + CONSTRUCTOR_APPEND_ELT (ivar, fields, byte_position (field_decl)); + + tree idx = size_int (n++); + CONSTRUCTOR_APPEND_ELT (inits, idx, objc_build_constructor (type, ivar)); } - return objc_build_constructor (build_array_type (type, 0), inits); + tree idx_type = build_index_type (size_int (n)); + return objc_build_constructor (build_array_type (type, idx_type), inits); } /* struct { @@ -637,7 +679,7 @@ build_next_selector_translation_table (void) The runtime re-writes these on start-up, but the compiler can't see that and optimizes it away unless we force it. */ DECL_PRESERVE_P (decl) = 1; - finish_var_decl (decl, expr); + finish_meta_decl (decl, expr); } } } @@ -685,7 +727,7 @@ generate_strings (void) string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, string_expr); + finish_meta_decl (decl, string_expr); } for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) @@ -695,7 +737,7 @@ generate_strings (void) string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, string_expr); + finish_meta_decl (decl, string_expr); } for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) @@ -705,7 +747,7 @@ generate_strings (void) string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, string_expr); + finish_meta_decl (decl, string_expr); } for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain)) @@ -715,7 +757,7 @@ generate_strings (void) string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); DECL_USER_ALIGN (decl) = 1; - finish_var_decl (decl, string_expr); + finish_meta_decl (decl, string_expr); } } diff --git a/gcc/objc/objc-runtime-shared-support.h b/gcc/objc/objc-runtime-shared-support.h index b22dcf2ef8d..1ba1590499a 100644 --- a/gcc/objc/objc-runtime-shared-support.h +++ b/gcc/objc/objc-runtime-shared-support.h @@ -31,8 +31,8 @@ extern tree build_sized_array_type (tree, int); extern tree lookup_interface (tree); extern tree objc_build_constructor (tree, vec *); -extern tree start_var_decl (tree, const char *); -extern void finish_var_decl (tree, tree); +extern tree start_meta_decl (tree, const char *); +extern void finish_meta_decl (tree, tree); extern tree my_build_string (int, const char *); extern tree my_build_string_pointer (int, const char *); @@ -84,4 +84,27 @@ extern void generate_strings (void); extern void dump_interface (FILE *, tree); extern FILE *gen_declaration_file; +/* For Objective-C/C++ metadata that can be initialized like an aggregate. */ + +inline tree +first_type_field (const tree type) +{ +#ifdef OBJCPLUS + return next_aggregate_field (TYPE_FIELDS (type)); +#else + return TYPE_FIELDS (type); +#endif +} + +inline tree +next_type_field (const tree last) +{ +#ifdef OBJCPLUS + return next_aggregate_field (DECL_CHAIN (last)); +#else + return DECL_CHAIN (last); +#endif +} + + #endif /* _OBJC_RUNTIME_SHARED_SUPPORT_H_ */ diff --git a/gcc/objcp/objcp-decl.h b/gcc/objcp/objcp-decl.h index d8aa3d3c454..fa3f9031646 100644 --- a/gcc/objcp/objcp-decl.h +++ b/gcc/objcp/objcp-decl.h @@ -44,7 +44,7 @@ extern tree objcp_end_compound_stmt (tree, int); #define finish_function() \ objcp_finish_function () #define finish_decl(decl, loc, init, origtype, asmspec) \ - cp_finish_decl (decl, init, false, asmspec, 0) + cp_finish_decl (decl, init, (init && really_constant_p (init)), asmspec, 0) #define xref_tag(code, name) \ objcp_xref_tag (code, name) #define comptypes(type1, type2) \