Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
c2beaa02
Commit
c2beaa02
authored
Feb 19, 2011
by
Nicola Pero
Committed by
Nicola Pero
Feb 19, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated comments
From-SVN: r170308
parent
54ba9323
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
295 additions
and
244 deletions
+295
-244
gcc/objc/ChangeLog
+5
-0
gcc/objc/objc-next-runtime-abi-01.c
+48
-36
gcc/objc/objc-next-runtime-abi-02.c
+242
-208
No files found.
gcc/objc/ChangeLog
View file @
c2beaa02
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
.
...
...
gcc/objc/objc-next-runtime-abi-01.c
View file @
c2beaa02
...
@@ -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 th
e
module (file) was compiled for, and is recorded in the modul
e
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 whe
n
allow the FE to tag meta-data in a manner that survives LTO and ca
n
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 */
...
...
gcc/objc/objc-next-runtime-abi-02.c
View file @
c2beaa02
...
@@ -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 an
d
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'
t
he address of a class.
*/
t
o 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
{
{
/*
r
oot class. */
/*
R
oot 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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment