This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Ziemowit Laski wrote:
> Oh, yeah, and I cleaned up <objc/...> headers to be usable with ObjC++.
>
Did you simply merge in Andrew's changes to libobjc or were there other
changes necessary?
>>
>>David, if you want to whip-up an identifier cleanup patch for
>>objc-improvements-branch, go for it. :-)
>>
Here is the cumulative patch adapted for the objc-improvements-branch for:
[RFA] c-parse.in unify ObjC tokens
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00782.html
[RFA][objc] Identifier cleanup
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg01561.html
[RFC/RFA] [ObjC] Class <protocol> support I
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg02496.html
I see that you have dealt with gcc/testsuite/objc.dg/id-1.m in a
different way already on the branch. But I must admit that I find the
new diagnostics...
id-1.m:4: error: conflicting types for 'id'
id-1.m:0: error: previous declaration of 'id' was here
(note the missing location and line number 0 as this seems to be a built
in type now) a bit misleading.
Anyway, bootstrapped and testing passed (including obj-c++)
Cheers,
David
PS: Why did you choose 'obj-c++' over of 'objc++' in various places? I
seems needlessly inconsistent.
2004-06-30 David Ayers <d.ayers@inode.at>
* objc.dg/class-protocol-1.m: New test.
gcc/
2004-06-30 David Ayers <d.ayers@inode.at>
* c-common.h: Remove RID_ID.
* c-parse.in: Unify Objective-C token names. Remove OBJECTNAME
and references to RID_ID.
(typespec_reserved_attr): Add rule for TYPENAME
non_empty_protocolrefs.
(yylexname): Remove special handling of RID_ID.
* objc/objc-act.h (super_type): Rename to objc_super_type.
(selector_type): Rename to objc_selector_type.
(instance_type): Rename to objc_instance_type.
(protocol_type): Rename to objc_protocol_type.
(PROTOCOL_DECLARED_BY_ROOT): New macro.
* objc/objc-act.c (lookup_method_in_protocol_list): Rename
class_meth to is_class. Add documentation.
(objc_finish_message_expr): Rename is_class to class_tree.
(synth_module_prologue, objc_build_protocol_expr): Update
references to protocol_type.
(synth_module_prologue, build_objc_symtab_template)
(init_objc_symtab, build_selector_reference_decl)
(build_selector_table_decl, build_selector)
(build_selector_translation_table)
(build_typed_selector_reference, build_method_prototype_template)
(build_selector_template, build_method_template)
(get_arg_type_list, synth_self_and_ucmd_args): Update references
to selector_type.
(build_private_template, build_ivar_reference):Update references
to instance_type.
(synth_module_prologue, get_arg_type_list)
(build_objc_method_call): Update references to super_type.
(mark_protocols_declared_by_root_class)
(instance_prototype_of_root_protocol): Add new functions.
(objc_finish_interface): Register instance prototypes as class
prototypes if the interface context is a protocol which has
previously been referenced by a root class.
(objc_get_protocol_qualified_type): Report error for unknown types
with protocol qualifiers. Update documentation.
(objc_finish_message_expr): Extend prototype search for protocol
qualified classes.
(start_class): Call mark_protocols_declared_by_root_class if
processing a root class with protocol references.
(lookup_and_install_protocols): Update documentation.
* objc/objc-tree.def: Add C mode identifier sequence.
gcc/cp
2004-06-30 David Ayers <d.ayers@inode.at>
* lex.c: Remove references to RID_ID.
Index: gcc/c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.189.2.18
diff -u -r1.189.2.18 c-common.h
--- gcc/c-common.h 26 Jun 2004 04:01:35 -0000 1.189.2.18
+++ gcc/c-common.h 30 Jun 2004 07:29:28 -0000
@@ -96,7 +96,7 @@
RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
/* Objective-C */
- RID_ID, RID_AT_ENCODE, RID_AT_END,
+ RID_AT_ENCODE, RID_AT_END,
RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS,
RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC,
RID_AT_PROTOCOL, RID_AT_SELECTOR,
Index: gcc/c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.170.2.14
diff -u -r1.170.2.14 c-parse.in
--- gcc/c-parse.in 26 Jun 2004 04:01:36 -0000 1.170.2.14
+++ gcc/c-parse.in 30 Jun 2004 07:29:29 -0000
@@ -171,8 +171,9 @@
/* The Objective-C keywords. These are included in C and in
Objective C, so that the token codes are the same in both. */
-%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
-%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+%token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE
+%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
+%token AT_CLASS AT_ALIAS
%token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
%token OBJC_STRING
@@ -244,7 +245,7 @@
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
-%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+%type <ttype> CLASSNAME OBJC_STRING
%type <ttype> superclass
%type <itype> objc_try_catch_stmt objc_finally_block optellipsis
@@ -440,7 +441,6 @@
IDENTIFIER
| TYPENAME
@@ifobjc
- | OBJECTNAME
| CLASSNAME
@@end_ifobjc
;
@@ -1326,7 +1326,7 @@
@@ifobjc
| CLASSNAME protocolrefs
{ $$ = objc_get_protocol_qualified_type ($1, $2); }
- | OBJECTNAME protocolrefs
+ | TYPENAME non_empty_protocolrefs
{ $$ = objc_get_protocol_qualified_type ($1, $2); }
/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
@@ -1594,9 +1594,6 @@
| '*' maybe_type_quals_attrs after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
| TYPENAME
-@@ifobjc
- | OBJECTNAME
-@@end_ifobjc
;
/* Kinds of declarator that can appear in a parameter list
@@ -1614,9 +1611,6 @@
| parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
| TYPENAME
-@@ifobjc
- | OBJECTNAME
-@@end_ifobjc
;
parm_declarator_nostarttypename:
@@ -1761,7 +1755,7 @@
pedwarn ("extra semicolon in struct or union specified"); }
@@ifobjc
/* foo(sizeof(struct{ @defs(ClassName)})); */
- | DEFS '(' CLASSNAME ')'
+ | AT_DEFS '(' CLASSNAME ')'
{ $$ = nreverse (objc_get_class_ivars ($3)); }
@@end_ifobjc
;
@@ -2710,7 +2704,7 @@
| aliasdecl
| protocoldef
| methoddef
- | END
+ | AT_END
{
objc_finish_implementation ();
}
@@ -2725,14 +2719,14 @@
;
classdecl:
- CLASS identifier_list ';'
+ AT_CLASS identifier_list ';'
{
objc_declare_class ($2);
}
;
aliasdecl:
- ALIAS identifier identifier ';'
+ AT_ALIAS identifier identifier ';'
{
objc_declare_alias ($2, $3);
}
@@ -2749,7 +2743,7 @@
;
classdef:
- INTERFACE identifier superclass protocolrefs
+ AT_INTERFACE identifier superclass protocolrefs
{
objc_start_class_interface ($2, $3, $4);
}
@@ -2757,12 +2751,12 @@
{
objc_continue_interface ();
}
- methodprotolist END
+ methodprotolist AT_END
{
objc_finish_interface ();
}
- | IMPLEMENTATION identifier superclass
+ | AT_IMPLEMENTATION identifier superclass
{
objc_start_class_implementation ($2, $3);
}
@@ -2771,28 +2765,28 @@
objc_continue_implementation ();
}
- | INTERFACE identifier '(' identifier ')' protocolrefs
+ | AT_INTERFACE identifier '(' identifier ')' protocolrefs
{
objc_start_category_interface ($2, $4, $6);
}
- methodprotolist END
+ methodprotolist AT_END
{
objc_finish_interface ();
}
- | IMPLEMENTATION identifier '(' identifier ')'
+ | AT_IMPLEMENTATION identifier '(' identifier ')'
{
objc_start_category_implementation ($2, $4);
}
;
protocoldef:
- PROTOCOL identifier protocolrefs
+ AT_PROTOCOL identifier protocolrefs
{
objc_pq_context = 1;
objc_start_protocol ($2, $3);
}
- methodprotolist END
+ methodprotolist AT_END
{
objc_pq_context = 0;
objc_finish_interface ();
@@ -2800,7 +2794,7 @@
/* The @protocol forward-declaration production introduces a
reduce/reduce conflict on ';', which should be resolved in
favor of the production 'identifier_list -> identifier'. */
- | PROTOCOL identifier_list ';'
+ | AT_PROTOCOL identifier_list ';'
{
objc_declare_protocols ($2);
}
@@ -2830,9 +2824,9 @@
;
visibility_spec:
- PRIVATE { objc_set_visibility (2); }
- | PROTECTED { objc_set_visibility (0); }
- | PUBLIC { objc_set_visibility (1); }
+ AT_PRIVATE { objc_set_visibility (2); }
+ | AT_PROTECTED { objc_set_visibility (0); }
+ | AT_PUBLIC { objc_set_visibility (1); }
;
ivar_decls:
@@ -3023,7 +3017,6 @@
IDENTIFIER
| TYPENAME
| CLASSNAME
- | OBJECTNAME
| reservedwords
;
@@ -3135,14 +3128,14 @@
;
objcselectorexpr:
- SELECTOR '(' selectorarg ')'
+ AT_SELECTOR '(' selectorarg ')'
{
$$ = $3;
}
;
objcprotocolexpr:
- PROTOCOL '(' identifier ')'
+ AT_PROTOCOL '(' identifier ')'
{
$$ = $3;
}
@@ -3151,7 +3144,7 @@
/* extension to support C-structures in the archiver */
objcencodeexpr:
- ENCODE '(' typename ')'
+ AT_ENCODE '(' typename ')'
{
$$ = groktypename ($3);
}
@@ -3260,8 +3253,6 @@
{ "volatile", RID_VOLATILE, 0 },
{ "while", RID_WHILE, 0 },
@@ifobjc
- { "id", RID_ID, D_OBJC },
-
/* These objc keywords are recognized only immediately after
an '@'. */
{ "class", RID_AT_CLASS, D_OBJC },
@@ -3406,24 +3397,23 @@
/* RID_STATCAST */ 0,
/* Objective C */
- /* RID_ID */ OBJECTNAME,
- /* RID_AT_ENCODE */ ENCODE,
- /* RID_AT_END */ END,
- /* RID_AT_CLASS */ CLASS,
- /* RID_AT_ALIAS */ ALIAS,
- /* RID_AT_DEFS */ DEFS,
- /* RID_AT_PRIVATE */ PRIVATE,
- /* RID_AT_PROTECTED */ PROTECTED,
- /* RID_AT_PUBLIC */ PUBLIC,
- /* RID_AT_PROTOCOL */ PROTOCOL,
- /* RID_AT_SELECTOR */ SELECTOR,
+ /* RID_AT_ENCODE */ AT_ENCODE,
+ /* RID_AT_END */ AT_END,
+ /* RID_AT_CLASS */ AT_CLASS,
+ /* RID_AT_ALIAS */ AT_ALIAS,
+ /* RID_AT_DEFS */ AT_DEFS,
+ /* RID_AT_PRIVATE */ AT_PRIVATE,
+ /* RID_AT_PROTECTED */ AT_PROTECTED,
+ /* RID_AT_PUBLIC */ AT_PUBLIC,
+ /* RID_AT_PROTOCOL */ AT_PROTOCOL,
+ /* RID_AT_SELECTOR */ AT_SELECTOR,
/* RID_AT_THROW */ AT_THROW,
/* RID_AT_TRY */ AT_TRY,
/* RID_AT_CATCH */ AT_CATCH,
/* RID_AT_FINALLY */ AT_FINALLY,
/* RID_AT_SYNCHRONIZED */ AT_SYNCHRONIZED,
- /* RID_AT_INTERFACE */ INTERFACE,
- /* RID_AT_IMPLEMENTATION */ IMPLEMENTATION
+ /* RID_AT_INTERFACE */ AT_INTERFACE,
+ /* RID_AT_IMPLEMENTATION */ AT_IMPLEMENTATION
};
static void
@@ -3475,15 +3465,6 @@
enum rid rid_code = C_RID_CODE (yylval.ttype);
@@ifobjc
- /* Turn non-typedefed refs to "id" into plain identifiers; this
- allows constructs like "void foo(id id);" to work. */
- if (rid_code == RID_ID)
- {
- decl = lookup_name (yylval.ttype);
- if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
- return IDENTIFIER;
- }
-
if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
@@end_ifobjc
@@ -3646,7 +3627,6 @@
{
case IDENTIFIER:
case TYPENAME:
- case OBJECTNAME:
case TYPESPEC:
case TYPE_QUAL:
case SCSPEC:
Index: gcc/cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.309.2.8
diff -u -r1.309.2.8 lex.c
--- gcc/cp/lex.c 2 Apr 2004 00:11:46 -0000 1.309.2.8
+++ gcc/cp/lex.c 30 Jun 2004 07:29:33 -0000
@@ -349,7 +349,6 @@
All of them will remain _disabled_, since they are context-
sensitive. */
- { "id", RID_ID, D_OBJC },
/* These ObjC keywords are recognized only immediately after
an '@'. NB: The following C++ keywords double as
ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.179.2.29
diff -u -r1.179.2.29 objc-act.c
--- gcc/objc/objc-act.c 26 Jun 2004 04:01:38 -0000 1.179.2.29
+++ gcc/objc/objc-act.c 30 Jun 2004 07:29:37 -0000
@@ -238,6 +238,8 @@
static tree lookup_protocol (tree);
static void check_protocol_recursively (tree, tree);
static tree lookup_and_install_protocols (tree);
+static void mark_protocols_declared_by_root_class (tree, int);
+static tree instance_prototype_of_root_protocol (tree, tree, int);
/* Type encoding. */
@@ -609,9 +611,14 @@
return decl;
}
+/* Return the first occurrence of a method declaration corresponding
+ to SEL_NAME in RPROTO_LIST. Search RPROTO_LIST recursively.
+ If IS_CLASS is 0, search for instance methods, otherwise for class
+ methods. */
+
static tree
lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
- int class_meth)
+ int is_class)
{
tree rproto, p;
tree fnd = 0;
@@ -622,13 +629,13 @@
if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
{
- if ((fnd = lookup_method (class_meth
+ if ((fnd = lookup_method (is_class
? PROTOCOL_CLS_METHODS (p)
: PROTOCOL_NST_METHODS (p), sel_name)))
;
else if (PROTOCOL_LIST (p))
fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
- sel_name, class_meth);
+ sel_name, is_class);
}
else
{
@@ -712,6 +719,28 @@
objc_finish_interface (void)
{
finish_class (objc_interface_context);
+
+ if (TREE_CODE (objc_interface_context) == PROTOCOL_INTERFACE_TYPE
+ && PROTOCOL_DECLARED_BY_ROOT (objc_interface_context))
+ {
+ tree protocol = objc_interface_context;
+ tree method_decl;
+
+ /* Since we do not have a protocol list,
+ go ahead and register the method list directly. */
+ for (method_decl = PROTOCOL_NST_METHODS (protocol);
+ method_decl;
+ method_decl = TREE_CHAIN (method_decl))
+ {
+ add_method_to_hash_list(cls_method_hash_list, method_decl);
+ }
+
+ /* This protocol is marked. Now insure that that all instance
+ prototypes of inherited protocols get registered as class
+ methods without marking them. */
+ mark_protocols_declared_by_root_class (PROTOCOL_LIST (protocol), 1);
+ }
+
objc_interface_context = NULL_TREE;
}
@@ -1152,7 +1181,7 @@
/* 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. */
+ types. If INTERFACE is not a valid ObjC type, report error. */
tree
objc_get_protocol_qualified_type (tree interface, tree protocols)
@@ -1168,7 +1197,7 @@
if (type)
type = xref_tag (RECORD_TYPE, type);
else
- return interface;
+ error ("protocol qualifiers specified for non-ObjC type");
}
if (protocols)
@@ -1221,8 +1250,10 @@
}
}
-/* Look up PROTOCOLS, and return a list of those that are found.
- If none are found, return NULL. */
+/* Look up PROTOCOLS, a list of identifiers, and return a list
+ of the protocol interface declarations that are found. Invokes error
+ for each identifier for which the lookup failed.
+ If PROTOCOLS is empty, return NULL. */
static tree
lookup_and_install_protocols (tree protocols)
@@ -1246,6 +1277,95 @@
return return_value;
}
+/* Iterates over the protocol interface list RPROTOS marking each as
+ PROTOCOL_DECLARED_BY_ROOT. Registers the instance methods prototypes
+ of each protocol and their inherited protocols recursively as
+ potential class methods. IGNORE should always be 0. It is used
+ for recursive calls to insure that inherited protocols will not be
+ marked unduly. */
+
+static void
+mark_protocols_declared_by_root_class (tree rprotos, int ignore)
+{
+ tree protocol_ch;
+ tree protocol;
+
+ for (protocol_ch = rprotos;
+ protocol_ch;
+ protocol_ch = TREE_CHAIN (protocol_ch))
+ {
+ protocol = TREE_CHECK(TREE_VALUE (protocol_ch),
+ PROTOCOL_INTERFACE_TYPE);
+
+ /* Minor efficency check. Expect all protocols which have
+ been previously marked, to have had their methods registered.
+ A protocol which itself is not declared by a root class yet
+ is inherited by multiple root classes will have its instance
+ methods processed redundantly, but it does not seem worth while
+ to flag them just to avoid this. */
+ if (!PROTOCOL_DECLARED_BY_ROOT (protocol))
+ {
+ tree method_decl;
+
+ for (method_decl = PROTOCOL_NST_METHODS (protocol);
+ method_decl;
+ method_decl = TREE_CHAIN (method_decl))
+ {
+ add_method_to_hash_list(cls_method_hash_list, method_decl);
+ }
+ }
+
+ if (!ignore)
+ {
+ PROTOCOL_DECLARED_BY_ROOT (protocol) = 1;
+ }
+
+ mark_protocols_declared_by_root_class (PROTOCOL_LIST (protocol), 1);
+ }
+}
+
+/* Searches for SELECTOR in the instance methods
+ of the protocol interface list RPROTOS. Returns
+ the prototype only if the corresponding protocol from RPROTOS
+ is declared by any root class. IGNORE should always be 0.
+ It is used for the recursive prototype search of inherited protocols. */
+
+static tree
+instance_prototype_of_root_protocol (tree rprotos, tree selector, int ignore)
+{
+ tree protocol_ch;
+ tree protocol;
+ tree prototype = NULL_TREE;
+
+ /* Loop over protocol list and search for protocols
+ that declare the method as an instance method. */
+ for (protocol_ch = rprotos;
+ protocol_ch;
+ protocol_ch = TREE_CHAIN (protocol_ch))
+ {
+ protocol = TREE_CHECK(TREE_VALUE (protocol_ch),
+ PROTOCOL_INTERFACE_TYPE);
+
+ if (ignore || PROTOCOL_DECLARED_BY_ROOT (protocol))
+ {
+ /* Check the protocol itself. */
+ prototype = lookup_method (PROTOCOL_NST_METHODS (protocol),
+ selector);
+ if (prototype)
+ return prototype;
+
+ /* Search prototypes of inherited protocols independent of mark. */
+ prototype
+ = instance_prototype_of_root_protocol (PROTOCOL_LIST (protocol),
+ selector, 1);
+ if (prototype)
+ return prototype;
+ }
+ }
+ return prototype;
+}
+
+
/* Create a declaration for field NAME of a given TYPE. */
static tree
@@ -1333,19 +1453,19 @@
type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
- protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
- type));
+ objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
+ type));
/* Declare type of selector-objects that represent an operation name. */
if (flag_next_runtime)
/* `struct objc_selector *' */
- selector_type
+ objc_selector_type
= build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier (TAG_SELECTOR)));
else
/* `const struct objc_selector *' */
- selector_type
+ objc_selector_type
= build_pointer_type
(build_qualified_type (xref_tag (RECORD_TYPE,
get_identifier (TAG_SELECTOR)),
@@ -1354,8 +1474,8 @@
/* Declare receiver type used for dispatching messages to 'super'. */
/* `struct objc_super *' */
- super_type = build_pointer_type (xref_tag (RECORD_TYPE,
- get_identifier (TAG_SUPER)));
+ objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SUPER)));
if (flag_next_runtime)
{
@@ -1371,7 +1491,8 @@
type
= build_function_type (objc_object_type,
tree_cons (NULL_TREE, objc_object_type,
- tree_cons (NULL_TREE, selector_type,
+ tree_cons (NULL_TREE,
+ objc_selector_type,
NULL_TREE)));
umsg_decl = builtin_function (TAG_MSGSEND,
type, 0, NOT_BUILT_IN,
@@ -1390,8 +1511,9 @@
/* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
type
= build_function_type (objc_object_type,
- tree_cons (NULL_TREE, super_type,
- tree_cons (NULL_TREE, selector_type,
+ tree_cons (NULL_TREE, objc_super_type,
+ tree_cons (NULL_TREE,
+ objc_selector_type,
NULL_TREE)));
umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
type, 0, NOT_BUILT_IN,
@@ -1409,14 +1531,16 @@
= build_pointer_type
(build_function_type (objc_object_type,
tree_cons (NULL_TREE, objc_object_type,
- tree_cons (NULL_TREE, selector_type,
+ tree_cons (NULL_TREE,
+ objc_selector_type,
NULL_TREE))));
/* IMP objc_msg_lookup (id, SEL); */
type
= build_function_type (IMP_type,
tree_cons (NULL_TREE, objc_object_type,
- tree_cons (NULL_TREE, selector_type,
+ tree_cons (NULL_TREE,
+ objc_selector_type,
OBJC_VOID_AT_END)));
umsg_decl = builtin_function (TAG_MSGSEND,
type, 0, NOT_BUILT_IN,
@@ -1425,8 +1549,9 @@
/* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
type
= build_function_type (IMP_type,
- tree_cons (NULL_TREE, super_type,
- tree_cons (NULL_TREE, selector_type,
+ tree_cons (NULL_TREE, objc_super_type,
+ tree_cons (NULL_TREE,
+ objc_selector_type,
OBJC_VOID_AT_END)));
umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
type, 0, NOT_BUILT_IN,
@@ -1718,7 +1843,7 @@
/* SEL *refs; */
- field_decl = create_field_decl (build_pointer_type (selector_type),
+ field_decl = create_field_decl (build_pointer_type (objc_selector_type),
"refs");
chainon (field_decl_chain, field_decl);
@@ -1814,7 +1939,7 @@
else
initlist
= tree_cons (NULL_TREE,
- convert (build_pointer_type (selector_type),
+ convert (build_pointer_type (objc_selector_type),
build_unary_op (ADDR_EXPR,
UOBJC_SELECTOR_TABLE_decl, 1)),
initlist);
@@ -2277,7 +2402,7 @@
ident = get_identifier (buf);
- decl = build_decl (VAR_DECL, ident, selector_type);
+ decl = build_decl (VAR_DECL, ident, objc_selector_type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
@@ -2304,7 +2429,7 @@
temp = build_array_type (objc_selector_template, NULL_TREE);
}
else
- temp = build_array_type (selector_type, NULL_TREE);
+ temp = build_array_type (objc_selector_type, NULL_TREE);
UOBJC_SELECTOR_TABLE_decl
= build_decl (VAR_DECL,
@@ -2327,7 +2452,7 @@
static tree
build_selector (tree ident)
{
- return convert (selector_type, add_objc_string (ident, meth_var_names));
+ return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
}
static void
@@ -2377,7 +2502,7 @@
sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
/* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
- decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
+ decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
var_decl = name;
@@ -2482,7 +2607,7 @@
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
build_int_2 (index, 0)),
1);
- return convert (selector_type, expr);
+ return convert (objc_selector_type, expr);
}
static tree
@@ -3639,7 +3764,7 @@
TREE_STATIC_TEMPLATE (uprivate_record) = 1;
}
- instance_type
+ objc_instance_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE,
uprivate_record),
build1 (INDIRECT_REF, NULL_TREE,
@@ -3794,7 +3919,7 @@
= start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
/* SEL _cmd; */
- decl_specs = build_tree_list (NULL_TREE, selector_type);
+ decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
field_decl = get_identifier ("_cmd");
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
@@ -4269,7 +4394,7 @@
/* SEL sel_id; */
- decl_specs = build_tree_list (NULL_TREE, selector_type);
+ decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
field_decl = get_identifier ("sel_id");
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
@@ -4905,7 +5030,7 @@
_SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
/* SEL _cmd; */
- decl_specs = build_tree_list (NULL_TREE, selector_type);
+ decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
field_decl = get_identifier ("_cmd");
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
@@ -5668,14 +5793,14 @@
/* Receiver type. */
if (flag_next_runtime && superflag)
- arglist = build_tree_list (NULL_TREE, super_type);
+ arglist = build_tree_list (NULL_TREE, objc_super_type);
else if (context == METHOD_DEF)
arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
else
arglist = build_tree_list (NULL_TREE, objc_object_type);
/* Selector type - will eventually change to `int'. */
- chainon (arglist, build_tree_list (NULL_TREE, selector_type));
+ chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
/* No actual method prototype given -- assume that remaining arguments
are `...'. */
@@ -5921,7 +6046,7 @@
objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
{
tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
- tree selector, retval, is_class;
+ tree selector, retval, class_tree;
int self, super, have_cast;
/* Extract the receiver of the message, as well as its type
@@ -5943,14 +6068,14 @@
/* If the receiver is a class object, retrieve the corresponding
@interface, if one exists. */
- is_class = receiver_is_class_object (receiver, self, super);
+ class_tree = receiver_is_class_object (receiver, self, super);
/* Now determine the receiver type (if an explicit cast has not been
provided). */
if (!have_cast)
{
- if (is_class)
- rtype = lookup_interface (is_class);
+ if (class_tree)
+ rtype = lookup_interface (class_tree);
/* Handle `self' and `super'. */
else if (super)
{
@@ -5972,7 +6097,7 @@
if (!rtype || objc_is_id (rtype))
{
if (!rtype)
- rtype = xref_tag (RECORD_TYPE, is_class);
+ rtype = xref_tag (RECORD_TYPE, class_tree);
else if (IS_ID (rtype))
{
rprotos = TYPE_PROTOCOL_LIST (rtype);
@@ -5980,18 +6105,32 @@
}
else
{
- is_class = objc_class_name;
- OBJC_SET_TYPE_NAME (rtype, is_class);
+ rprotos = TYPE_PROTOCOL_LIST (rtype);
+ class_tree = objc_class_name;
+ OBJC_SET_TYPE_NAME (rtype, class_tree);
+
+ if (rprotos)
+ rtype = NULL_TREE;
}
if (rprotos)
- method_prototype
- = lookup_method_in_protocol_list (rprotos, sel_name,
- is_class != NULL_TREE);
+ {
+ method_prototype
+ = lookup_method_in_protocol_list (rprotos, sel_name,
+ class_tree != NULL_TREE);
+
+ if (!method_prototype && class_tree != NULL_TREE)
+ method_prototype
+ = instance_prototype_of_root_protocol(rprotos,
+ sel_name, 0);
+ }
+
if (!method_prototype && !rprotos)
- method_prototype
- = lookup_method_in_hash_lists (sel_name,
- is_class != NULL_TREE);
+ {
+ method_prototype
+ = lookup_method_in_hash_lists (sel_name,
+ class_tree != NULL_TREE);
+ }
}
else
{
@@ -6023,7 +6162,7 @@
in the published @interface for the class (and its
superclasses). */
method_prototype
- = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
+ = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
/* If the method was not found in the @interface, it may still
exist locally as part of the @implementation. */
@@ -6032,7 +6171,7 @@
== OBJC_TYPE_NAME (rtype))
method_prototype
= lookup_method
- ((is_class
+ ((class_tree
? CLASS_CLS_METHODS (objc_implementation_context)
: CLASS_NST_METHODS (objc_implementation_context)),
sel_name);
@@ -6042,7 +6181,7 @@
if (!method_prototype && rprotos)
method_prototype
= lookup_method_in_protocol_list (rprotos, sel_name,
- is_class != NULL_TREE);
+ class_tree != NULL_TREE);
}
else
{
@@ -6059,11 +6198,11 @@
if (rtype)
warning ("`%s' may not respond to `%c%s'",
IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
- (is_class ? '+' : '-'),
+ (class_tree ? '+' : '-'),
IDENTIFIER_POINTER (sel_name));
if (rprotos)
warning ("`%c%s' not implemented by protocol(s)",
- (is_class ? '+' : '-'),
+ (class_tree ? '+' : '-'),
IDENTIFIER_POINTER (sel_name));
if (!warn_missing_methods)
{
@@ -6110,7 +6249,7 @@
(!flag_next_runtime || flag_nil_receivers
? umsg_decl
: umsg_nonnil_decl));
- tree rcv_p = (super_flag ? super_type : objc_object_type);
+ tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
/* If a prototype for the method to be called exists, then cast
the sender's return type and arguments to match that of the method.
@@ -6232,9 +6371,9 @@
expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
- /* ??? Ideally we'd build the reference with protocol_type directly,
+ /* ??? Ideally we'd build the reference with objc_protocol_type directly,
if we have it, rather than converting it here. */
- expr = convert (protocol_type, expr);
+ expr = convert (objc_protocol_type, expr);
/* The @protocol() expression is being compiled into a pointer to a
statically allocated instance of the Protocol class. To become
@@ -6252,7 +6391,7 @@
if (! flag_next_runtime)
{
/* This type is a struct containing the fields of a Protocol
- object. (Cfr. protocol_type instead is the type of a pointer
+ object. (Cfr. objc_protocol_type instead is the type of a pointer
to such a struct). */
tree protocol_struct_type = xref_tag
(RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
@@ -6365,7 +6504,7 @@
paradigm. */
warning ("instance variable `%s' accessed in class method",
IDENTIFIER_POINTER (id));
- TREE_TYPE (self_decl) = instance_type; /* cast */
+ TREE_TYPE (self_decl) = objc_instance_type; /* cast */
}
return build_component_ref (build_indirect_ref (self_decl, "->"), id);
@@ -7103,8 +7242,14 @@
add_class (class);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
- = lookup_and_install_protocols (protocol_list);
+ {
+ CLASS_PROTOCOL_LIST (class)
+ = lookup_and_install_protocols (protocol_list);
+
+ if (!CLASS_SUPER_NAME (class))
+ mark_protocols_declared_by_root_class (CLASS_PROTOCOL_LIST (class),
+ 0);
+ }
}
else if (code == CATEGORY_INTERFACE_TYPE)
@@ -7125,8 +7270,14 @@
add_category (class_category_is_assoc_with, class);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
- = lookup_and_install_protocols (protocol_list);
+ {
+ CLASS_PROTOCOL_LIST (class)
+ = lookup_and_install_protocols (protocol_list);
+
+ if (!CLASS_SUPER_NAME (class_category_is_assoc_with))
+ mark_protocols_declared_by_root_class (CLASS_PROTOCOL_LIST (class),
+ 0);
+ }
}
else if (code == CATEGORY_IMPLEMENTATION_TYPE)
@@ -7785,7 +7936,7 @@
build1 (INDIRECT_REF, NULL_TREE, self_id)),
unused_list));
- decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
+ decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
push_parm_decl (build_tree_list
(build_tree_list (decl_specs,
build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.16.4.11
diff -u -r1.16.4.11 objc-act.h
--- gcc/objc/objc-act.h 26 Jun 2004 04:01:39 -0000 1.16.4.11
+++ gcc/objc/objc-act.h 30 Jun 2004 07:29:37 -0000
@@ -36,6 +36,14 @@
#define CLASS_BINFO_ELTS 6
#define PROTOCOL_BINFO_ELTS 2
+/*
+ Objective-C usage for TREE_LANG_FLAG_?:
+
+ 0: PROTOCOL_DECLARED_BY_ROOT - (valid for PROTOCOL_INTERFACE_TYPE)
+ Marks protocol declarations that are declared by root classes
+ so that instance methods are also checked for Class references.
+*/
+
/* KEYWORD_DECL */
#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name)
#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments)
@@ -66,6 +74,7 @@
#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
+#define PROTOCOL_DECLARED_BY_ROOT(CLASS) TREE_LANG_FLAG_0 (CLASS)
/* We need to distinguish TYPE_PROTOCOL_LISTs from TYPE_CONTEXTs, both of which
are stored in the same accessor slot. */
@@ -265,12 +274,12 @@
#define objc_get_meta_class_decl \
objc_global_trees[OCTI_GET_MCLASS_DECL]
-#define super_type objc_global_trees[OCTI_SUPER_TYPE]
-#define selector_type objc_global_trees[OCTI_SEL_TYPE]
+#define objc_super_type objc_global_trees[OCTI_SUPER_TYPE]
+#define objc_selector_type objc_global_trees[OCTI_SEL_TYPE]
#define objc_object_type objc_global_trees[OCTI_ID_TYPE]
#define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
-#define instance_type objc_global_trees[OCTI_NST_TYPE]
-#define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
+#define objc_instance_type objc_global_trees[OCTI_NST_TYPE]
+#define objc_protocol_type objc_global_trees[OCTI_PROTO_TYPE]
/* Type checking macros. */
Index: gcc/objc/objc-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-tree.def,v
retrieving revision 1.7.8.1
diff -u -r1.7.8.1 objc-tree.def
--- gcc/objc/objc-tree.def 23 Jul 2003 19:05:54 -0000 1.7.8.1
+++ gcc/objc/objc-tree.def 30 Jun 2004 07:29:37 -0000
@@ -37,3 +37,9 @@
/* Objective-C expressions. */
DEFTREECODE (MESSAGE_SEND_EXPR, "message_send_expr", 'e', 3)
DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", 'e', 1)
+
+/*
+Local variables:
+mode:c
+End:
+*/
Attachment:
objc.patch.gz
Description: application/gunzip
/* Check Class <protocol> types */
/* Author: David Ayers <d.ayers@inode.at> */
/* { dg-do compile } */
#include <objc/objc.h>
#include <objc/objc-api.h>
@protocol MyProto1
+(void)doItClass1;
-(void)doItInstance1;
@end
@protocol MyProto2
+(void)doItClass2;
-(void)doItInstance2;
@end
@interface MyClass1 <MyProto1>
{
Class isa;
}
@end
@implementation MyClass1
+(void)doItClass1{}
-(void)doItInstance1{}
@end
@interface MyClass2 : MyClass1 <MyProto2>
@end
@implementation MyClass2
+(void)doItClass2{}
-(void)doItInstance2{}
@end
/*----------------------------------------*/
Class cls = 0;
Class <MyProto1> clsP1 = 0;
Class <MyProto2> clsP2 = 0;
void
testSimple(void)
{
[cls doItClass1];
[cls doItInstance1]; /* Do not warn as root Class declares this. */
[cls doItClass2];
[cls doItInstance2]; /* { dg-warning "may not respond" } */
[clsP1 doItClass1];
[clsP1 doItInstance1]; /* Do not warn as root Class declares this. */
[clsP1 doItClass2]; /* { dg-warning "not implemented by protocol" } */
[clsP1 doItInstance2]; /* { dg-warning "not implemented by protocol" } */
[clsP2 doItClass1]; /* { dg-warning "not implemented by protocol" } */
[clsP2 doItInstance1]; /* { dg-warning "not implemented by protocol" } */
[clsP2 doItClass2];
[clsP2 doItInstance2]; /* { dg-warning "not implemented by protocol" } */
[MyClass1 doItClass1];
[MyClass1 doItInstance1];
[MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */
[MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */
[MyClass2 doItClass1];
[MyClass2 doItInstance1];
[MyClass2 doItClass2];
[MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */
}
/*----------------------------------------*/
/* Protocols declared by categories */
@protocol MyProto3
+(void)doItClass3;
-(void)doItInstance3;
@end
@protocol MyProto4
+(void)doItClass4;
-(void)doItInstance4;
@end
@interface MyClass1 (Category1) <MyProto3>
@end
@interface MyClass2 (Category2) <MyProto4>
@end
void
testCategory(void)
{
[cls doItClass3];
[cls doItInstance3]; /* Do not warn as root Class declares this. */
[cls doItClass4];
[cls doItInstance4]; /* { dg-warning "may not respond" } */
[MyClass1 doItClass3];
[MyClass1 doItInstance3];
[MyClass1 doItClass4]; /* { dg-warning "may not respond" } */
[MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */
[MyClass2 doItClass3];
[MyClass2 doItInstance3];
[MyClass2 doItClass4];
[MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */
}
/*----------------------------------------*/
/* Inherited protocols declared by categories */
@protocol MyProto5 <MyProto1>
+(void)doItClass5;
-(void)doItInstance5;
@end
@protocol MyProto6 <MyProto2>
+(void)doItClass6;
-(void)doItInstance6;
@end
@interface MyClass1 (Category3) <MyProto5>
@end
@interface MyClass2 (Category4) <MyProto6>
@end
Class <MyProto5> clsP5 = 0;
Class <MyProto6> clsP6 = 0;
void
testCategoryInherited(void)
{
[cls doItClass5];
[cls doItInstance5]; /* Do not warn as root Class declares this. */
[cls doItClass6];
[cls doItInstance6]; /* { dg-warning "may not respond" } */
[clsP5 doItClass1];
[clsP5 doItInstance1];
[clsP5 doItClass2]; /* { dg-warning "not implemented by protocol" } */
[clsP5 doItInstance2]; /* { dg-warning "not implemented by protocol" } */
[clsP6 doItClass1]; /* { dg-warning "not implemented by protocol" } */
[clsP6 doItInstance1]; /* { dg-warning "not implemented by protocol" } */
[clsP6 doItClass2];
[clsP6 doItInstance2]; /* { dg-warning "not implemented by protocol" } */
[MyClass1 doItClass5];
[MyClass1 doItInstance5]; /* Do not warn as root Class declares this. */
[MyClass1 doItClass6]; /* { dg-warning "may not respond" } */
[MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */
[MyClass2 doItClass5];
[MyClass2 doItInstance5]; /* Do not warn as root Class declares this. */
[MyClass2 doItClass6];
[MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */
}
/*----------------------------------------*/
/* Forward declared root protocols */
@protocol FwProto;
@interface MyClass1 (Forward) <FwProto>
@end
Class <FwProto> clsP7 = 0;
void
testForwardeDeclared1(void)
{
[cls doItClass7]; /* { dg-warning "may not respond" } */
[cls doItInstance7]; /* { dg-warning "may not respond" } */
[clsP7 doItClass7]; /* { dg-warning "not implemented by protocol" } */
[clsP7 doItInstance7]; /* { dg-warning "not implemented by protocol" } */
[MyClass1 doItClass7]; /* { dg-warning "may not respond" } */
[MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */
[MyClass2 doItClass7]; /* { dg-warning "may not respond" } */
[MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */
}
@protocol FwProto
+(void)doItClass7;
-(void)doItInstance7;
@end
void
testForwardeDeclared2(void)
{
[cls doItClass7];
[cls doItInstance7]; /* Do not warn as root Class declares this. */
[clsP7 doItClass7];
[clsP7 doItInstance7]; /* Do not warn as root Class declares this. */
[MyClass1 doItClass7];
[MyClass1 doItInstance7];
[MyClass2 doItClass7];
[MyClass2 doItInstance7];
}
/*----------------------------------------*/
/* Inherited non root protocols */
@protocol MyProto8
+(void)doItClass8;
-(void)doItInstance8;
@end
@protocol MyProto9 <MyProto8>
+(void)doItClass9;
-(void)doItInstance9;
@end
@interface MyClass1 (InheritedNonRoot) <MyProto9>
@end
Class <MyProto8> clsP8 = 0;
Class <MyProto9> clsP9 = 0;
void
testInheritedNonRoot(void)
{
[cls doItClass8];
[cls doItInstance8]; /* Do not warn as root Class declares super. */
[cls doItClass9];
[cls doItInstance9]; /* Do not warn as root Class declares this. */
[clsP8 doItClass8];
[clsP8 doItInstance8]; /* { dg-warning "not implemented by protocol" } */
[clsP8 doItClass9]; /* { dg-warning "not implemented by protocol" } */
[clsP8 doItInstance9]; /* { dg-warning "not implemented by protocol" } */
[clsP9 doItClass8];
[clsP9 doItInstance8];
[clsP9 doItClass9];
[clsP9 doItInstance9];
[MyClass1 doItClass8];
[MyClass1 doItInstance8]; /* Do not warn as root Class declares this. */
[MyClass1 doItClass9];
[MyClass1 doItInstance9];
[MyClass2 doItClass8];
[MyClass2 doItInstance8]; /* Do not warn as root Class declares this. */
[MyClass2 doItClass9];
[MyClass2 doItInstance9];
}
int main ()
{
testSimple();
testCategory();
testCategoryInherited();
return(0);
}
/* { dg-warning "Messages without a matching" "" { target *-*-* } 47 } */
/* { dg-warning "will be assumed to return" "" { target *-*-* } 47 } */
/* { dg-warning "as arguments" "" { target *-*-* } 47 } */
Attachment:
class-protocol-1.m.gz
Description: application/gunzip
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |