Commit c2beaa02 by Nicola Pero Committed by Nicola Pero

Updated comments

From-SVN: r170308
parent 54ba9323
2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com> 2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-next-runtime-abi-01.c: Updated comments.
* objc-next-runtime-abi-02.c: Same.
2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_init, generate_struct_by_value_array): Updated * objc-act.c (objc_init, generate_struct_by_value_array): Updated
comments. comments.
......
...@@ -18,10 +18,10 @@ You should have received a copy of the GNU General Public License ...@@ -18,10 +18,10 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
/* This implements the original NeXT ABI (0) used for m32 code and indicated /* This implements the original NeXT ABI (0) used for m32 code and
by module version 6. It also implements the small number of additions made indicated by module version 6. It also implements the small number
for properties and optional protocol methods as ABI=1 of additions made for properties and optional protocol methods as
(module version 7). */ ABI=1 (module version 7). */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
...@@ -39,8 +39,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -39,8 +39,9 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-objc.h" #include "c-family/c-objc.h"
#include "objc-act.h" #include "objc-act.h"
/* When building Objective-C++, we are not linking against the C front-end /* When building Objective-C++, we are not linking against the C
and so need to replicate the C tree-construction functions in some way. */ front-end and so need to replicate the C tree-construction
functions in some way. */
#ifdef OBJCPLUS #ifdef OBJCPLUS
#define OBJCP_REMAP_FUNCTIONS #define OBJCP_REMAP_FUNCTIONS
#include "objcp-decl.h" #include "objcp-decl.h"
...@@ -85,9 +86,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -85,9 +86,9 @@ along with GCC; see the file COPYING3. If not see
#define TAG_MSGSEND_FAST "objc_msgSend_Fast" #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
#define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast" #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
/* The version identifies which language generation and runtime /* The version identifies which language generation and runtime the
the module (file) was compiled for, and is recorded in the module (file) was compiled for, and is recorded in the module
module descriptor. */ descriptor. */
#define OBJC_VERSION (flag_objc_abi >= 1 ? 7 : 6) #define OBJC_VERSION (flag_objc_abi >= 1 ? 7 : 6)
#define UTAG_CLASS_EXT "_objc_class_ext" #define UTAG_CLASS_EXT "_objc_class_ext"
...@@ -96,10 +97,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -96,10 +97,10 @@ along with GCC; see the file COPYING3. If not see
#define CLS_HAS_CXX_STRUCTORS 0x2000L #define CLS_HAS_CXX_STRUCTORS 0x2000L
/* rt_trees identifiers - shared between NeXT implementations. These allow /* rt_trees identifiers - shared between NeXT implementations. These
the FE to tag meta-data in a manner that survives LTO and can be used when allow the FE to tag meta-data in a manner that survives LTO and can
the runtime requires that certain meta-data items appear in particular be used when the runtime requires that certain meta-data items
named sections. */ appear in particular named sections. */
#include "objc-next-metadata-tags.h" #include "objc-next-metadata-tags.h"
extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX]; extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
...@@ -187,14 +188,15 @@ objc_next_runtime_abi_01_init (objc_runtime_hooks *rthooks) ...@@ -187,14 +188,15 @@ objc_next_runtime_abi_01_init (objc_runtime_hooks *rthooks)
return true; return true;
} }
/* We need a way to convey what kind of meta-data are represented by a given /* We need a way to convey what kind of meta-data are represented by a
variable, since each type is expected (by the runtime) to be found in a given variable, since each type is expected (by the runtime) to be
specific named section. The solution must be usable with LTO. found in a specific named section. The solution must be usable
with LTO.
The scheme used for NeXT ABI 0/1 (partial matching of variable names) is not The scheme used for NeXT ABI 0/1 (partial matching of variable
satisfactory for LTO & ABI-2. We now tag ObjC meta-data with identification names) is not satisfactory for LTO & ABI-2. We now tag ObjC
attributes in the front end. The back-end may choose to act on these as it meta-data with identification attributes in the front end. The
requires. */ back-end may choose to act on these as it requires. */
static void static void
next_runtime_abi_01_init_metadata_attributes (void) next_runtime_abi_01_init_metadata_attributes (void)
...@@ -252,7 +254,8 @@ static void next_runtime_01_initialize (void) ...@@ -252,7 +254,8 @@ static void next_runtime_01_initialize (void)
tree type; tree type;
#ifdef OBJCPLUS #ifdef OBJCPLUS
/* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by default. */ /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by
default. */
if (!global_options_set.x_flag_objc_call_cxx_cdtors) if (!global_options_set.x_flag_objc_call_cxx_cdtors)
global_options.x_flag_objc_call_cxx_cdtors = 1; global_options.x_flag_objc_call_cxx_cdtors = 1;
#endif #endif
...@@ -265,7 +268,8 @@ static void next_runtime_01_initialize (void) ...@@ -265,7 +268,8 @@ static void next_runtime_01_initialize (void)
objc_prop_list_ptr = build_pointer_type (xref_tag (RECORD_TYPE, objc_prop_list_ptr = build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier ("_prop_list_t"))); get_identifier ("_prop_list_t")));
/* Declare type of selector-objects that represent an operation name. */ /* Declare type of selector-objects that represent an operation
name. */
/* `struct objc_selector *' */ /* `struct objc_selector *' */
objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier (TAG_SELECTOR))); get_identifier (TAG_SELECTOR)));
...@@ -306,8 +310,8 @@ static void next_runtime_01_initialize (void) ...@@ -306,8 +310,8 @@ static void next_runtime_01_initialize (void)
NULL, NULL_TREE); NULL, NULL_TREE);
/* These can throw, because the function that gets called can throw /* These can throw, because the function that gets called can throw
in Obj-C++, or could itself call something that can throw even in Obj-C++, or could itself call something that can throw even in
in Obj-C. */ Obj-C. */
TREE_NOTHROW (umsg_decl) = 0; TREE_NOTHROW (umsg_decl) = 0;
TREE_NOTHROW (umsg_nonnil_decl) = 0; TREE_NOTHROW (umsg_nonnil_decl) = 0;
TREE_NOTHROW (umsg_stret_decl) = 0; TREE_NOTHROW (umsg_stret_decl) = 0;
...@@ -357,7 +361,8 @@ static void next_runtime_01_initialize (void) ...@@ -357,7 +361,8 @@ static void next_runtime_01_initialize (void)
objc_get_meta_class_decl objc_get_meta_class_decl
= add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* This is the type of all of the following functions objc_copyStruct(). */ /* This is the type of all of the following functions
objc_copyStruct(). */
type = build_function_type_list (void_type_node, type = build_function_type_list (void_type_node,
ptr_type_node, ptr_type_node,
const_ptr_type_node, const_ptr_type_node,
...@@ -385,7 +390,8 @@ static void next_runtime_01_initialize (void) ...@@ -385,7 +390,8 @@ static void next_runtime_01_initialize (void)
/* --- templates --- */ /* --- templates --- */
/* struct _objc_class { /* struct _objc_class
{
struct _objc_class *isa; struct _objc_class *isa;
struct _objc_class *super_class; struct _objc_class *super_class;
char *name; char *name;
...@@ -405,8 +411,9 @@ static void next_runtime_01_initialize (void) ...@@ -405,8 +411,9 @@ static void next_runtime_01_initialize (void)
#endif #endif
}; */ }; */
/* The 'sel_id' & 'gc_object_type' fields are not used by the NeXT runtime. /* The 'sel_id' & 'gc_object_type' fields are not used by the NeXT
We generate them for ABI==0 to maintain backward binary compatibility. */ runtime. We generate them for ABI==0 to maintain backward binary
compatibility. */
static void static void
build_v1_class_template (void) build_v1_class_template (void)
...@@ -474,16 +481,17 @@ build_v1_class_template (void) ...@@ -474,16 +481,17 @@ build_v1_class_template (void)
objc_finish_struct (objc_class_template, decls); objc_finish_struct (objc_class_template, decls);
} }
/* struct _objc_category { /* struct _objc_category
{
char *category_name; char *category_name;
char *class_name; char *class_name;
struct _objc_method_list *instance_methods; struct _objc_method_list *instance_methods;
struct _objc_method_list *class_methods; struct _objc_method_list *class_methods;
struct _objc_protocol_list *protocols; struct _objc_protocol_list *protocols;
if ABI=1 #if ABI=1
uint32_t size; // sizeof (struct _objc_category) uint32_t size; // sizeof (struct _objc_category)
struct _objc_property_list *instance_properties; // category's own @property decl. struct _objc_property_list *instance_properties; // category's own @property decl.
END #endif
}; */ }; */
static void static void
...@@ -526,11 +534,13 @@ build_v1_category_template (void) ...@@ -526,11 +534,13 @@ build_v1_category_template (void)
/* Begin code generation for protocols... /* Begin code generation for protocols...
Modified for ObjC #1 extensions. */ Modified for ObjC #1 extensions. */
/* struct _objc_protocol { /* struct _objc_protocol
IF ABI=1 {
#if ABI=1
struct _objc_protocol_extension *isa; struct _objc_protocol_extension *isa;
ElSE #else
struct _objc_class *isa; struct _objc_class *isa;
#endif
char *protocol_name; char *protocol_name;
struct _objc_protocol **protocol_list; struct _objc_protocol **protocol_list;
...@@ -1789,8 +1799,7 @@ generate_v1_category (struct imp_entry *impent) ...@@ -1789,8 +1799,7 @@ generate_v1_category (struct imp_entry *impent)
impent->class_decl = cat_decl; impent->class_decl = cat_decl;
} }
/* This routine builds the class extension used by v1 NeXT. /* This routine builds the class extension used by v1 NeXT. */
*/
static tree static tree
generate_objc_class_ext (tree property_list, tree context) generate_objc_class_ext (tree property_list, tree context)
...@@ -2357,6 +2366,9 @@ objc_generate_v1_next_metadata (void) ...@@ -2357,6 +2366,9 @@ objc_generate_v1_next_metadata (void)
tree chain, attr; tree chain, attr;
long vers; long vers;
/* FIXME: Make sure that we generate no metadata if there is nothing
to put into it. */
if (objc_static_instances) if (objc_static_instances)
gcc_unreachable (); /* Not for NeXT */ gcc_unreachable (); /* Not for NeXT */
......
...@@ -352,7 +352,8 @@ static void next_runtime_02_initialize (void) ...@@ -352,7 +352,8 @@ static void next_runtime_02_initialize (void)
{ {
tree type; tree type;
#ifdef OBJCPLUS #ifdef OBJCPLUS
/* For all objc ABIs -fobjc-call-cxx-cdtors is on by default. */ /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by
default. */
if (!global_options_set.x_flag_objc_call_cxx_cdtors) if (!global_options_set.x_flag_objc_call_cxx_cdtors)
global_options.x_flag_objc_call_cxx_cdtors = 1; global_options.x_flag_objc_call_cxx_cdtors = 1;
#endif #endif
...@@ -460,7 +461,8 @@ static void next_runtime_02_initialize (void) ...@@ -460,7 +461,8 @@ static void next_runtime_02_initialize (void)
type, 0, NOT_BUILT_IN, type, 0, NOT_BUILT_IN,
NULL, NULL_TREE); NULL, NULL_TREE);
/* This is the type of all of the following functions objc_copyStruct(). */ /* This is the type of all of the following functions
objc_copyStruct(). */
type = build_function_type_list (void_type_node, type = build_function_type_list (void_type_node,
ptr_type_node, ptr_type_node,
const_ptr_type_node, const_ptr_type_node,
...@@ -482,10 +484,11 @@ static void next_runtime_02_initialize (void) ...@@ -482,10 +484,11 @@ static void next_runtime_02_initialize (void)
gcc_assert (!flag_objc_sjlj_exceptions); gcc_assert (!flag_objc_sjlj_exceptions);
/* Although we warn that fobjc-exceptions is required for exceptions /* Although we warn that fobjc-exceptions is required for exceptions
code, we carry on an create it anyway. */ code, we carry on and create it anyway. */
/* This can be required, even when exceptions code is not present, /* This can be required, even when exceptions code is not present,
when an __attribute__((objc_exception)) is applied to a class. */ when an __attribute__((objc_exception)) is applied to a
class. */
build_v2_ehtype_template (); build_v2_ehtype_template ();
/* void * objc_begin_catch (void *) */ /* void * objc_begin_catch (void *) */
...@@ -519,19 +522,21 @@ static void next_runtime_02_initialize (void) ...@@ -519,19 +522,21 @@ static void next_runtime_02_initialize (void)
/* NOTE --- templates --- */ /* NOTE --- templates --- */
/* Set 'objc_v2_message_ref_template' to the data type node for 'struct _message_ref_t'. /* Set 'objc_v2_message_ref_template' to the data type node for
This needs to be done just once per compilation. Also Set 'struct _message_ref_t'. This needs to be done just once per
'objc_v2_super_message_ref_template' to data type node compilation. Also Set 'objc_v2_super_message_ref_template' to data
for 'struct _super_message_ref_t'. */ type node for 'struct _super_message_ref_t'. */
/* struct _message_ref_t { /* struct _message_ref_t
{
IMP messenger; IMP messenger;
SEL name; SEL name;
}; };
where IMP is: id (*) (id, _message_ref_t*, ...) where IMP is: id (*) (id, _message_ref_t*, ...)
*/ */
/* struct _super_message_ref_t { /* struct _super_message_ref_t
{
SUPER_IMP messenger; SUPER_IMP messenger;
SEL name; SEL name;
}; };
...@@ -598,7 +603,8 @@ build_v2_message_ref_templates (void) ...@@ -598,7 +603,8 @@ build_v2_message_ref_templates (void)
/* Build following types which represent each class implementation. /* Build following types which represent each class implementation.
struct class_ro_t { struct class_ro_t
{
uint32_t const flags; uint32_t const flags;
uint32_t const instanceStart; uint32_t const instanceStart;
uint32_t const instanceSize; uint32_t const instanceSize;
...@@ -614,7 +620,8 @@ struct class_ro_t { ...@@ -614,7 +620,8 @@ struct class_ro_t {
const struct _prop_list_t * const properties; const struct _prop_list_t * const properties;
}; };
struct class_t { struct class_t
{
struct class_t *isa; struct class_t *isa;
struct class_t *superclass; struct class_t *superclass;
void *cache; void *cache;
...@@ -640,40 +647,40 @@ build_v2_class_templates (void) ...@@ -640,40 +647,40 @@ build_v2_class_templates (void)
/* uint32_t const flags; */ /* uint32_t const flags; */
decls = add_field_decl (integer_type_node, "flags", &chain); decls = add_field_decl (integer_type_node, "flags", &chain);
/* uint32_t const instanceStart */ /* uint32_t const instanceStart; */
add_field_decl (integer_type_node, "instanceStart", &chain); add_field_decl (integer_type_node, "instanceStart", &chain);
/* uint32_t const instanceSize */ /* uint32_t const instanceSize; */
add_field_decl (integer_type_node, "instanceSize", &chain); add_field_decl (integer_type_node, "instanceSize", &chain);
/* This ABI is currently only used on m64 NeXT, we choose to /* This ABI is currently only used on m64 NeXT. We always
make the alignment padding explicit. */ explicitly declare the alignment padding. */
/* uint32_t const reserved. */ /* uint32_t const reserved; */
add_field_decl (integer_type_node, "reserved", &chain); add_field_decl (integer_type_node, "reserved", &chain);
/* const uint8_t * const ivarLayout */ /* const uint8_t * const ivarLayout; */
cnst_strg_type = build_pointer_type (unsigned_char_type_node); cnst_strg_type = build_pointer_type (unsigned_char_type_node);
add_field_decl (cnst_strg_type, "ivarLayout", &chain); add_field_decl (cnst_strg_type, "ivarLayout", &chain);
/* const char *const name; */ /* const char *const name; */
add_field_decl (string_type_node, "name", &chain); add_field_decl (string_type_node, "name", &chain);
/* const struct method_list_t * const baseMethods */ /* const struct method_list_t * const baseMethods; */
add_field_decl (objc_method_list_ptr, "baseMethods", &chain); add_field_decl (objc_method_list_ptr, "baseMethods", &chain);
/* const struct objc_protocol_list *const baseProtocols */ /* const struct objc_protocol_list *const baseProtocols; */
add_field_decl (build_pointer_type add_field_decl (build_pointer_type
(xref_tag (RECORD_TYPE, (xref_tag (RECORD_TYPE,
get_identifier (UTAG_V2_PROTOCOL_LIST))), get_identifier (UTAG_V2_PROTOCOL_LIST))),
"baseProtocols", &chain); "baseProtocols", &chain);
/* const struct ivar_list_t *const ivars */ /* const struct ivar_list_t *const ivars; */
add_field_decl (objc_v2_ivar_list_ptr, "ivars", &chain); add_field_decl (objc_v2_ivar_list_ptr, "ivars", &chain);
/* const uint8_t * const weakIvarLayout; */ /* const uint8_t * const weakIvarLayout; */
add_field_decl (cnst_strg_type, "weakIvarLayout", &chain); add_field_decl (cnst_strg_type, "weakIvarLayout", &chain);
/* struct _prop_list_t * baseProperties */ /* struct _prop_list_t * baseProperties; */
add_field_decl (objc_prop_list_ptr, "baseProperties", &chain); add_field_decl (objc_prop_list_ptr, "baseProperties", &chain);
objc_finish_struct (objc_v2_class_ro_template, decls); objc_finish_struct (objc_v2_class_ro_template, decls);
...@@ -687,7 +694,7 @@ build_v2_class_templates (void) ...@@ -687,7 +694,7 @@ build_v2_class_templates (void)
decls = add_field_decl (build_pointer_type (objc_v2_class_template), decls = add_field_decl (build_pointer_type (objc_v2_class_template),
"isa", &chain); "isa", &chain);
/* struct class_t * const superclass */ /* struct class_t * const superclass; */
add_field_decl (build_pointer_type (objc_v2_class_template), add_field_decl (build_pointer_type (objc_v2_class_template),
"superclass", &chain); "superclass", &chain);
...@@ -703,11 +710,11 @@ build_v2_class_templates (void) ...@@ -703,11 +710,11 @@ build_v2_class_templates (void)
objc_finish_struct (objc_v2_class_template, decls); objc_finish_struct (objc_v2_class_template, decls);
} }
/* struct _objc_super { /* struct _objc_super
{
struct _objc_object *self; struct _objc_object *self;
Class cls; Class cls;
}; */ }; */
void void
build_v2_super_template (void) build_v2_super_template (void)
{ {
...@@ -724,7 +731,8 @@ build_v2_super_template (void) ...@@ -724,7 +731,8 @@ build_v2_super_template (void)
objc_finish_struct (objc_super_template, decls); objc_finish_struct (objc_super_template, decls);
} }
/* struct protocol_t { /* struct protocol_t
{
Class isa; Class isa;
const char * const protocol_name; const char * const protocol_name;
const struct protocol_list_t * const protocol_list; const struct protocol_list_t * const protocol_list;
...@@ -761,10 +769,10 @@ build_v2_protocol_template (void) ...@@ -761,10 +769,10 @@ build_v2_protocol_template (void)
/* const struct method_list_t * const class_methods; */ /* const struct method_list_t * const class_methods; */
add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain); add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
/* const struct method_list_t * optionalInstanceMethods */ /* const struct method_list_t * optionalInstanceMethods; */
add_field_decl (objc_method_proto_list_ptr, "optionalInstanceMethods", &chain); add_field_decl (objc_method_proto_list_ptr, "optionalInstanceMethods", &chain);
/* const struct method_list_t * optionalClassMethods */ /* const struct method_list_t * optionalClassMethods; */
add_field_decl (objc_method_proto_list_ptr, "optionalClassMethods", &chain); add_field_decl (objc_method_proto_list_ptr, "optionalClassMethods", &chain);
/* struct _prop_list_t * properties; */ /* struct _prop_list_t * properties; */
...@@ -780,7 +788,8 @@ build_v2_protocol_template (void) ...@@ -780,7 +788,8 @@ build_v2_protocol_template (void)
} }
/* Build type for a category: /* Build type for a category:
struct category_t { struct category_t
{
const char * const name; const char * const name;
struct class_t *const cls; struct class_t *const cls;
const struct method_list_t * const instance_methods; const struct method_list_t * const instance_methods;
...@@ -822,9 +831,8 @@ build_v2_category_template (void) ...@@ -822,9 +831,8 @@ build_v2_category_template (void)
/* NOTE --- Decls, Identifiers, Names etc. --- */ /* NOTE --- Decls, Identifiers, Names etc. --- */
/* This routine is given a name and returns a matching extern variable if /* This routine is given a name and returns a matching extern variable
one is found. if one is found. */
*/
static tree static tree
hash_name_lookup (hash *hashlist, tree name) hash_name_lookup (hash *hashlist, tree name)
...@@ -843,9 +851,9 @@ hash_name_lookup (hash *hashlist, tree name) ...@@ -843,9 +851,9 @@ hash_name_lookup (hash *hashlist, tree name)
return 0; return 0;
} }
/* This routine is given an extern variable and enters it in its hash table. /* This routine is given an extern variable and enters it in its hash
Note that hashing is done on its inner IDENTIFIER_NODE node. table. Note that hashing is done on its inner IDENTIFIER_NODE
*/ node. */
static void static void
hash_name_enter (hash *hashlist, tree id) hash_name_enter (hash *hashlist, tree id)
...@@ -903,7 +911,7 @@ create_global_decl (tree type, const char *name) ...@@ -903,7 +911,7 @@ create_global_decl (tree type, const char *name)
} }
/* Create a symbol with __attribute__ ((visibility ("hidden"))) /* Create a symbol with __attribute__ ((visibility ("hidden")))
attribute (private extern) */ attribute (private extern). */
static tree static tree
create_hidden_decl (tree type, const char *name) create_hidden_decl (tree type, const char *name)
...@@ -915,10 +923,14 @@ create_hidden_decl (tree type, const char *name) ...@@ -915,10 +923,14 @@ create_hidden_decl (tree type, const char *name)
} }
/* Irritatingly, we have a different superclass field name for ABI=2. */ /* Irritatingly, we have a different superclass field name for ABI=2. */
/* PS/TODO: The field name does not matter, it is only used internally
by the compiler. We can rename it to whatever we want. ;-) */
static tree static tree
next_runtime_abi_02_super_superclassfield_id (void) next_runtime_abi_02_super_superclassfield_id (void)
{ {
/* TODO: Simplify. Just always return get_identifier ("cls"), or at
most look it once at startup then always return it. */
if (!super_superclassfield_id) if (!super_superclassfield_id)
super_superclassfield_id = get_identifier ("cls"); super_superclassfield_id = get_identifier ("cls");
return super_superclassfield_id; return super_superclassfield_id;
...@@ -1011,8 +1023,8 @@ typedef struct GTY(()) ident_data_tuple { ...@@ -1011,8 +1023,8 @@ typedef struct GTY(()) ident_data_tuple {
DEF_VEC_O(ident_data_tuple); DEF_VEC_O(ident_data_tuple);
DEF_VEC_ALLOC_O(ident_data_tuple, gc); DEF_VEC_ALLOC_O(ident_data_tuple, gc);
/* This routine creates a file scope static variable of type 'Class' to hold /* This routine creates a file scope static variable of type 'Class'
the address of a class. */ to hold the address of a class. */
static tree static tree
build_v2_class_reference_decl (tree ident) build_v2_class_reference_decl (tree ident)
...@@ -1027,9 +1039,9 @@ build_v2_class_reference_decl (tree ident) ...@@ -1027,9 +1039,9 @@ build_v2_class_reference_decl (tree ident)
} }
/* This routine builds a class refs entry for each class name used. /* This routine builds a class refs entry for each class name used.
Initially, a (static-ref, IDENT) tuple is added to the list. Initially, a (static-ref, IDENT) tuple is added to the list. The
The ident is replaced with address of the class metadata (of type 'Class') ident is replaced with address of the class metadata (of type
in the output routine. */ 'Class') in the output routine. */
static GTY (()) VEC (ident_data_tuple, gc) * classrefs; static GTY (()) VEC (ident_data_tuple, gc) * classrefs;
...@@ -1055,6 +1067,7 @@ objc_v2_get_class_reference (tree ident) ...@@ -1055,6 +1067,7 @@ objc_v2_get_class_reference (tree ident)
else else
/* Somewhat arbitrary initial provision. */ /* Somewhat arbitrary initial provision. */
classrefs = VEC_alloc (ident_data_tuple, gc, 16); classrefs = VEC_alloc (ident_data_tuple, gc, 16);
/* We come here if we don't find the entry - or if the table was yet /* We come here if we don't find the entry - or if the table was yet
to be created. */ to be created. */
decl = build_v2_class_reference_decl (ident); decl = build_v2_class_reference_decl (ident);
...@@ -1088,10 +1101,11 @@ next_runtime_abi_02_get_class_reference (tree ident) ...@@ -1088,10 +1101,11 @@ next_runtime_abi_02_get_class_reference (tree ident)
} }
/* Used by get_arg_type_list. /* Used by get_arg_type_list.
Return the types for receiver & _cmd at the start of a method argument list. Return the types for receiver & _cmd at the start of a method
context is either METHOD_DEF or METHOD_REF, saying whether we are trying argument list. context is either METHOD_DEF or METHOD_REF, saying
to define a method or call one. superflag says this is for a send to super. whether we are trying to define a method or call one. superflag
meth may be NULL, in the case that there is no prototype. */ says this is for a send to super. meth may be NULL, in the case
that there is no prototype. */
static tree static tree
next_runtime_abi_02_get_arg_type_list_base (tree meth, int context, int superflag) next_runtime_abi_02_get_arg_type_list_base (tree meth, int context, int superflag)
...@@ -1196,8 +1210,9 @@ DEF_VEC_ALLOC_O(msgref_entry, gc); ...@@ -1196,8 +1210,9 @@ DEF_VEC_ALLOC_O(msgref_entry, gc);
static GTY (()) VEC (msgref_entry, gc) * msgrefs; static GTY (()) VEC (msgref_entry, gc) * msgrefs;
/* Build the list of (objc_msgSend_fixup_xxx, selector name) Used later on to /* Build the list of (objc_msgSend_fixup_xxx, selector name), used
initialize the table of 'struct message_ref_t' elements. */ later on to initialize the table of 'struct message_ref_t'
elements. */
static tree static tree
build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl) build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
...@@ -1215,6 +1230,7 @@ build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl) ...@@ -1215,6 +1230,7 @@ build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
else else
/* Somewhat arbitrary initial provision. */ /* Somewhat arbitrary initial provision. */
msgrefs = VEC_alloc (msgref_entry, gc, 32); msgrefs = VEC_alloc (msgref_entry, gc, 32);
/* We come here if we don't find a match or at the start. */ /* We come here if we don't find a match or at the start. */
decl = build_v2_message_reference_decl (sel_name, decl = build_v2_message_reference_decl (sel_name,
DECL_NAME (message_func_decl)); DECL_NAME (message_func_decl));
...@@ -1272,6 +1288,7 @@ objc_v2_get_protocol_reference (tree ident) ...@@ -1272,6 +1288,7 @@ objc_v2_get_protocol_reference (tree ident)
else else
/* Somewhat arbitrary initial provision. */ /* Somewhat arbitrary initial provision. */
protrefs = VEC_alloc (prot_list_entry, gc, 32); protrefs = VEC_alloc (prot_list_entry, gc, 32);
/* We come here if we don't find the entry - or if the table was yet /* We come here if we don't find the entry - or if the table was yet
to be created. */ to be created. */
decl = build_v2_protocollist_ref_decl (ident); decl = build_v2_protocollist_ref_decl (ident);
...@@ -1291,9 +1308,9 @@ next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED, ...@@ -1291,9 +1308,9 @@ next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED,
return objc_v2_get_protocol_reference (p); return objc_v2_get_protocol_reference (p);
} }
/* This routine returns the ivar declaration, if component is a valid ivar field; /* This routine returns the ivar declaration, if component is a valid
NULL_TREE otherwise. On finding an ivar, it also returns the class name in CLASS. ivar field; NULL_TREE otherwise. On finding an ivar, it also
*/ returns the class name in CLASS. */
static tree static tree
objc_is_ivar (tree expr, tree component, tree *klass) objc_is_ivar (tree expr, tree component, tree *klass)
...@@ -1334,11 +1351,10 @@ create_ivar_offset_name (char *buf, tree class_name, tree field_decl) ...@@ -1334,11 +1351,10 @@ create_ivar_offset_name (char *buf, tree class_name, tree field_decl)
return; return;
} }
/* This routine generates new abi's ivar reference tree. It amounts to generating /* This routine generates new abi's ivar reference tree. It amounts
*(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally generate pObj->IVAR to generating *(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally
OFFSET_IVAR is an 'extern' variable holding the offset for 'IVAR' field. TYPE generate pObj->IVAR. OFFSET_IVAR is an 'extern' variable holding
is type of IVAR field. the offset for 'IVAR' field. TYPE is type of IVAR field. */
*/
static tree static tree
objc_v2_build_ivar_ref (tree datum, tree component) objc_v2_build_ivar_ref (tree datum, tree component)
...@@ -1351,10 +1367,11 @@ objc_v2_build_ivar_ref (tree datum, tree component) ...@@ -1351,10 +1367,11 @@ objc_v2_build_ivar_ref (tree datum, tree component)
return NULL_TREE; return NULL_TREE;
/* This routine only handles non-bitfield fields */ /* This routine only handles non-bitfield fields */
/* DECL_INITIAL macro is set to width of bitfield and can be relied on to /* DECL_INITIAL macro is set to width of bitfield and can be relied
check for bitfield ivars. Note that I cannot rely on DECL_BIT_FIELD macro on to check for bitfield ivars. Note that I cannot rely on
because it is only set when the whole struct is seen (at finish_struct) DECL_BIT_FIELD macro because it is only set when the whole struct
and not when the ivar chain is built. */ is seen (at finish_struct) and not when the ivar chain is
built. */
if (DECL_INITIAL (field)) if (DECL_INITIAL (field))
return NULL_TREE; return NULL_TREE;
...@@ -1378,10 +1395,10 @@ objc_v2_build_ivar_ref (tree datum, tree component) ...@@ -1378,10 +1395,10 @@ objc_v2_build_ivar_ref (tree datum, tree component)
/* Finally: *(ftype*)((char*)datum + offset) */ /* Finally: *(ftype*)((char*)datum + offset) */
ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR); ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR);
/* We must set type of the resulting expression to be the same as the /* We must set type of the resulting expression to be the same as
field type. This is because, build_indirect_ref (...) rebuilds the the field type. This is because, build_indirect_ref (...)
type which may result in lost information; as in the case of rebuilds the type which may result in lost information; as in the
protocol-qualified types (id <protocol> ). */ case of protocol-qualified types (id <protocol> ). */
TREE_TYPE (ref) = ftype; TREE_TYPE (ref) = ftype;
if (TREE_READONLY (datum) || TREE_READONLY (field)) if (TREE_READONLY (datum) || TREE_READONLY (field))
...@@ -1409,9 +1426,8 @@ next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED, ...@@ -1409,9 +1426,8 @@ next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
return objc_build_component_ref (base, id); return objc_build_component_ref (base, id);
} }
/* [super ...] references are listed here (and built into a table at meta /* [super ...] references are listed here (and built into a table at
-data emit time). */ meta -data emit time). */
static tree static tree
build_v2_superclass_ref_decl (tree ident, bool inst) build_v2_superclass_ref_decl (tree ident, bool inst)
{ {
...@@ -1484,9 +1500,9 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED, ...@@ -1484,9 +1500,9 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
if (!inst_meth) if (!inst_meth)
/* If we are in a class method, we must retrieve the /* If we are in a class method, we must retrieve the
_metaclass_ for the current class, pointed at by _metaclass_ for the current class, pointed at by the
the class's "isa" pointer. The following assumes that class's "isa" pointer. The following assumes that "isa" is
"isa" is the first ivar in a class (which it must be). */ the first ivar in a class (which it must be). */
super_class = super_class =
build_indirect_ref (input_location, build_indirect_ref (input_location,
build_c_cast (input_location, build_c_cast (input_location,
...@@ -1498,7 +1514,7 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED, ...@@ -1498,7 +1514,7 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
/* ??? Do we need to add the class ref anway for zero-link? */ /* ??? Do we need to add the class ref anway for zero-link? */
/* else do it the slow way. */ /* else do it the slow way. */
super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl); super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
/* assemble_external (super_class);*/ /* assemble_external (super_class); */
super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1, super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
IDENTIFIER_POINTER (super_name)); IDENTIFIER_POINTER (super_name));
/* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */ /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
...@@ -1525,15 +1541,15 @@ next_runtime_abi_02_receiver_is_class_object (tree receiver) ...@@ -1525,15 +1541,15 @@ next_runtime_abi_02_receiver_is_class_object (tree receiver)
return NULL_TREE; return NULL_TREE;
} }
/* Assign all arguments in VALUES which have side-effect to a temporary and /* Assign all arguments in VALUES which have side-effect to a
replaced that argument in VALUES list with the temporary. TYPELIST is the temporary and replaced that argument in VALUES list with the
list of argument types. */ temporary. TYPELIST is the list of argument types. */
static tree static tree
objc_copy_to_temp_side_effect_params (tree typelist, tree values) objc_copy_to_temp_side_effect_params (tree typelist, tree values)
{ {
tree valtail, typetail; tree valtail, typetail;
/* skip over receiver and the &_msf_ref types */ /* Skip over receiver and the &_msf_ref types. */
gcc_assert (TREE_CHAIN (typelist)); gcc_assert (TREE_CHAIN (typelist));
typetail = TREE_CHAIN (TREE_CHAIN (typelist)); typetail = TREE_CHAIN (TREE_CHAIN (typelist));
...@@ -1546,7 +1562,7 @@ objc_copy_to_temp_side_effect_params (tree typelist, tree values) ...@@ -1546,7 +1562,7 @@ objc_copy_to_temp_side_effect_params (tree typelist, tree values)
break; break;
if (!TREE_SIDE_EFFECTS (value)) if (!TREE_SIDE_EFFECTS (value))
continue; continue;
/* To prevent re-evaluation */ /* To prevent re-evaluation. */
value = save_expr (value); value = save_expr (value);
add_stmt (value); add_stmt (value);
TREE_VALUE (valtail) = value; TREE_VALUE (valtail) = value;
...@@ -1555,8 +1571,7 @@ objc_copy_to_temp_side_effect_params (tree typelist, tree values) ...@@ -1555,8 +1571,7 @@ objc_copy_to_temp_side_effect_params (tree typelist, tree values)
} }
/* Build the new abi's messaging library call. It looks like: /* Build the new abi's messaging library call. It looks like:
(*_msg.messenger) (receiver, &_msg, ...) (*_msg.messenger) (receiver, &_msg, ...) */
*/
static tree static tree
build_v2_build_objc_method_call (int super_flag, tree method_prototype, build_v2_build_objc_method_call (int super_flag, tree method_prototype,
...@@ -1586,7 +1601,7 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype, ...@@ -1586,7 +1601,7 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
method_params = objc_copy_to_temp_side_effect_params (method_param_types, method_params = objc_copy_to_temp_side_effect_params (method_param_types,
method_params); method_params);
/* Get &message_ref_t.messenger */ /* Get &message_ref_t.messenger. */
sender = build_c_cast (input_location, sender = build_c_cast (input_location,
build_pointer_type (super_flag build_pointer_type (super_flag
? objc_v2_super_imp_type ? objc_v2_super_imp_type
...@@ -1617,7 +1632,8 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype, ...@@ -1617,7 +1632,8 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
|| TREE_CODE (ret_type) == UNION_TYPE) || TREE_CODE (ret_type) == UNION_TYPE)
{ {
VEC(constructor_elt,gc) *rtt = NULL; VEC(constructor_elt,gc) *rtt = NULL;
/* ??? CHECKME. hmmm..... think we need something more here. */ /* ??? CHECKME. hmmm..... think we need something more
here. */
CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE); CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
ftree = objc_build_constructor (ret_type, rtt); ftree = objc_build_constructor (ret_type, rtt);
} }
...@@ -1659,8 +1675,9 @@ next_runtime_abi_02_build_objc_method_call (location_t loc, ...@@ -1659,8 +1675,9 @@ next_runtime_abi_02_build_objc_method_call (location_t loc,
objc_object_type); objc_object_type);
/* Do we need to check for nil receivers ? */ /* Do we need to check for nil receivers ? */
/* For now, message sent to classes need no nil check. In future, class /* For now, message sent to classes need no nil check. In the
declaration marked as weak_import must be nil checked. */ future, class declaration marked as weak_import must be nil
checked. */
if (super if (super
|| (TREE_CODE (receiver) == VAR_DECL || (TREE_CODE (receiver) == VAR_DECL
&& TREE_TYPE (receiver) == objc_class_type)) && TREE_TYPE (receiver) == objc_class_type))
...@@ -1719,10 +1736,10 @@ next_runtime_abi_02_setup_const_string_class_decl (void) ...@@ -1719,10 +1736,10 @@ next_runtime_abi_02_setup_const_string_class_decl (void)
string_class_decl = lookup_name (constant_string_global_id); string_class_decl = lookup_name (constant_string_global_id);
/* In OBJC2 abi constant string class reference refers to /* In OBJC2 abi, constant string class reference refers to class
class name for NSConstantString class. This declaration may not be name for NSConstantString class. This declaration may not be
available yet (in fact it is not in most cases). So, declare an extern available yet (in fact it is not in most cases). So, declare an
OBJC_CLASS_$_NSConstantString in its place. */ extern OBJC_CLASS_$_NSConstantString in its place. */
if (!string_class_decl) if (!string_class_decl)
string_class_decl = string_class_decl =
create_extern_decl (objc_v2_class_template, create_extern_decl (objc_v2_class_template,
...@@ -1763,7 +1780,8 @@ next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string, ...@@ -1763,7 +1780,8 @@ next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string,
/* NOTE --- NeXT V2 Metadata templates --- */ /* NOTE --- NeXT V2 Metadata templates --- */
/* This routine builds the following type: /* This routine builds the following type:
struct _prop_t { struct _prop_t
{
const char * const name; // property name const char * const name; // property name
const char * const attributes; // comma-delimited, encoded, const char * const attributes; // comma-delimited, encoded,
// property attributes // property attributes
...@@ -1787,7 +1805,8 @@ build_v2_property_template (void) ...@@ -1787,7 +1805,8 @@ build_v2_property_template (void)
return prop_record; return prop_record;
} }
/* struct ivar_t { /* struct ivar_t
{
unsigned long int *offset; unsigned long int *offset;
char *name; char *name;
char *type; char *type;
...@@ -1805,7 +1824,7 @@ build_v2_ivar_t_template (void) ...@@ -1805,7 +1824,7 @@ build_v2_ivar_t_template (void)
objc_ivar_id = get_identifier ("_ivar_t"); objc_ivar_id = get_identifier ("_ivar_t");
objc_ivar_record = objc_start_struct (objc_ivar_id); objc_ivar_record = objc_start_struct (objc_ivar_id);
/* unsigned long int *offset */ /* unsigned long int *offset; */
decls = add_field_decl (build_pointer_type decls = add_field_decl (build_pointer_type
(TREE_TYPE (size_zero_node)), "offset", &chain); (TREE_TYPE (size_zero_node)), "offset", &chain);
...@@ -1874,8 +1893,7 @@ newabi_append_ro (const char *name) ...@@ -1874,8 +1893,7 @@ newabi_append_ro (const char *name)
/* Build the struct message_ref_t msg = /* Build the struct message_ref_t msg =
{objc_msgSend_fixup_xxx, @selector(func)} {objc_msgSend_fixup_xxx, @selector(func)}
table. table. */
*/
static static
void build_v2_message_ref_translation_table (void) void build_v2_message_ref_translation_table (void)
...@@ -1894,12 +1912,12 @@ void build_v2_message_ref_translation_table (void) ...@@ -1894,12 +1912,12 @@ void build_v2_message_ref_translation_table (void)
location_t loc = DECL_SOURCE_LOCATION (ref->refdecl); location_t loc = DECL_SOURCE_LOCATION (ref->refdecl);
initializer = NULL; initializer = NULL;
/* First 'IMP messenger' field.. */ /* First 'IMP messenger' field... */
expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0); expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0);
expr = convert (objc_v2_imp_type, expr); expr = convert (objc_v2_imp_type, expr);
CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr); CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);
/* then.. 'SEL name' field */ /* ... then 'SEL name' field. */
expr = build_selector (ref->selname); expr = build_selector (ref->selname);
CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr); CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);
constructor = objc_build_constructor (struct_type, initializer); constructor = objc_build_constructor (struct_type, initializer);
...@@ -1907,7 +1925,8 @@ void build_v2_message_ref_translation_table (void) ...@@ -1907,7 +1925,8 @@ void build_v2_message_ref_translation_table (void)
} }
} }
/* Build decl = initializer; for each externally visible class reference. */ /* Build decl = initializer; for each externally visible class
reference. */
static void static void
build_v2_classrefs_table (void) build_v2_classrefs_table (void)
...@@ -1922,8 +1941,9 @@ build_v2_classrefs_table (void) ...@@ -1922,8 +1941,9 @@ build_v2_classrefs_table (void)
{ {
tree expr = ref->ident; tree expr = ref->ident;
tree decl = ref->data; tree decl = ref->data;
/* Interface with no implementation and yet one of its messages has been /* Interface with no implementation and yet one of its messages
used. Need to generate a full address-of tree for it here. */ has been used. Need to generate a full address-of tree for it
here. */
if (TREE_CODE (expr) == IDENTIFIER_NODE) if (TREE_CODE (expr) == IDENTIFIER_NODE)
{ {
const char *name = objc_build_internal_classname (expr, false); const char *name = objc_build_internal_classname (expr, false);
...@@ -1937,7 +1957,8 @@ build_v2_classrefs_table (void) ...@@ -1937,7 +1957,8 @@ build_v2_classrefs_table (void)
} }
} }
/* Build decl = initializer; for each externally visible class reference. */ /* Build decl = initializer; for each externally visible super class
reference. */
static void static void
build_v2_super_classrefs_table (bool metaclass) build_v2_super_classrefs_table (bool metaclass)
...@@ -1954,8 +1975,9 @@ build_v2_super_classrefs_table (bool metaclass) ...@@ -1954,8 +1975,9 @@ build_v2_super_classrefs_table (bool metaclass)
{ {
tree expr = ref->ident; tree expr = ref->ident;
tree decl = ref->data; tree decl = ref->data;
/* Interface with no implementation and yet one of its messages has been /* Interface with no implementation and yet one of its messages
used. Need to generate a full address-of tree for it here. */ has been used. Need to generate a full address-of tree for it
here. */
if (TREE_CODE (expr) == IDENTIFIER_NODE) if (TREE_CODE (expr) == IDENTIFIER_NODE)
{ {
const char * name = objc_build_internal_classname (expr, metaclass); const char * name = objc_build_internal_classname (expr, metaclass);
...@@ -1966,8 +1988,8 @@ build_v2_super_classrefs_table (bool metaclass) ...@@ -1966,8 +1988,8 @@ build_v2_super_classrefs_table (bool metaclass)
} }
} }
/* Add the global class meta-data declaration to the list which later on /* Add the global class meta-data declaration to the list which later
ends up in the __class_list section. */ on ends up in the __class_list section. */
static GTY(()) VEC(tree,gc) *class_list; static GTY(()) VEC(tree,gc) *class_list;
...@@ -1981,8 +2003,8 @@ objc_v2_add_to_class_list (tree global_class_decl) ...@@ -1981,8 +2003,8 @@ objc_v2_add_to_class_list (tree global_class_decl)
static GTY(()) VEC(tree,gc) *nonlazy_class_list; static GTY(()) VEC(tree,gc) *nonlazy_class_list;
/* Add the global class meta-data declaration to the list which later on /* Add the global class meta-data declaration to the list which later
ends up in the __nonlazy_class section. */ on ends up in the __nonlazy_class section. */
static void static void
objc_v2_add_to_nonlazy_class_list (tree global_class_decl) objc_v2_add_to_nonlazy_class_list (tree global_class_decl)
...@@ -1994,8 +2016,8 @@ objc_v2_add_to_nonlazy_class_list (tree global_class_decl) ...@@ -1994,8 +2016,8 @@ objc_v2_add_to_nonlazy_class_list (tree global_class_decl)
static GTY(()) VEC(tree,gc) *category_list; static GTY(()) VEC(tree,gc) *category_list;
/* Add the category meta-data declaration to the list which later on ends up /* Add the category meta-data declaration to the list which later on
in the __nonlazy_category section. */ ends up in the __nonlazy_category section. */
static void static void
objc_v2_add_to_category_list (tree decl) objc_v2_add_to_category_list (tree decl)
...@@ -2007,8 +2029,8 @@ objc_v2_add_to_category_list (tree decl) ...@@ -2007,8 +2029,8 @@ objc_v2_add_to_category_list (tree decl)
static GTY(()) VEC(tree,gc) *nonlazy_category_list; static GTY(()) VEC(tree,gc) *nonlazy_category_list;
/* Add the category meta-data declaration to the list which later on ends up /* Add the category meta-data declaration to the list which later on
in the __category_list section. */ ends up in the __category_list section. */
static void static void
objc_v2_add_to_nonlazy_category_list (tree decl) objc_v2_add_to_nonlazy_category_list (tree decl)
...@@ -2033,8 +2055,8 @@ has_load_impl (tree clsmeth) ...@@ -2033,8 +2055,8 @@ has_load_impl (tree clsmeth)
return false; return false;
} }
/* Build a __{class,category}_list section table containing address of all /* Build a __{class,category}_list section table containing address of
@implemented {class,category} meta-data. */ all @implemented {class,category} meta-data. */
static void static void
build_v2_address_table (VEC(tree,gc) *src, const char *nam, tree attr) build_v2_address_table (VEC(tree,gc) *src, const char *nam, tree attr)
...@@ -2060,17 +2082,17 @@ build_v2_address_table (VEC(tree,gc) *src, const char *nam, tree attr) ...@@ -2060,17 +2082,17 @@ build_v2_address_table (VEC(tree,gc) *src, const char *nam, tree attr)
type = build_array_type (objc_class_type, type = build_array_type (objc_class_type,
build_index_type (build_int_cst (NULL_TREE, count - 1))); build_index_type (build_int_cst (NULL_TREE, count - 1)));
decl = start_var_decl (type, nam); decl = start_var_decl (type, nam);
/* The runtime wants this, even if it appears unused, so we must force the /* The runtime wants this, even if it appears unused, so we must
output. */ force the output. */
DECL_PRESERVE_P (decl) = 1; DECL_PRESERVE_P (decl) = 1;
expr = objc_build_constructor (type, initlist); expr = objc_build_constructor (type, initlist);
OBJCMETA (decl, objc_meta, attr); OBJCMETA (decl, objc_meta, attr);
finish_var_decl (decl, expr); finish_var_decl (decl, expr);
} }
/* Build decl = initializer; /* Build decl = initializer; for each protocol referenced in
for each protocol referenced in @protocol(MyProt) expression. @protocol(MyProt) expression. Refs as built in the entry section
Refs as built in the entry section above. */ above. */
static void static void
build_v2_protocol_list_translation_table (void) build_v2_protocol_list_translation_table (void)
...@@ -2097,8 +2119,8 @@ build_v2_protocol_list_translation_table (void) ...@@ -2097,8 +2119,8 @@ build_v2_protocol_list_translation_table (void)
static GTY (()) VEC (prot_list_entry, gc) * protlist; static GTY (()) VEC (prot_list_entry, gc) * protlist;
/* Add the local protocol meta-data declaration to the list which later on ends up /* Add the local protocol meta-data declaration to the list which
in the __protocol_list section. */ later on ends up in the __protocol_list section. */
static void static void
objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl) objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl)
...@@ -2112,8 +2134,8 @@ objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl) ...@@ -2112,8 +2134,8 @@ objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl)
VEC_safe_push (prot_list_entry, gc, protlist, &e); VEC_safe_push (prot_list_entry, gc, protlist, &e);
} }
/* Build the __protocol_list section table containing address of all generate protocol_t /* Build the __protocol_list section table containing address of all
meta-data. */ generate protocol_t meta-data. */
static void static void
build_v2_protocol_list_address_table (void) build_v2_protocol_list_address_table (void)
...@@ -2140,8 +2162,8 @@ build_v2_protocol_list_address_table (void) ...@@ -2140,8 +2162,8 @@ build_v2_protocol_list_address_table (void)
/* TODO: upgrade to the the clang/llvm hidden version. */ /* TODO: upgrade to the the clang/llvm hidden version. */
} }
/* This routine declares a variable to hold meta data for /* This routine declares a variable to hold meta data for 'struct
'struct protocol_list_t'. */ protocol_list_t'. */
static tree static tree
generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
...@@ -2216,12 +2238,12 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) ...@@ -2216,12 +2238,12 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
return refs_decl; return refs_decl;
} }
/* This routine builds one 'struct method_t' initializer list. Note that the /* This routine builds one 'struct method_t' initializer list. Note
old ABI is supposed to build 'struct objc_method' which has 3 fields, but that the old ABI is supposed to build 'struct objc_method' which
it does not build the initialization expression for 'method_imp' which for has 3 fields, but it does not build the initialization expression
protocols is NULL any way. To be consistant with declaration of for 'method_imp' which for protocols is NULL any way. To be
'struct method_t', in the new ABI we set the method_t.imp to NULL. consistant with declaration of 'struct method_t', in the new ABI we
*/ set the method_t.imp to NULL. */
static tree static tree
build_v2_descriptor_table_initializer (tree type, tree entries) build_v2_descriptor_table_initializer (tree type, tree entries)
...@@ -2246,7 +2268,8 @@ build_v2_descriptor_table_initializer (tree type, tree entries) ...@@ -2246,7 +2268,8 @@ build_v2_descriptor_table_initializer (tree type, tree entries)
return objc_build_constructor (build_array_type (type, 0), initlist); return objc_build_constructor (build_array_type (type, 0), initlist);
} }
/* struct method_list_t { /* struct method_list_t
{
uint32_t entsize; uint32_t entsize;
uint32_t method_count; uint32_t method_count;
struct objc_method method_list[method_count]; struct objc_method method_list[method_count];
...@@ -2260,7 +2283,7 @@ build_v2_method_list_template (tree list_type, int size) ...@@ -2260,7 +2283,7 @@ build_v2_method_list_template (tree list_type, int size)
method_list_t_record = objc_start_struct (NULL_TREE); method_list_t_record = objc_start_struct (NULL_TREE);
/* uint32_t const entsize */ /* uint32_t const entsize; */
decls = add_field_decl (integer_type_node, "entsize", &chain); decls = add_field_decl (integer_type_node, "entsize", &chain);
/* int method_count; */ /* int method_count; */
...@@ -2275,8 +2298,8 @@ build_v2_method_list_template (tree list_type, int size) ...@@ -2275,8 +2298,8 @@ build_v2_method_list_template (tree list_type, int size)
} }
/* Note, as above that we are building to the objc_method_template /* Note, as above that we are building to the objc_method_template
which has the *imp field. ABI0/1 build with objc_method_prototype_template which has the *imp field. ABI0/1 build with
which is missing this field. */ objc_method_prototype_template which is missing this field. */
static tree static tree
generate_v2_meth_descriptor_table (tree chain, tree protocol, generate_v2_meth_descriptor_table (tree chain, tree protocol,
const char *prefix, tree attr) const char *prefix, tree attr)
...@@ -2320,8 +2343,8 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol, ...@@ -2320,8 +2343,8 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol,
return decl; return decl;
} }
/* This routine builds the initializer list to initialize the /* This routine builds the initializer list to initialize the 'struct
'struct _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */ _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */
static tree static tree
build_v2_property_table_initializer (tree type, tree context) build_v2_property_table_initializer (tree type, tree context)
...@@ -2336,7 +2359,8 @@ build_v2_property_table_initializer (tree type, tree context) ...@@ -2336,7 +2359,8 @@ build_v2_property_table_initializer (tree type, tree context)
for (; x; x = TREE_CHAIN (x)) for (; x; x = TREE_CHAIN (x))
{ {
VEC(constructor_elt,gc) *elemlist = NULL; VEC(constructor_elt,gc) *elemlist = NULL;
/* NOTE! sections where property name/attribute go MUST change later. */ /* NOTE! sections where property name/attribute go MUST change
later. */
tree attribute, name_ident = PROPERTY_NAME (x); tree attribute, name_ident = PROPERTY_NAME (x);
CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
...@@ -2354,7 +2378,8 @@ build_v2_property_table_initializer (tree type, tree context) ...@@ -2354,7 +2378,8 @@ build_v2_property_table_initializer (tree type, tree context)
} }
/* This routine builds the following type: /* This routine builds the following type:
struct _prop_list_t { struct _prop_list_t
{
uint32_t entsize; // sizeof (struct _prop_t) uint32_t entsize; // sizeof (struct _prop_t)
uint32_t prop_count; uint32_t prop_count;
struct _prop_t prop_list [prop_count]; struct _prop_t prop_list [prop_count];
...@@ -2370,10 +2395,10 @@ build_v2_property_list_template (tree list_type, int size) ...@@ -2370,10 +2395,10 @@ build_v2_property_list_template (tree list_type, int size)
/* anonymous. */ /* anonymous. */
property_list_t_record = objc_start_struct (NULL_TREE); property_list_t_record = objc_start_struct (NULL_TREE);
/* uint32_t const entsize */ /* uint32_t const entsize; */
decls = add_field_decl (integer_type_node, "entsize", &chain); decls = add_field_decl (integer_type_node, "entsize", &chain);
/* int prop_count */ /* int prop_count; */
add_field_decl (integer_type_node, "prop_count", &chain); add_field_decl (integer_type_node, "prop_count", &chain);
/* struct _prop_t prop_list[]; */ /* struct _prop_t prop_list[]; */
...@@ -2384,9 +2409,8 @@ build_v2_property_list_template (tree list_type, int size) ...@@ -2384,9 +2409,8 @@ build_v2_property_list_template (tree list_type, int size)
return property_list_t_record; return property_list_t_record;
} }
/* /* Top-level routine to generate property tables for each
Top-level routine to generate property tables for each implementation. implementation. */
*/
static tree static tree
generate_v2_property_table (tree context, tree klass_ctxt) generate_v2_property_table (tree context, tree klass_ctxt)
...@@ -2503,9 +2527,8 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list ...@@ -2503,9 +2527,8 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list
return objc_build_constructor (type, inits); return objc_build_constructor (type, inits);
} }
/* /* Main routine to build all meta data for all protocols used in a
Main routine to build all meta data for all protocols used in a translation unit. translation unit. */
*/
static void static void
generate_v2_protocols (void) generate_v2_protocols (void)
...@@ -2516,7 +2539,8 @@ generate_v2_protocols (void) ...@@ -2516,7 +2539,8 @@ generate_v2_protocols (void)
if (!protocol_chain) if (!protocol_chain)
return ; return ;
/* If a protocol was directly referenced, pull in indirect references. */ /* If a protocol was directly referenced, pull in indirect
references. */
for (p = protocol_chain; p; p = TREE_CHAIN (p)) for (p = protocol_chain; p; p = TREE_CHAIN (p))
if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
generate_protocol_references (PROTOCOL_LIST (p)); generate_protocol_references (PROTOCOL_LIST (p));
...@@ -2583,10 +2607,11 @@ generate_v2_protocols (void) ...@@ -2583,10 +2607,11 @@ generate_v2_protocols (void)
if (some) if (some)
{ {
/* Make sure we get the Protocol class linked in - reference it... */ /* Make sure we get the Protocol class linked in - reference
it... */
p = objc_v2_get_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); p = objc_v2_get_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
/* .. but since we don't specifically use the ref.. /* ... but since we don't specifically use the reference... we
we need to force it. */ need to force it. */
DECL_PRESERVE_P (p) = 1; DECL_PRESERVE_P (p) = 1;
} }
} }
...@@ -2702,7 +2727,7 @@ generate_v2_category (struct imp_entry *impent) ...@@ -2702,7 +2727,7 @@ generate_v2_category (struct imp_entry *impent)
else else
protocol_decl = NULL_TREE; protocol_decl = NULL_TREE;
/* decl = update_var_decl(impent->class_decl);*/ /* decl = update_var_decl(impent->class_decl); */
props = generate_v2_property_table (NULL_TREE, cat); props = generate_v2_property_table (NULL_TREE, cat);
...@@ -2732,16 +2757,17 @@ generate_v2_category (struct imp_entry *impent) ...@@ -2732,16 +2757,17 @@ generate_v2_category (struct imp_entry *impent)
finish_var_decl (cat_decl, initlist); finish_var_decl (cat_decl, initlist);
impent->class_decl = cat_decl; impent->class_decl = cat_decl;
/* Add to list of pointers in __category_list section */ /* Add to list of pointers in __category_list section. */
objc_v2_add_to_category_list (cat_decl); objc_v2_add_to_category_list (cat_decl);
if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context))) if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)))
objc_v2_add_to_nonlazy_category_list (cat_decl); objc_v2_add_to_nonlazy_category_list (cat_decl);
} }
/* This routine declares a variable to hold the offset for ivar FIELD_DECL. /* This routine declares a variable to hold the offset for ivar
Variable name is .objc_ivar.ClassName.IvarName. */ FIELD_DECL. Variable name is .objc_ivar.ClassName.IvarName. */
typedef struct GTY(()) ivarref_entry { typedef struct GTY(()) ivarref_entry
{
tree decl; tree decl;
tree offset; tree offset;
} ivarref_entry; } ivarref_entry;
...@@ -2789,11 +2815,10 @@ ivar_offset_ref (tree class_name, tree field_decl) ...@@ -2789,11 +2815,10 @@ ivar_offset_ref (tree class_name, tree field_decl)
return decl; return decl;
} }
/* This routine builds initializer-list needed to initialize /* This routine builds initializer-list needed to initialize 'struct
'struct ivar_t list[count] ivar_t list[count] of 'struct ivar_list_t' meta data. TYPE is
of 'struct ivar_list_t' meta data. TYPE is 'struct ivar_t' and 'struct ivar_t' and FIELD_DECL is list of ivars for the target
FIELD_DECL is list of ivars for the target class. class. */
*/
static tree static tree
build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
...@@ -2813,19 +2838,19 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) ...@@ -2813,19 +2838,19 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
continue; continue;
} }
/* Set offset */ /* Set offset. */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
build_unary_op (input_location, build_unary_op (input_location,
ADDR_EXPR, ADDR_EXPR,
ivar_offset_ref (class_name, ivar_offset_ref (class_name,
field_decl), 0)); field_decl), 0));
/* Set name */ /* Set name. */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
add_objc_string (DECL_NAME (field_decl), add_objc_string (DECL_NAME (field_decl),
meth_var_names)); meth_var_names));
/* Set type */ /* Set type. */
encode_field_decl (field_decl, encode_field_decl (field_decl,
obstack_object_size (&util_obstack), obstack_object_size (&util_obstack),
OBJC_ENCODE_DONT_INLINE_DEFS); OBJC_ENCODE_DONT_INLINE_DEFS);
...@@ -2836,13 +2861,13 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) ...@@ -2836,13 +2861,13 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id); CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
obstack_free (&util_obstack, util_firstobj); obstack_free (&util_obstack, util_firstobj);
/* Set alignment */ /* Set alignment. */
val = DECL_ALIGN_UNIT (field_decl); val = DECL_ALIGN_UNIT (field_decl);
val = exact_log2 (val); val = exact_log2 (val);
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
build_int_cst (integer_type_node, val)); build_int_cst (integer_type_node, val));
/* Set size */ /* Set size. */
val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl)); val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl));
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
build_int_cst (integer_type_node, val)); build_int_cst (integer_type_node, val));
...@@ -2860,7 +2885,8 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) ...@@ -2860,7 +2885,8 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
} }
/* /*
struct ivar_list_t { struct ivar_list_t
{
uint32 entsize; uint32 entsize;
uint32 count; uint32 count;
struct iver_t list[count]; struct iver_t list[count];
...@@ -2890,11 +2916,10 @@ build_v2_ivar_list_t_template (tree list_type, int size) ...@@ -2890,11 +2916,10 @@ build_v2_ivar_list_t_template (tree list_type, int size)
return objc_ivar_list_record; return objc_ivar_list_record;
} }
/* This routine declares a static variable of type 'struct ivar_list_t' and /* This routine declares a static variable of type 'struct
initializes it. ivar_list_t' and initializes it. chain is the source of the data,
chain is the source of the data, name is the name for the var. name is the name for the var. attr is the meta-data section tag
attr is the meta-data section tag attribute attribute. templ is the implementation template for the class. */
templ is the implementation template for the class. */
static tree static tree
generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ) generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ)
...@@ -2926,7 +2951,8 @@ generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ) ...@@ -2926,7 +2951,8 @@ generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ)
return decl; return decl;
} }
/* Routine to build initializer list to initialize objects of type struct class_t; */ /* Routine to build initializer list to initialize objects of type
struct class_t; */
static tree static tree
build_v2_class_t_initializer (tree type, tree isa, tree superclass, build_v2_class_t_initializer (tree type, tree isa, tree superclass,
...@@ -2987,8 +3013,8 @@ build_v2_class_ro_t_initializer (tree type, tree name, ...@@ -2987,8 +3013,8 @@ build_v2_class_ro_t_initializer (tree type, tree name,
CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
build_int_cst (integer_type_node, instanceSize)); build_int_cst (integer_type_node, instanceSize));
/* This ABI is currently only used on m64 NeXT, we choose to /* This ABI is currently only used on m64 NeXT. We always
make the alignment padding explicit. */ explicitly declare the alignment padding. */
/* reserved, pads alignment. */ /* reserved, pads alignment. */
CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
build_int_cst (integer_type_node, 0)); build_int_cst (integer_type_node, 0));
...@@ -3063,6 +3089,7 @@ objc_v2_add_to_ehtype_list (tree name) ...@@ -3063,6 +3089,7 @@ objc_v2_add_to_ehtype_list (tree name)
else else
/* Arbitrary initial count. */ /* Arbitrary initial count. */
ehtype_list = VEC_alloc (ident_data_tuple, gc, 8); ehtype_list = VEC_alloc (ident_data_tuple, gc, 8);
/* Not found, or new list. */ /* Not found, or new list. */
e.ident = name; e.ident = name;
e.data = NULL_TREE; e.data = NULL_TREE;
...@@ -3098,12 +3125,12 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3098,12 +3125,12 @@ generate_v2_class_structs (struct imp_entry *impent)
gcc_assert (!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace); gcc_assert (!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace);
#endif #endif
/* Generation of data for meta class */ /* Generation of data for meta class. */
my_super_id = CLASS_SUPER_NAME (impent->imp_template); my_super_id = CLASS_SUPER_NAME (impent->imp_template);
if (my_super_id) if (my_super_id)
{ {
/* compute reference to root's name. For meta class, "isa" is reference /* Compute reference to root's name. For a meta class, "isa" is
to root class name. */ a reference to the root class name. */
tree my_root_id = my_super_id; tree my_root_id = my_super_id;
tree my_root_int, interface; tree my_root_int, interface;
do do
...@@ -3140,11 +3167,11 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3140,11 +3167,11 @@ generate_v2_class_structs (struct imp_entry *impent)
} }
else else
{ {
/* root class. */ /* Root class. */
root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0); root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0);
metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0); metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0);
class_superclass_expr = build_int_cst (NULL_TREE, 0); class_superclass_expr = build_int_cst (NULL_TREE, 0);
flags |= 0x02; /* RO_ROOT: it is also a root meta class */ flags |= 0x02; /* RO_ROOT: it is also a root meta class. */
} }
if (CLASS_PROTOCOL_LIST (impent->imp_template)) if (CLASS_PROTOCOL_LIST (impent->imp_template))
...@@ -3170,10 +3197,11 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3170,10 +3197,11 @@ generate_v2_class_structs (struct imp_entry *impent)
instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template)); instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));
/* Currently there are no class ivars and generation of class variables for /* Currently there are no class ivars and generation of class
the root of the inheritance has been removed. It causes multiple defines variables for the root of the inheritance has been removed. It
if there are two root classes in the link, because each will define its causes multiple defines if there are two root classes in the
own identically-named offset variable. */ link, because each will define its own identically-named offset
variable. */
class_ivars = NULL_TREE; class_ivars = NULL_TREE;
/* TODO: Add total size of class variables when implemented. */ /* TODO: Add total size of class variables when implemented. */
...@@ -3239,7 +3267,7 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3239,7 +3267,7 @@ generate_v2_class_structs (struct imp_entry *impent)
impent->imp_template); impent->imp_template);
} }
/* Compute instanceStart */ /* Compute instanceStart. */
gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template)); gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template));
field = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (impent->imp_template)); field = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (impent->imp_template));
if (my_super_id && field && TREE_CHAIN (field)) if (my_super_id && field && TREE_CHAIN (field))
...@@ -3252,7 +3280,7 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3252,7 +3280,7 @@ generate_v2_class_structs (struct imp_entry *impent)
gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true); gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true);
/* Compute instanceSize */ /* Compute instanceSize. */
while (field && TREE_CHAIN (field) while (field && TREE_CHAIN (field)
&& TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL) && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
field = TREE_CHAIN (field); field = TREE_CHAIN (field);
...@@ -3266,8 +3294,8 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3266,8 +3294,8 @@ generate_v2_class_structs (struct imp_entry *impent)
props = generate_v2_property_table (NULL_TREE, impent->imp_context); props = generate_v2_property_table (NULL_TREE, impent->imp_context);
/* If the class has no ivars, instanceStart should be set to the superclass's /* If the class has no ivars, instanceStart should be set to the
instanceSize */ superclass's instanceSize. */
instanceStart = instanceStart =
(inst_ivars != NULL_TREE) ? (unsigned) int_byte_position (firstIvar) (inst_ivars != NULL_TREE) ? (unsigned) int_byte_position (firstIvar)
: instanceSize; : instanceSize;
...@@ -3307,7 +3335,8 @@ generate_v2_class_structs (struct imp_entry *impent) ...@@ -3307,7 +3335,8 @@ generate_v2_class_structs (struct imp_entry *impent)
objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template)); objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template));
} }
/* This routine outputs the (ivar_reference_offset, offset) tuples. */ /* This routine outputs the (ivar_reference_offset, offset)
tuples. */
static void static void
build_v2_ivar_offset_ref_table (void) build_v2_ivar_offset_ref_table (void)
...@@ -3352,6 +3381,9 @@ objc_generate_v2_next_metadata (void) ...@@ -3352,6 +3381,9 @@ objc_generate_v2_next_metadata (void)
{ {
struct imp_entry *impent; struct imp_entry *impent;
/* 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_assert (!objc_static_instances); /* Not for NeXT */
build_metadata_templates (); build_metadata_templates ();
...@@ -3359,8 +3391,8 @@ objc_generate_v2_next_metadata (void) ...@@ -3359,8 +3391,8 @@ objc_generate_v2_next_metadata (void)
for (impent = imp_list; impent; impent = impent->next) for (impent = imp_list; impent; impent = impent->next)
{ {
/* If -gen-decls is present, Dump the @interface of each class. /* If -gen-decls is present, Dump the @interface of each class.
TODO: Dump the classes in the order they were found, rather than in TODO: Dump the classes in the order they were found, rather
reverse order as we are doing now. */ than in reverse order as we are doing now. */
if (flag_gen_declaration) if (flag_gen_declaration)
dump_interface (gen_declaration_file, impent->imp_context); dump_interface (gen_declaration_file, impent->imp_context);
...@@ -3429,10 +3461,11 @@ build_v2_ehtype_template (void) ...@@ -3429,10 +3461,11 @@ build_v2_ehtype_template (void)
objc_finish_struct (objc_v2_ehtype_template, decls); objc_finish_struct (objc_v2_ehtype_template, decls);
} }
/* Template for the Objective-C family typeinfo type for ABI=2. /* Template for the Objective-C family typeinfo type for ABI=2. This
This starts off the same as the gxx/cxx eh typeinfo. starts off the same as the gxx/cxx eh typeinfo.
struct _objc_ehtype_t { struct _objc_ehtype_t
{
void *_objc_ehtype_vtable_ptr; - as per c++ void *_objc_ehtype_vtable_ptr; - as per c++
const char *className; - as per c++ const char *className; - as per c++
struct class_t *const cls; struct class_t *const cls;
...@@ -3448,9 +3481,10 @@ objc2_build_ehtype_initializer (tree name, tree cls) ...@@ -3448,9 +3481,10 @@ objc2_build_ehtype_initializer (tree name, tree cls)
VEC(constructor_elt,gc) *initlist = NULL; VEC(constructor_elt,gc) *initlist = NULL;
tree addr, offs; tree addr, offs;
/* This is done the same way as c++, missing the two first entries in the /* This is done the same way as c++, missing the two first entries
parent vtable. NOTE: there is a fix-me in the Apple/NeXT runtime source in the parent vtable. NOTE: there is a fix-me in the Apple/NeXT
about this so, perhaps, this will change at some point. */ runtime source about this so, perhaps, this will change at some
point. */
/* _objc_ehtype_vtable + 2*sizeof(void*) */ /* _objc_ehtype_vtable + 2*sizeof(void*) */
if (!next_v2_ehvtable_decl) if (!next_v2_ehvtable_decl)
{ {
...@@ -3481,7 +3515,8 @@ build_ehtype (tree name, const char *eh_name, bool weak) ...@@ -3481,7 +3515,8 @@ build_ehtype (tree name, const char *eh_name, bool weak)
tree name_expr, class_name_expr, ehtype_decl, inits; tree name_expr, class_name_expr, ehtype_decl, inits;
name_expr = add_objc_string (name, class_names); name_expr = add_objc_string (name, class_names);
/* Extern ref. for the class. ??? maybe we can look this up somewhere. */ /* Extern ref. for the class. ??? Maybe we can look this up
somewhere. */
class_name_expr = class_name_expr =
create_extern_decl (objc_v2_class_template, create_extern_decl (objc_v2_class_template,
objc_build_internal_classname (name, false)); objc_build_internal_classname (name, false));
...@@ -3496,8 +3531,7 @@ build_ehtype (tree name, const char *eh_name, bool weak) ...@@ -3496,8 +3531,7 @@ build_ehtype (tree name, const char *eh_name, bool weak)
} }
/* This routine returns TRUE if CLS or any of its super classes has /* This routine returns TRUE if CLS or any of its super classes has
__attribute__ ((objc_exception)). __attribute__ ((objc_exception)). */
*/
static bool static bool
objc2_objc_exception_attr (tree cls) objc2_objc_exception_attr (tree cls)
...@@ -3565,10 +3599,9 @@ lookup_ehtype_ref (tree id) ...@@ -3565,10 +3599,9 @@ lookup_ehtype_ref (tree id)
return NULL_TREE; return NULL_TREE;
} }
/* This hook, called via lang_eh_runtime_type, generates a runtime object /* This hook, called via lang_eh_runtime_type, generates a runtime
which is either the address of the 'OBJC_EHTYPE_$_class' object or object which is either the address of the 'OBJC_EHTYPE_$_class'
address of external OBJC_EHTYPE_id object. object or address of external OBJC_EHTYPE_id object. */
*/
static tree static tree
next_runtime_02_eh_type (tree type) next_runtime_02_eh_type (tree type)
{ {
...@@ -3582,8 +3615,8 @@ next_runtime_02_eh_type (tree type) ...@@ -3582,8 +3615,8 @@ next_runtime_02_eh_type (tree type)
{ {
if (!next_v2_EHTYPE_id_decl) if (!next_v2_EHTYPE_id_decl)
{ {
/* This is provided by the Apple/NeXT libobjc.dylib so we need /* This is provided by the Apple/NeXT libobjc.dylib so we
only to reference it. */ need only to reference it. */
next_v2_EHTYPE_id_decl = next_v2_EHTYPE_id_decl =
start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id"); start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id");
DECL_EXTERNAL (next_v2_EHTYPE_id_decl) = 1; DECL_EXTERNAL (next_v2_EHTYPE_id_decl) = 1;
...@@ -3596,8 +3629,8 @@ next_runtime_02_eh_type (tree type) ...@@ -3596,8 +3629,8 @@ next_runtime_02_eh_type (tree type)
if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type))) if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
{ {
#ifdef OBJCPLUS #ifdef OBJCPLUS
/* This routine is also called for c++'s catch clause; in which case, /* This routine is also called for c++'s catch clause; in which
we use c++'s typeinfo decl. */ case, we use c++'s typeinfo decl. */
return build_eh_type_type (type); return build_eh_type_type (type);
#else #else
error ("non-objective-c type '%T' cannot be caught", type); error ("non-objective-c type '%T' cannot be caught", type);
...@@ -3639,7 +3672,7 @@ build_throw_stmt (location_t loc, tree throw_expr, bool rethrown) ...@@ -3639,7 +3672,7 @@ build_throw_stmt (location_t loc, tree throw_expr, bool rethrown)
t = build_function_call_vec (loc, objc_rethrow_exception_decl, NULL, NULL); t = build_function_call_vec (loc, objc_rethrow_exception_decl, NULL, NULL);
else else
{ {
/* Throw like the others .. */ /* Throw like the others... */
VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1); VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
VEC_quick_push (tree, parms, throw_expr); VEC_quick_push (tree, parms, throw_expr);
t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL); t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
...@@ -3675,14 +3708,15 @@ static tree begin_catch (struct objc_try_context **cur_try_context, tree type, ...@@ -3675,14 +3708,15 @@ static tree begin_catch (struct objc_try_context **cur_try_context, tree type,
/* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */ /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
t = objc_build_exc_ptr (cur_try_context); t = objc_build_exc_ptr (cur_try_context);
t = convert (TREE_TYPE (decl), t); t = convert (TREE_TYPE (decl), t);
/* TODO location stuff. */ /* FIXME: location. */
if (type && type != error_mark_node) if (type && type != error_mark_node)
{ {
t = build1(NOP_EXPR, ptr_type_node, t); t = build1(NOP_EXPR, ptr_type_node, t);
t = build_function_call (input_location, objc2_begin_catch_decl, t = build_function_call (input_location, objc2_begin_catch_decl,
tree_cons (NULL_TREE, t, NULL_TREE)); tree_cons (NULL_TREE, t, NULL_TREE));
/* We might want to build a catch object for this (if it's not id). */ /* We might want to build a catch object for this (if it's not
id). */
if (POINTER_TYPE_P (type) if (POINTER_TYPE_P (type)
&& !objc_is_object_id (TREE_TYPE (type)) && !objc_is_object_id (TREE_TYPE (type))
&& TYPED_OBJECT (TREE_TYPE (type))) && TYPED_OBJECT (TREE_TYPE (type)))
...@@ -3705,20 +3739,20 @@ finish_catch (struct objc_try_context **cur_try_context, tree curr_catch) ...@@ -3705,20 +3739,20 @@ finish_catch (struct objc_try_context **cur_try_context, tree curr_catch)
t = CATCH_BODY (curr_catch); t = CATCH_BODY (curr_catch);
if (TREE_CODE (t) == BIND_EXPR) if (TREE_CODE (t) == BIND_EXPR)
{ {
/* usual case of @catch (objc-expr). */ /* Usual case of @catch (objc-expr). */
objc_begin_try_stmt (loc, BIND_EXPR_BODY (t)); objc_begin_try_stmt (loc, BIND_EXPR_BODY (t));
BIND_EXPR_BODY (t) = NULL_TREE; BIND_EXPR_BODY (t) = NULL_TREE;
l = &BIND_EXPR_BODY (t); l = &BIND_EXPR_BODY (t);
} }
else else
{ {
/* NULL entry, @catch (...) */ /* NULL entry, meaning @catch (...). */
objc_begin_try_stmt (loc, t); objc_begin_try_stmt (loc, t);
CATCH_BODY (curr_catch) = NULL_TREE; CATCH_BODY (curr_catch) = NULL_TREE;
l = &CATCH_BODY (curr_catch); l = &CATCH_BODY (curr_catch);
} }
/* Pick up the new context we made in begin_try above.. */ /* Pick up the new context we made in begin_try above... */
ct = *cur_try_context; ct = *cur_try_context;
func = build_function_call_vec (loc, objc2_end_catch_decl, NULL, NULL); func = build_function_call_vec (loc, objc2_end_catch_decl, NULL, NULL);
append_to_statement_list (func, &ct->finally_body); append_to_statement_list (func, &ct->finally_body);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment