diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-27 09:53:43 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-27 09:53:43 +0000 |
commit | 2f78a7ce0a8d0ccd0b3142ec45da79a32fbd601d (patch) | |
tree | 895f2f8651a945915cdbeae810ca04b6e2835748 /gcc/objc | |
parent | 1d400a467fc4064fc1ee232f8ba15f0b7c54331d (diff) | |
download | gcc-2f78a7ce0a8d0ccd0b3142ec45da79a32fbd601d.tar.gz |
In gcc/objc/:
2010-11-27 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_build_struct): Fixed loops that save and
restore TYPE_OBJC_INFO to iterate over all variants of the type; a
special case for the current type is then no longer required.
Duplicate TYPE_LANG_SPECIFIC for each type before restoring
TYPE_OBJC_INFO.
(objc_get_protocol_qualified_type): Updated comments.
In gcc/testsuite/:
2010-11-27 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/protocol-qualifier-1.m: New.
* objc.dg/protocol-qualifier-2.m: New.
* obj-c++.dg/protocol-qualifier-1.mm: New.
* obj-c++.dg/protocol-qualifier-2.mm: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167195 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/objc')
-rw-r--r-- | gcc/objc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 75 |
2 files changed, 56 insertions, 28 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index fb1ee6a4de3..7c890ce7e2e 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,12 @@ +2010-11-27 Nicola Pero <nicola.pero@meta-innovation.com> + + * objc-act.c (objc_build_struct): Fixed loops that save and + restore TYPE_OBJC_INFO to iterate over all variants of the type; a + special case for the current type is then no longer required. + Duplicate TYPE_LANG_SPECIFIC for each type before restoring + TYPE_OBJC_INFO. + (objc_get_protocol_qualified_type): Updated comments. + 2010-11-25 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_build_struct): Install TYPE_OBJC_INTERFACE diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 042fa359a4f..232708f6dbb 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2137,41 +2137,54 @@ objc_build_struct (tree klass, tree fields, tree super_name) fields = base; } - /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC - fields in all variants of this RECORD_TYPE to be clobbered (this - is because the C frontend stores a sorted version of the list of - fields in lang_type if it deems appropriate, and will update and - propagate that list to all variants ignoring the fact that we use - lang_type for something else and that such propagation will wipe - the objc_info away), but it is therein that we store protocol - conformance info (e.g., 'NSObject <MyProtocol>'). Hence, we must - squirrel away the ObjC-specific information before calling + /* NB: Calling finish_struct() may cause type TYPE_OBJC_INFO + information in all variants of this RECORD_TYPE to be destroyed + (this is because the C frontend manipulates TYPE_LANG_SPECIFIC + for something else and then will change all variants to use the + same resulting TYPE_LANG_SPECIFIC, ignoring the fact that we use + it for ObjC protocols and that such propagation will make all + variants use the same objc_info), but it is therein that we store + protocol conformance info (e.g., 'NSObject <MyProtocol>'). + Hence, we must save the ObjC-specific information before calling finish_struct(), and then reinstate it afterwards. */ - for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t)) + for (t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t)) { - if (!TYPE_HAS_OBJC_INFO (t)) - { - INIT_TYPE_OBJC_INFO (t); - TYPE_OBJC_INTERFACE (t) = klass; - } + INIT_TYPE_OBJC_INFO (t); VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t)); } s = objc_finish_struct (s, fields); - /* Point the struct at its related Objective-C class. We do this - after calling finish_struct() because otherwise finish_struct() - would wipe TYPE_OBJC_INTERFACE() out. */ - if (!TYPE_HAS_OBJC_INFO (s)) - INIT_TYPE_OBJC_INFO (s); - - TYPE_OBJC_INTERFACE (s) = klass; - - for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++) + for (i = 0, t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++) { + /* We now want to restore the different TYPE_OBJC_INFO, but we + have the additional problem that the C frontend doesn't just + copy TYPE_LANG_SPECIFIC from one variant to the other; it + actually makes all of them the *same* TYPE_LANG_SPECIFIC. As + we need a different TYPE_OBJC_INFO for each (and + TYPE_OBJC_INFO is a field in TYPE_LANG_SPECIFIC), we need to + make a copy of each TYPE_LANG_SPECIFIC before we modify + TYPE_OBJC_INFO. */ + if (TYPE_LANG_SPECIFIC (t)) + { + /* Create a copy of TYPE_LANG_SPECIFIC. */ + struct lang_type *old_lang_type = TYPE_LANG_SPECIFIC (t); + ALLOC_OBJC_TYPE_LANG_SPECIFIC (t); + memcpy (TYPE_LANG_SPECIFIC (t), old_lang_type, + SIZEOF_OBJC_TYPE_LANG_SPECIFIC); + } + else + { + /* Just create a new one. */ + ALLOC_OBJC_TYPE_LANG_SPECIFIC (t); + } + /* Replace TYPE_OBJC_INFO with the saved one. This restores any + protocol information that may have been associated with the + type. */ TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i); - /* Replace the IDENTIFIER_NODE with an actual @interface. */ + /* Replace the IDENTIFIER_NODE with an actual @interface now + that we have it. */ TYPE_OBJC_INTERFACE (t) = klass; } VEC_free (tree, heap, objc_info); @@ -2766,9 +2779,12 @@ objc_non_volatilized_type (tree type) return type; } -/* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may - either name an Objective-C class, or refer to the special 'id' or 'Class' - types. If INTERFACE is not a valid ObjC type, just return it unchanged. */ +/* Construct a PROTOCOLS-qualified variant of INTERFACE, where + INTERFACE may either name an Objective-C class, or refer to the + special 'id' or 'Class' types. If INTERFACE is not a valid ObjC + type, just return it unchanged. This function is often called when + PROTOCOLS is NULL_TREE, in which case we simply look up the + appropriate INTERFACE. */ tree objc_get_protocol_qualified_type (tree interface, tree protocols) @@ -4422,6 +4438,9 @@ objc_declare_class (tree ident_list) record = xref_tag (RECORD_TYPE, ident); INIT_TYPE_OBJC_INFO (record); + /* In the case of a @class declaration, we store the ident + in the TYPE_OBJC_INTERFACE. If later an @interface is + found, we'll replace the ident with the interface. */ TYPE_OBJC_INTERFACE (record) = ident; hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE); } |