discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC/objc] Support for 'Class <Protocol>' & frontend cleanups


From: David Ayers
Subject: [RFC/objc] Support for 'Class <Protocol>' & frontend cleanups
Date: Thu, 18 Sep 2003 01:14:52 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5b) Gecko/20030827

Hello Everyone,

I've been working on adding support for qualifying the ObjC 'Class' type with protocols just as one can qualify the ObjC 'id' with it. When qualifying with 'id' only the instance methods are handled, so we need this feature to allow correct handling (typing and casting) for class methods.

During this work I noticed a couple of issues that lead to the following proposals.

1. Merge 'get_object_reference()' with 'get_static_reference()'.
2. Remove the 'RID_ID'/'OBJECTNAME' keyword, replacing the corresponding
  typespec_nonreserved_nonattr: rule with 'TYPENAME' protocolrefs
3. Consistently prefix all ObjC '@' tokens with 'AT_'
4. Find/implement a consistent naming convention in objc-act.[hc]
  for the defines referencing the entries in the global table.
5. Improve handling of 'error_mark'.
6. Introduce 'same_type_p' instead of using pointer equality.
7. Reformatting (esp. objc-imp)
8. Potentially deprecate the '<SomeProtocol>' 'id <SomeProtocol>'
  equivalence in typespec_nonreserved_nonattr: as it would now be
  ambiguous from a user point of view.

The reasoning for interested readers:

It seems that main (only?) reason for 'id' being a keyword in ObjC is to allow the parser to define the 'OBJECTNAME' token for the following rule:

typespec_nonreserved_nonattr:
        TYPENAME
              { /* For a typedef name, record the meaning, not the
                   name. In case of `foo foo, bar;'.  */
                $$ = lookup_name ($1); }
@@ifobjc
      | CLASSNAME protocolrefs
              { $$ = get_static_reference ($1, $2); }
      | OBJECTNAME protocolrefs
              { $$ = get_object_reference ($2); }

/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
 - nisse@lysator.liu.se */
      | non_empty_protocolrefs
              { $$ = get_object_reference ($1); }
@@end_ifobjc
      | typeof '(' expr ')'
              { skip_evaluation--; $$ = TREE_TYPE ($3); }
      | typeof '(' typename ')'
              { skip_evaluation--; $$ = groktypename ($3); }
      ;

There are no other places where 'OBJECTNAME' is used but 'TYPENAME' isn't. Also 'OBJECTNAME' has been added where 'TYPENAME' already exists, with one (other) exception:

receiver:
        expr
      | CLASSNAME
              {
                $$ = get_class_reference ($1);
              }
      | TYPENAME
              {
                $$ = get_class_reference ($1);
              }
      ;

The use of 'TYPENAME' supports class names aliases (and may be part of future ObjC++ support ?). Anyway, the 'get_class_reference()' asserts that the identifier is in fact an ObjC class, so even if some wrote '[id message]' we would catch it.

I think this change would do a lot to remove some of the complexity of the parser. The only thing that could possibly foil this approach is ObjC++ and strange interaction with template declarations. But I know too little about ObjC++ to decide whether this really can be an issue or not. OTOH, I believe the ObjC++ holdup was due too waiting on the new parser for g++ so I could guess you're not intending to add ObjC++ parsing here anyway. But looking at some of changes like:
#define OBJC_TYPE_NAME(type) TYPE_NAME(type)
you must be preparing this parser for ObjC++...

I've attached two patches that apply against the latest merge-point (objc-improvements-candidate-20030915) because the anonymous cvs didn't update the C90 changes in time for me to adapt the patches. Both patches also include spurious whitespace hunks where I attempted to convert stuff I touched during debugging to standard formatting. I know that for the formal RFA I'll have to post separate patches.

Both patches implement 'Class <Protocol>' but the first one doesn't address issue 2. (removing 'id' as a keyword) but follows the scheme of the keyword 'id' by making 'Class' another ObjC keyword. The 'RID_CLASS' keyword, and 'CLASS' token are already in use so, I decided on the name '(RID_)OBJC_CLASS' and also renamed 'RID_ID' and 'OBJECTNAME' to '(RID_)OBJC_ID' respectively. The second patch removes the 'id' keyword an implements the rule with TYPENAME protocolrefs and having get_protocol_reference assert the validity of the type.

While renaming tokens, it also seemed reasonable to prefix the remaining ObjC '@' tokens with 'AT_' making the parser much easier to read.

I renamed 'OBJECTNAME' to 'OBJC_ID' and introduced 'OBJC_CLASS' in the parser in this patch. I also renamed some of defines and enum values referencing the trees to the 'Class' and 'id' types to gain consistency:

id_type    => objc_id_type     (objc_class_type already existed,
                              in fact, I think prefixing:
                              instance_type, selector_type,
                              super_type, protocol_type with objc_
                              would also be a good idea.)

OCTI_ID_ID => OCTI_TYPE_ID_ID   (it refers to a typedef rather than
                               a structure as all the other _ID trees)
objc_id_id => objc_type_id_id
new:          OCTI_TYPE_CLS_ID  (refers to TYPE_NAME "Class")
new:          objc_type_cls_id

I also renamed 'get_object_reference' to 'get_protocol_reference'.

Please let me know whether these changes are acceptable and whether or not we can/should remove 'OBJECTNAME' ('OBJC_ID'/'OBJC_CLASS') from the parser. I could start sending breakdowns of one of these the all-in-one patch as of Sunday. I intend to break out the root instance method search somehow, but wanted to wait on the infrastructure supplied by Alex's patch is available. So it's currently all hacked into the general function. I don't think speed is an issue as this is a new feature and when it's used, I believe the casts will not need to rely on the root instance method search, but it should be there for correctness.

I've also included a test case that still needs to be deja-gnu-ified, which I'll do with the RFA, once the other points have been decided upon and the dust has settled.

I'll be back latest on Sunday to reply to any questions and suggestions.

Cheers,
David

PS: The first patch exposes an invalid test case in method-6.m that tries to send 'Class' a message, but instead of 'Class' not being an ObjC class name or alias, it has become a parsing error just as if you tried to send 'id' a message. (But I believe we're updating that test case with Alex's patch anyway.) The second one makes id-1.m invalid. As soon as you typedef id to something else and include <objc/objc.h> you'll receive:
error: previous declaration of 'id'
so that test case will just have to be adapted accordingly.
Index: gcc/c-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.189.2.5
diff -u -r1.189.2.5 c-common.h
--- gcc/c-common.h      13 Sep 2003 02:18:52 -0000      1.189.2.5
+++ gcc/c-common.h      17 Sep 2003 13:18:25 -0000
@@ -95,7 +95,10 @@
   RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
 
   /* Objective-C */
-  RID_ID,          RID_AT_ENCODE,    RID_AT_END,
+  RID_OBJC_ID,     RID_OBJC_CLASS, /* These need not be reserved words.  
+                                     Yet we treat them as such to identify
+                                     protocol qualified declarations.  */
+  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: /cvsroot/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.170.2.4
diff -u -r1.170.2.4 c-parse.in
--- gcc/c-parse.in      13 Sep 2003 02:18:54 -0000      1.170.2.4
+++ gcc/c-parse.in      17 Sep 2003 13:18:30 -0000
@@ -173,8 +173,8 @@
 
 /* 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 OBJC_ID 
OBJC_CLASS AT_CLASS AT_ALIAS
 %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
 %token OBJC_STRING
 
@@ -245,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_ID OBJC_CLASS OBJC_STRING
 
 %type <ttype> objc_try_stmt superclass
 %type <itype> objc_try_catch_stmt objc_finally_block
@@ -457,7 +457,8 @@
        IDENTIFIER
        | TYPENAME
 @@ifobjc
-       | OBJECTNAME
+       | OBJC_ID
+       | OBJC_CLASS
        | CLASSNAME
 @@end_ifobjc
        ;
@@ -1356,13 +1357,15 @@
 @@ifobjc
        | CLASSNAME protocolrefs
                { $$ = get_static_reference ($1, $2); }
-       | OBJECTNAME protocolrefs
-               { $$ = get_object_reference ($2); }
+       | OBJC_ID protocolrefs
+               { $$ = get_protocol_reference ($2, 1); }
+       | OBJC_CLASS protocolrefs
+               { $$ = get_protocol_reference ($2, 0); }
 
 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
    - nisse@lysator.liu.se */
         | non_empty_protocolrefs
-                { $$ = get_object_reference ($1); }
+                { $$ = get_protocol_reference ($1, 1); }
 @@end_ifobjc
        | typeof '(' expr ')'
                { skip_evaluation--; $$ = TREE_TYPE ($3); }
@@ -1630,7 +1633,8 @@
                { $$ = make_pointer_declarator ($2, $3); }
        | TYPENAME
 @@ifobjc
-       | OBJECTNAME
+       | OBJC_ID
+       | OBJC_CLASS
 @@end_ifobjc
        ;
 
@@ -1653,7 +1657,8 @@
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | TYPENAME
 @@ifobjc
-       | OBJECTNAME
+       | OBJC_ID
+       | OBJC_CLASS
 @@end_ifobjc
        ;
 
@@ -1805,7 +1810,7 @@
                    pedwarn ("extra semicolon in struct or union specified"); }
 @@ifobjc
        /* foo(sizeof(struct{ @defs(ClassName)})); */
-       | DEFS '(' CLASSNAME ')'
+       | AT_DEFS '(' CLASSNAME ')'
                { $$ = nreverse (get_class_ivars_from_name ($3)); }
 @@end_ifobjc
        ;
@@ -2694,7 +2699,7 @@
        | aliasdecl
        | protocoldef
        | methoddef
-       | END
+       | AT_END
                {
                  if (objc_implementation_context)
                     {
@@ -2716,14 +2721,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);
                }
@@ -2740,7 +2745,7 @@
        ;
 
 classdef:
-         INTERFACE identifier superclass protocolrefs
+         AT_INTERFACE identifier superclass protocolrefs
                {
                  objc_interface_context = objc_ivar_context
                    = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
@@ -2750,13 +2755,13 @@
                {
                   continue_class (objc_interface_context);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
 
-       | IMPLEMENTATION identifier superclass
+       | AT_IMPLEMENTATION identifier superclass
                {
                  objc_implementation_context = objc_ivar_context
                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, 
NULL_TREE);
@@ -2768,19 +2773,19 @@
                    = continue_class (objc_implementation_context);
                }
 
-       | INTERFACE identifier '(' identifier ')' protocolrefs
+       | AT_INTERFACE identifier '(' identifier ')' protocolrefs
                {
                  objc_interface_context
                    = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
                   continue_class (objc_interface_context);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
 
-       | IMPLEMENTATION identifier '(' identifier ')'
+       | AT_IMPLEMENTATION identifier '(' identifier ')'
                {
                  objc_implementation_context
                    = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, 
NULL_TREE);
@@ -2790,13 +2795,13 @@
        ;
 
 protocoldef:
-         PROTOCOL identifier protocolrefs
+         AT_PROTOCOL identifier protocolrefs
                {
                  objc_pq_context = 1;
                  objc_interface_context
                    = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  objc_pq_context = 0;
                  finish_protocol(objc_interface_context);
@@ -2805,7 +2810,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);
                }
@@ -2835,9 +2840,9 @@
         ;
 
 visibility_spec:
-         PRIVATE { objc_public_flag = 2; }
-       | PROTECTED { objc_public_flag = 0; }
-       | PUBLIC { objc_public_flag = 1; }
+         AT_PRIVATE { objc_public_flag = 2; }
+       | AT_PROTECTED { objc_public_flag = 0; }
+       | AT_PUBLIC { objc_public_flag = 1; }
        ;
 
 ivar_decls:
@@ -3080,7 +3085,8 @@
          IDENTIFIER
        | TYPENAME
        | CLASSNAME
-       | OBJECTNAME
+       | OBJC_ID
+       | OBJC_CLASS
        | reservedwords
        ;
 
@@ -3192,14 +3198,14 @@
        ;
 
 objcselectorexpr:
-         SELECTOR '(' selectorarg ')'
+         AT_SELECTOR '(' selectorarg ')'
                {
                  $$ = $3;
                }
        ;
 
 objcprotocolexpr:
-         PROTOCOL '(' identifier ')'
+         AT_PROTOCOL '(' identifier ')'
                {
                  $$ = $3;
                }
@@ -3208,7 +3214,7 @@
 /* extension to support C-structures in the archiver */
 
 objcencodeexpr:
-         ENCODE '(' typename ')'
+         AT_ENCODE '(' typename ')'
                {
                  $$ = groktypename ($3);
                }
@@ -3317,7 +3323,8 @@
   { "volatile",                RID_VOLATILE,   0 },
   { "while",           RID_WHILE,      0 },
 @@ifobjc
-  { "id",              RID_ID,                 D_OBJC },
+  { "id",              RID_OBJC_ID,    D_OBJC },
+  { "Class",           RID_OBJC_CLASS, D_OBJC },
 
   /* These objc keywords are recognized only immediately after
      an '@'.  */
@@ -3462,24 +3469,25 @@
   /* 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_OBJC_ID */            OBJC_ID,
+  /* RID_OBJC_CLASS */         OBJC_CLASS,
+  /* 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
@@ -3552,9 +3560,9 @@
       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)
+      /* Turn non-typedefed refs to "id" or "Class" into plain identifiers;
+        this allows constructs like "void foo(id id);" to work.  */
+      if (rid_code == RID_OBJC_ID || rid_code == RID_OBJC_CLASS)
       {
        decl = lookup_name (yylval.ttype);
        if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
@@ -3723,7 +3731,8 @@
     {
     case IDENTIFIER:
     case TYPENAME:
-    case OBJECTNAME:
+    case OBJC_ID:
+    case OBJC_CLASS:
     case TYPESPEC:
     case TYPE_QUAL:
     case SCSPEC:
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.179.2.12
diff -u -r1.179.2.12 objc-act.c
--- gcc/objc/objc-act.c 13 Sep 2003 02:19:46 -0000      1.179.2.12
+++ gcc/objc/objc-act.c 17 Sep 2003 13:28:15 -0000
@@ -313,6 +313,7 @@
 /* Reserved tag definitions.  */
 
 #define TYPE_ID                        "id"
+#define TYPE_CLASS             "Class"
 #define TAG_OBJECT             "objc_object"
 #define TAG_CLASS              "objc_class"
 #define TAG_SUPER              "objc_super"
@@ -579,33 +580,33 @@
    tree sel_name;
    int class_meth;
 {
-   tree rproto, p;
-   tree fnd = 0;
+  tree rproto, p;
+  tree fnd = 0;
 
-   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
-     {
-        p = TREE_VALUE (rproto);
+  for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+    {
+      p = TREE_VALUE (rproto);
 
-       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
-         {
-           if ((fnd = lookup_method (class_meth
-                                     ? 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);
-         }
-       else
-          {
-           ; /* An identifier...if we could not find a protocol.  */
-          }
+      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+       {
+         if ((fnd = lookup_method (class_meth
+                                   ? 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);
+       }
+      else
+       {
+         ; /* An identifier...if we could not find a protocol.  */
+       }
 
-       if (fnd)
-         return fnd;
-     }
+      if (fnd)
+       return fnd;
+    }
 
-   return 0;
+  return 0;
 }
 
 static tree
@@ -1008,23 +1009,43 @@
   return type;
 }
 
+/* 
+   Ayers: Maybe we should merge get_static_reference
+   into this function and have the second parameter
+   be a 3 value enum of 'typed object', 'id' and 'Class'.  
+*/
 tree
-get_object_reference (protocols)
+get_protocol_reference (protocols, is_id)
      tree protocols;
+     int  is_id;
 {
-  tree type_decl = lookup_name (objc_id_id);
+  tree type_decl;
   tree type;
+  tree type_ref;
+
+  if (is_id == 1)
+    {
+      type_decl = lookup_name (objc_type_id_id);
+      type_ref =  objc_id_type;
+    }
+  else
+    {
+      type_decl = lookup_name (objc_type_cls_id);
+      type_ref =  objc_class_type;
+    }
 
   if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
     {
       type = TREE_TYPE (type_decl);
-      if (TYPE_MAIN_VARIANT (type) != id_type)
-       warning ("unexpected type for `id' (%s)",
+      if (TYPE_MAIN_VARIANT (type) != type_ref)
+       warning ("unexpected type for `%s' (%s)",
+                (is_id ? TYPE_ID : TYPE_CLASS),
                 gen_declaration (type, errbuf));
     }
   else
     {
-      error ("undefined type `id', please import <objc/objc.h>");
+      error ("undefined type `%s', please import <objc/objc.h>",
+            (is_id ? TYPE_ID : TYPE_CLASS));
       return error_mark_node;
     }
 
@@ -1179,9 +1200,11 @@
 
   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
 
-  id_type = build_pointer_type (objc_object_reference);
+  objc_id_type = build_pointer_type (objc_object_reference);
+
+  objc_type_id_id = get_identifier (TYPE_ID);
+  objc_type_cls_id = get_identifier (TYPE_CLASS);
 
-  objc_id_id = get_identifier (TYPE_ID);
   objc_class_id = get_identifier (TAG_CLASS);
 
   objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
@@ -1208,8 +1231,8 @@
   /* id objc_msgSend (id, SEL, ...); */
 
   temp_type
-    = build_function_type (id_type,
-                          tree_cons (NULL_TREE, id_type,
+    = build_function_type (objc_id_type,
+                          tree_cons (NULL_TREE, objc_id_type,
                                      tree_cons (NULL_TREE, selector_type,
                                                 NULL_TREE)));
 
@@ -1235,7 +1258,7 @@
   /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
 
   temp_type
-    = build_function_type (id_type,
+    = build_function_type (objc_id_type,
                           tree_cons (NULL_TREE, super_type,
                                      tree_cons (NULL_TREE, selector_type,
                                                 NULL_TREE)));
@@ -1271,8 +1294,8 @@
                    get_identifier (TAG_RETURN_STRUCT));
 
       tree stret_temp_type
-       = build_function_type (id_type,
-                              tree_cons (NULL_TREE, id_type,
+       = build_function_type (objc_id_type,
+                              tree_cons (NULL_TREE, objc_id_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
 
@@ -1280,7 +1303,7 @@
        builtin_function (TAG_MSGSEND_STRET, stret_temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
       stret_temp_type
        = build_function_type (objc_return_struct_type,
-                              tree_cons (NULL_TREE, id_type,
+                              tree_cons (NULL_TREE, objc_id_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
 
@@ -1288,7 +1311,7 @@
        builtin_function (TAG_MSGSEND_NONNIL_STRET, stret_temp_type, 0, 
NOT_BUILT_IN, NULL, NULL_TREE);
 
       stret_temp_type
-       = build_function_type (id_type,
+       = build_function_type (objc_id_type,
                               tree_cons (NULL_TREE, super_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
@@ -1300,7 +1323,7 @@
 
   /* id objc_getClass (const char *); */
 
-  temp_type = build_function_type (id_type,
+  temp_type = build_function_type (objc_id_type,
                        tree_cons (NULL_TREE,
                                   const_string_type_node,
                                   OBJC_VOID_AT_END));
@@ -2641,8 +2664,8 @@
   if (!type || TREE_CODE (type) != POINTER_TYPE)
     return 0;
   /* NB: This function may be called before the ObjC front-end
-     has been initialized, in which case ID_TYPE will be NULL. */
-  if (id_type && type && TYPE_P (type)
+     has been initialized, in which case OBJC_ID_TYPE will be NULL. */
+  if (objc_id_type && type && TYPE_P (type)
       && (IS_ID (type)
          || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
     return type;
@@ -2983,7 +3006,7 @@
        objc_stack_exception_data);
   objc_rethrow_exception = tree_cons (NULL_TREE,
        objc_declare_variable (RID_VOLATILE, get_identifier 
(UTAG_RETHROWEXC_VAR), 
-               id_type,
+               objc_id_type,
                build_int_2 (0, 0)),
        objc_rethrow_exception);
 
@@ -3020,7 +3043,7 @@
     objc_enter_block ();
     objc_caught_exception = tree_cons (NULL_TREE, 
        objc_declare_variable (RID_REGISTER, get_identifier 
(UTAG_CAUGHTEXC_VAR), 
-               id_type, objc_build_extract_expr ()),
+               objc_id_type, objc_build_extract_expr ()),
        objc_caught_exception);
     objc_build_try_enter_fragment ();  
     val_stack_push (&catch_count_stack, 1);
@@ -3069,7 +3092,7 @@
     var_name = TREE_OPERAND (var_name, 0);
   if (TREE_CODE (var_type) == TYPE_DECL || TREE_CODE (var_type) == 
POINTER_TYPE)
     var_type = TREE_TYPE (var_type);
-  catch_id = (var_type == TREE_TYPE (id_type));
+  catch_id = (var_type == TREE_TYPE (objc_id_type));
         
   if (!flag_objc_exceptions)
     fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception 
syntax");
@@ -3082,7 +3105,7 @@
   for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch); 
        prev_catch = TREE_CHAIN (prev_catch))   
     {
-      if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
+      if (TREE_VALUE (prev_catch) == TREE_TYPE (objc_id_type))
        {
          warning ("Exception already handled by preceding `@catch(id)'");
          break;
@@ -3295,7 +3318,7 @@
   objc_enter_block ();
   objc_eval_once = tree_cons (NULL_TREE,
        objc_declare_variable (RID_AUTO, get_identifier (UTAG_EVALONCE_VAR), 
-               id_type,
+               objc_id_type,
                sync_expr),
        objc_eval_once);
   objc_build_try_prologue ();
@@ -3394,7 +3417,7 @@
        = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, 
NULL_TREE);
 
   /* id objc_exception_extract(struct _objc_exception_data *); */
-  temp_type = build_function_type (id_type,
+  temp_type = build_function_type (objc_id_type,
                tree_cons (NULL_TREE, 
                    build_pointer_type (objc_exception_data_template), 
                        OBJC_VOID_AT_END));
@@ -3414,7 +3437,7 @@
   /* void objc_sync_enter(id); */
   /* void objc_sync_exit(id); */
   temp_type = build_function_type (void_type_node,
-               tree_cons (NULL_TREE, id_type,
+               tree_cons (NULL_TREE, objc_id_type,
                        OBJC_VOID_AT_END));
   objc_exception_throw_decl
        = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
@@ -3426,8 +3449,8 @@
        = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, 
NULL_TREE);
   /* int objc_exception_match(id, id); */
   temp_type = build_function_type (integer_type_node,
-               tree_cons (NULL_TREE, id_type, 
-                   tree_cons (NULL_TREE, id_type,
+               tree_cons (NULL_TREE, objc_id_type, 
+                   tree_cons (NULL_TREE, objc_id_type,
                        OBJC_VOID_AT_END)));
   objc_exception_match_decl
        = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
@@ -5562,7 +5585,7 @@
   else if (context == METHOD_DEF)
     arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
   else
-    arglist = build_tree_list (NULL_TREE, id_type);
+    arglist = build_tree_list (NULL_TREE, objc_id_type);
 
   /* Selector type - will eventually change to `int'.  */
   chainon (arglist, build_tree_list (NULL_TREE, selector_type));
@@ -5609,7 +5632,8 @@
 
       if (hsh->list)
         {
-         /* We have two or more methods with the same name but different 
types.  */
+         /* We have two or more methods with the same name 
+            but different types.  */
          attr loop;
          char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
 
@@ -5820,7 +5844,8 @@
                     IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
              return error_mark_node;
            }
-         rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+         rtype 
+           = lookup_interface (CLASS_SUPER_NAME (implementation_template));
        }
       else if (self)
        rtype = lookup_interface (CLASS_NAME (implementation_template));
@@ -5840,16 +5865,84 @@
          rtype = NULL_TREE;
        }
       else
-       is_class = TYPE_NAME (rtype) = get_identifier ("Class");
+       {
+         rprotos = TYPE_PROTOCOL_LIST (rtype);
+         is_class = TYPE_NAME (rtype) = get_identifier ("Class");
+
+         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, 
+                                             is_class != NULL_TREE);
+         if (!method_prototype && is_class != NULL_TREE)
+           {
+             /* Check if any root classes implement the protocol
+                in which case we also have to check the instance methods.  */
+             tree proto_ch;        /* protocol chain */
+             tree inter_ch;        /* interface chain */
+             tree categ_ch;        /* category chain */
+             tree proto_value;     /* protocol value */
+             tree proto_candidate; /* prototype candidate */
+
+             for (proto_ch = rprotos;
+                  proto_ch && method_prototype == NULL_TREE;
+                  proto_ch = TREE_CHAIN (proto_ch))
+               {
+                 proto_value = TREE_VALUE(proto_ch);
+
+                 if (TREE_CODE (proto_value) != PROTOCOL_INTERFACE_TYPE)
+                   continue;
+
+                 /* Find protocols that declare the method
+                    as an instance method.  */
+                 proto_candidate 
+                   = lookup_method (PROTOCOL_NST_METHODS (proto_value),
+                                    sel_name);
+                 /* Check inherited protocols.  */
+                 if (!proto_candidate)
+                   proto_candidate 
+                     = lookup_method_in_protocol_list 
+                     (PROTOCOL_LIST (proto_value), sel_name, 0);
+
+                 /* If we found one, check all root classes
+                    to see if any declare it.  */
+                 if (proto_candidate)
+                   for (inter_ch = interface_chain;
+                        inter_ch && method_prototype == NULL_TREE;
+                        inter_ch = TREE_CHAIN (inter_ch))
+                     {
+                       if (CLASS_SUPER_NAME (inter_ch))
+                         continue;
+                       
+                       if (!method_prototype
+                           && lookup_protocol_in_reflist
+                           (CLASS_PROTOCOL_LIST (inter_ch),
+                            proto_value))
+                         method_prototype = proto_candidate;
+
+                       /* We've already retrieved the prototype from
+                          the protocol, so there is no need to check
+                          the category before the interface declaration.  */
+                       for (categ_ch = CLASS_CATEGORY_LIST (inter_ch);
+                            categ_ch && !method_prototype;
+                            categ_ch = CLASS_CATEGORY_LIST (categ_ch))
+                              if (lookup_protocol_in_reflist
+                                  (CLASS_PROTOCOL_LIST (categ_ch),
+                                   proto_value))
+                                method_prototype = proto_candidate;
+                     }
+               }
+           }
+       }
       if (!method_prototype && !rprotos)
        method_prototype
          = (is_class
-            ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 
1)
+            ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name),
+                                1)
             : lookup_method_in_hash_lists (sel_name));
     }
   else
@@ -5970,7 +6063,7 @@
                 (!flag_next_runtime || flag_nil_receivers
                  ? umsg_decl
                  : umsg_nonnil_decl));
-  tree rcv_p = (super_flag ? super_type : id_type);
+  tree rcv_p = (super_flag ? super_type : objc_id_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.
@@ -5978,7 +6071,7 @@
   tree ret_type
     = (method_prototype
        ? groktypename (TREE_TYPE (method_prototype))
-       : id_type);
+       : objc_id_type);
   tree sender_cast
     = build_pointer_type
       (build_function_type 
@@ -6345,7 +6438,9 @@
 
   while (inter)
     {
-      tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS 
(inter);
+      tree chain = (is_class 
+                   ? CLASS_CLS_METHODS (inter) 
+                   : CLASS_NST_METHODS (inter));
       tree category = inter;
 
       /* First, look up the method in the class itself.  */
@@ -6355,7 +6450,9 @@
       /* Failing that, look for the method in each category of the class.  */
       while ((category = CLASS_CATEGORY_LIST (category)))
        {
-         chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS 
(category);
+         chain = (is_class 
+                  ? CLASS_CLS_METHODS (category) 
+                  : CLASS_NST_METHODS (category));
 
          /* Check directly in each category.  */
          if ((meth = lookup_method (chain, ident)))
@@ -6400,7 +6497,9 @@
   tree mth;
   hash hsh;
 
-  if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : 
CLASS_NST_METHODS (class), method)))
+  if (!(mth = lookup_method ((is_class 
+                             ? CLASS_CLS_METHODS (class) 
+                             : CLASS_NST_METHODS (class)), method)))
     {
       /* put method on list in reverse order */
       if (is_class)
@@ -6424,15 +6523,19 @@
           || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
          && !comp_proto_with_proto (method, mth))
        error ("duplicate declaration of method `%c%s'",
-               is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME 
(mth)));
+               (is_class ? '+' : '-'),
+              IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
     }
 
-  if (!(hsh = hash_lookup (is_class 
-                          ? cls_method_hash_list
-                          : nst_method_hash_list, METHOD_SEL_NAME (method))))
+  if (!(hsh 
+       = hash_lookup ((is_class 
+                       ? cls_method_hash_list
+                       : nst_method_hash_list), METHOD_SEL_NAME (method))))
     {
       /* Install on a global chain.  */
-      hash_enter (is_class ? cls_method_hash_list : nst_method_hash_list, 
method);
+      hash_enter ((is_class 
+                  ? cls_method_hash_list 
+                  : nst_method_hash_list), method);
     }
   else
     {
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.16.4.2
diff -u -r1.16.4.2 objc-act.h
--- gcc/objc/objc-act.h 27 Aug 2003 00:19:24 -0000      1.16.4.2
+++ gcc/objc/objc-act.h 17 Sep 2003 13:28:16 -0000
@@ -60,7 +60,7 @@
 tree get_class_ivars_from_name                 PARAMS ((tree));
 tree get_class_reference                       PARAMS ((tree));
 tree get_static_reference                      PARAMS ((tree, tree));
-tree get_object_reference                      PARAMS ((tree));
+tree get_protocol_reference                    PARAMS ((tree, int));
 tree build_message_expr                                PARAMS ((tree));
 tree finish_message_expr                       PARAMS ((tree, tree, tree));
 tree build_selector_expr                       PARAMS ((tree));
@@ -259,7 +259,8 @@
 
     OCTI_OBJ_ID,
     OCTI_CLS_ID,
-    OCTI_ID_ID,
+    OCTI_TYPE_ID_ID,
+    OCTI_TYPE_CLS_ID,
     OCTI_CNST_STR_ID,
     OCTI_CNST_STR_TYPE,
     OCTI_CNST_STR_GLOB_ID,
@@ -313,7 +314,7 @@
 
 #define super_type             objc_global_trees[OCTI_SUPER_TYPE]
 #define selector_type          objc_global_trees[OCTI_SEL_TYPE]
-#define id_type                        objc_global_trees[OCTI_ID_TYPE]
+#define objc_id_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]
@@ -321,7 +322,7 @@
 /* Type checking macros.  */
 
 #define IS_ID(TYPE) \
-  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
+  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (objc_id_type))
 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
   (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
 #define IS_SUPER(TYPE) \
@@ -419,7 +420,8 @@
                                
 #define objc_object_id         objc_global_trees[OCTI_OBJ_ID]
 #define objc_class_id          objc_global_trees[OCTI_CLS_ID]
-#define objc_id_id             objc_global_trees[OCTI_ID_ID]
+#define objc_type_id_id                objc_global_trees[OCTI_TYPE_ID_ID]
+#define objc_type_cls_id       objc_global_trees[OCTI_TYPE_CLS_ID]
 #define constant_string_id     objc_global_trees[OCTI_CNST_STR_ID]
 #define constant_string_type   objc_global_trees[OCTI_CNST_STR_TYPE]
 #define constant_string_global_id              \
Index: gcc/c-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.189.2.5
diff -u -r1.189.2.5 c-common.h
--- gcc/c-common.h      13 Sep 2003 02:18:52 -0000      1.189.2.5
+++ gcc/c-common.h      17 Sep 2003 16:52:51 -0000
@@ -95,7 +95,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: /cvsroot/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.170.2.4
diff -u -r1.170.2.4 c-parse.in
--- gcc/c-parse.in      13 Sep 2003 02:18:54 -0000      1.170.2.4
+++ gcc/c-parse.in      17 Sep 2003 16:52:56 -0000
@@ -173,8 +173,8 @@
 
 /* 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 AT_CLASS 
AT_ALIAS
 %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
 %token OBJC_STRING
 
@@ -245,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> objc_try_stmt superclass
 %type <itype> objc_try_catch_stmt objc_finally_block
@@ -457,7 +457,6 @@
        IDENTIFIER
        | TYPENAME
 @@ifobjc
-       | OBJECTNAME
        | CLASSNAME
 @@end_ifobjc
        ;
@@ -1356,13 +1355,13 @@
 @@ifobjc
        | CLASSNAME protocolrefs
                { $$ = get_static_reference ($1, $2); }
-       | OBJECTNAME protocolrefs
-               { $$ = get_object_reference ($2); }
+       | TYPENAME protocolrefs
+               { $$ = get_protocol_reference ($1, $2); }
 
 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
    - nisse@lysator.liu.se */
         | non_empty_protocolrefs
-                { $$ = get_object_reference ($1); }
+                { $$ = get_protocol_reference (0, $1); }
 @@end_ifobjc
        | typeof '(' expr ')'
                { skip_evaluation--; $$ = TREE_TYPE ($3); }
@@ -1629,9 +1628,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
@@ -1652,9 +1648,6 @@
        | parm_declarator_starttypename array_declarator  %prec '.'
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | TYPENAME
-@@ifobjc
-       | OBJECTNAME
-@@end_ifobjc
        ;
 
 parm_declarator_nostarttypename:
@@ -1805,7 +1798,7 @@
                    pedwarn ("extra semicolon in struct or union specified"); }
 @@ifobjc
        /* foo(sizeof(struct{ @defs(ClassName)})); */
-       | DEFS '(' CLASSNAME ')'
+       | AT_DEFS '(' CLASSNAME ')'
                { $$ = nreverse (get_class_ivars_from_name ($3)); }
 @@end_ifobjc
        ;
@@ -2694,7 +2687,7 @@
        | aliasdecl
        | protocoldef
        | methoddef
-       | END
+       | AT_END
                {
                  if (objc_implementation_context)
                     {
@@ -2716,14 +2709,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);
                }
@@ -2740,7 +2733,7 @@
        ;
 
 classdef:
-         INTERFACE identifier superclass protocolrefs
+         AT_INTERFACE identifier superclass protocolrefs
                {
                  objc_interface_context = objc_ivar_context
                    = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
@@ -2750,13 +2743,13 @@
                {
                   continue_class (objc_interface_context);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
 
-       | IMPLEMENTATION identifier superclass
+       | AT_IMPLEMENTATION identifier superclass
                {
                  objc_implementation_context = objc_ivar_context
                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, 
NULL_TREE);
@@ -2768,19 +2761,19 @@
                    = continue_class (objc_implementation_context);
                }
 
-       | INTERFACE identifier '(' identifier ')' protocolrefs
+       | AT_INTERFACE identifier '(' identifier ')' protocolrefs
                {
                  objc_interface_context
                    = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
                   continue_class (objc_interface_context);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
 
-       | IMPLEMENTATION identifier '(' identifier ')'
+       | AT_IMPLEMENTATION identifier '(' identifier ')'
                {
                  objc_implementation_context
                    = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, 
NULL_TREE);
@@ -2790,13 +2783,13 @@
        ;
 
 protocoldef:
-         PROTOCOL identifier protocolrefs
+         AT_PROTOCOL identifier protocolrefs
                {
                  objc_pq_context = 1;
                  objc_interface_context
                    = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
                }
-         methodprotolist END
+         methodprotolist AT_END
                {
                  objc_pq_context = 0;
                  finish_protocol(objc_interface_context);
@@ -2805,7 +2798,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);
                }
@@ -2835,9 +2828,9 @@
         ;
 
 visibility_spec:
-         PRIVATE { objc_public_flag = 2; }
-       | PROTECTED { objc_public_flag = 0; }
-       | PUBLIC { objc_public_flag = 1; }
+         AT_PRIVATE { objc_public_flag = 2; }
+       | AT_PROTECTED { objc_public_flag = 0; }
+       | AT_PUBLIC { objc_public_flag = 1; }
        ;
 
 ivar_decls:
@@ -3080,7 +3073,6 @@
          IDENTIFIER
        | TYPENAME
        | CLASSNAME
-       | OBJECTNAME
        | reservedwords
        ;
 
@@ -3192,14 +3184,14 @@
        ;
 
 objcselectorexpr:
-         SELECTOR '(' selectorarg ')'
+         AT_SELECTOR '(' selectorarg ')'
                {
                  $$ = $3;
                }
        ;
 
 objcprotocolexpr:
-         PROTOCOL '(' identifier ')'
+         AT_PROTOCOL '(' identifier ')'
                {
                  $$ = $3;
                }
@@ -3208,7 +3200,7 @@
 /* extension to support C-structures in the archiver */
 
 objcencodeexpr:
-         ENCODE '(' typename ')'
+         AT_ENCODE '(' typename ')'
                {
                  $$ = groktypename ($3);
                }
@@ -3317,8 +3309,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 },
@@ -3462,24 +3452,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
@@ -3552,15 +3541,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
@@ -3723,7 +3703,6 @@
     {
     case IDENTIFIER:
     case TYPENAME:
-    case OBJECTNAME:
     case TYPESPEC:
     case TYPE_QUAL:
     case SCSPEC:
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.179.2.12
diff -u -r1.179.2.12 objc-act.c
--- gcc/objc/objc-act.c 13 Sep 2003 02:19:46 -0000      1.179.2.12
+++ gcc/objc/objc-act.c 17 Sep 2003 17:02:21 -0000
@@ -313,6 +313,7 @@
 /* Reserved tag definitions.  */
 
 #define TYPE_ID                        "id"
+#define TYPE_CLASS             "Class"
 #define TAG_OBJECT             "objc_object"
 #define TAG_CLASS              "objc_class"
 #define TAG_SUPER              "objc_super"
@@ -579,33 +580,33 @@
    tree sel_name;
    int class_meth;
 {
-   tree rproto, p;
-   tree fnd = 0;
+  tree rproto, p;
+  tree fnd = 0;
 
-   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
-     {
-        p = TREE_VALUE (rproto);
+  for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+    {
+      p = TREE_VALUE (rproto);
 
-       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
-         {
-           if ((fnd = lookup_method (class_meth
-                                     ? 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);
-         }
-       else
-          {
-           ; /* An identifier...if we could not find a protocol.  */
-          }
+      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+       {
+         if ((fnd = lookup_method (class_meth
+                                   ? 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);
+       }
+      else
+       {
+         ; /* An identifier...if we could not find a protocol.  */
+       }
 
-       if (fnd)
-         return fnd;
-     }
+      if (fnd)
+       return fnd;
+    }
 
-   return 0;
+  return 0;
 }
 
 static tree
@@ -1008,23 +1009,50 @@
   return type;
 }
 
+/* 
+   Ayers: Maybe we should merge get_static_reference
+   into this function.
+*/
 tree
-get_object_reference (protocols)
+get_protocol_reference (typename, protocols)
+     tree typename;
      tree protocols;
 {
-  tree type_decl = lookup_name (objc_id_id);
-  tree type;
+  tree type_decl;
+  tree type = NULL_TREE;
+  tree type_ref;
+
+  //  debug_tree (typename);
+
+  if (typename == objc_type_id_id || !typename)
+    {
+      type_decl = lookup_name (objc_type_id_id);
+      type_ref =  objc_id_type;
+    }
+  else if (typename == objc_type_cls_id)
+    {
+      type_decl = lookup_name (objc_type_cls_id);
+      type_ref =  objc_class_type;
+    }
+  else
+    {
+      error ("Protocol qualifier is invalid for type `%s'",
+            IDENTIFIER_POINTER(typename));
+      return error_mark_node;
+    }
 
   if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
     {
       type = TREE_TYPE (type_decl);
-      if (TYPE_MAIN_VARIANT (type) != id_type)
-       warning ("unexpected type for `id' (%s)",
+      if (TYPE_MAIN_VARIANT (type) != type_ref)
+       warning ("unexpected type for `%s' (%s)",
+                (IS_ID(typename) ? TYPE_ID : TYPE_CLASS),
                 gen_declaration (type, errbuf));
     }
   else
     {
-      error ("undefined type `id', please import <objc/objc.h>");
+      error ("undefined type `%s', please import <objc/objc.h>",
+            (IS_ID(typename) ? TYPE_ID : TYPE_CLASS));
       return error_mark_node;
     }
 
@@ -1053,6 +1081,7 @@
 
       type = t;
     }
+
   return type;
 }
 
@@ -1179,9 +1208,11 @@
 
   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
 
-  id_type = build_pointer_type (objc_object_reference);
+  objc_id_type = build_pointer_type (objc_object_reference);
+
+  objc_type_id_id = get_identifier (TYPE_ID);
+  objc_type_cls_id = get_identifier (TYPE_CLASS);
 
-  objc_id_id = get_identifier (TYPE_ID);
   objc_class_id = get_identifier (TAG_CLASS);
 
   objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
@@ -1208,8 +1239,8 @@
   /* id objc_msgSend (id, SEL, ...); */
 
   temp_type
-    = build_function_type (id_type,
-                          tree_cons (NULL_TREE, id_type,
+    = build_function_type (objc_id_type,
+                          tree_cons (NULL_TREE, objc_id_type,
                                      tree_cons (NULL_TREE, selector_type,
                                                 NULL_TREE)));
 
@@ -1235,7 +1266,7 @@
   /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
 
   temp_type
-    = build_function_type (id_type,
+    = build_function_type (objc_id_type,
                           tree_cons (NULL_TREE, super_type,
                                      tree_cons (NULL_TREE, selector_type,
                                                 NULL_TREE)));
@@ -1271,8 +1302,8 @@
                    get_identifier (TAG_RETURN_STRUCT));
 
       tree stret_temp_type
-       = build_function_type (id_type,
-                              tree_cons (NULL_TREE, id_type,
+       = build_function_type (objc_id_type,
+                              tree_cons (NULL_TREE, objc_id_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
 
@@ -1280,7 +1311,7 @@
        builtin_function (TAG_MSGSEND_STRET, stret_temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
       stret_temp_type
        = build_function_type (objc_return_struct_type,
-                              tree_cons (NULL_TREE, id_type,
+                              tree_cons (NULL_TREE, objc_id_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
 
@@ -1288,7 +1319,7 @@
        builtin_function (TAG_MSGSEND_NONNIL_STRET, stret_temp_type, 0, 
NOT_BUILT_IN, NULL, NULL_TREE);
 
       stret_temp_type
-       = build_function_type (id_type,
+       = build_function_type (objc_id_type,
                               tree_cons (NULL_TREE, super_type,
                                          tree_cons (NULL_TREE, selector_type,
                                                     NULL_TREE)));
@@ -1300,7 +1331,7 @@
 
   /* id objc_getClass (const char *); */
 
-  temp_type = build_function_type (id_type,
+  temp_type = build_function_type (objc_id_type,
                        tree_cons (NULL_TREE,
                                   const_string_type_node,
                                   OBJC_VOID_AT_END));
@@ -2641,8 +2672,8 @@
   if (!type || TREE_CODE (type) != POINTER_TYPE)
     return 0;
   /* NB: This function may be called before the ObjC front-end
-     has been initialized, in which case ID_TYPE will be NULL. */
-  if (id_type && type && TYPE_P (type)
+     has been initialized, in which case OBJC_ID_TYPE will be NULL. */
+  if (objc_id_type && type && TYPE_P (type)
       && (IS_ID (type)
          || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
     return type;
@@ -2983,7 +3014,7 @@
        objc_stack_exception_data);
   objc_rethrow_exception = tree_cons (NULL_TREE,
        objc_declare_variable (RID_VOLATILE, get_identifier 
(UTAG_RETHROWEXC_VAR), 
-               id_type,
+               objc_id_type,
                build_int_2 (0, 0)),
        objc_rethrow_exception);
 
@@ -3020,7 +3051,7 @@
     objc_enter_block ();
     objc_caught_exception = tree_cons (NULL_TREE, 
        objc_declare_variable (RID_REGISTER, get_identifier 
(UTAG_CAUGHTEXC_VAR), 
-               id_type, objc_build_extract_expr ()),
+               objc_id_type, objc_build_extract_expr ()),
        objc_caught_exception);
     objc_build_try_enter_fragment ();  
     val_stack_push (&catch_count_stack, 1);
@@ -3069,7 +3100,7 @@
     var_name = TREE_OPERAND (var_name, 0);
   if (TREE_CODE (var_type) == TYPE_DECL || TREE_CODE (var_type) == 
POINTER_TYPE)
     var_type = TREE_TYPE (var_type);
-  catch_id = (var_type == TREE_TYPE (id_type));
+  catch_id = (var_type == TREE_TYPE (objc_id_type));
         
   if (!flag_objc_exceptions)
     fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception 
syntax");
@@ -3082,7 +3113,7 @@
   for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch); 
        prev_catch = TREE_CHAIN (prev_catch))   
     {
-      if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
+      if (TREE_VALUE (prev_catch) == TREE_TYPE (objc_id_type))
        {
          warning ("Exception already handled by preceding `@catch(id)'");
          break;
@@ -3295,7 +3326,7 @@
   objc_enter_block ();
   objc_eval_once = tree_cons (NULL_TREE,
        objc_declare_variable (RID_AUTO, get_identifier (UTAG_EVALONCE_VAR), 
-               id_type,
+               objc_id_type,
                sync_expr),
        objc_eval_once);
   objc_build_try_prologue ();
@@ -3394,7 +3425,7 @@
        = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, 
NULL_TREE);
 
   /* id objc_exception_extract(struct _objc_exception_data *); */
-  temp_type = build_function_type (id_type,
+  temp_type = build_function_type (objc_id_type,
                tree_cons (NULL_TREE, 
                    build_pointer_type (objc_exception_data_template), 
                        OBJC_VOID_AT_END));
@@ -3414,7 +3445,7 @@
   /* void objc_sync_enter(id); */
   /* void objc_sync_exit(id); */
   temp_type = build_function_type (void_type_node,
-               tree_cons (NULL_TREE, id_type,
+               tree_cons (NULL_TREE, objc_id_type,
                        OBJC_VOID_AT_END));
   objc_exception_throw_decl
        = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
@@ -3426,8 +3457,8 @@
        = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, 
NULL_TREE);
   /* int objc_exception_match(id, id); */
   temp_type = build_function_type (integer_type_node,
-               tree_cons (NULL_TREE, id_type, 
-                   tree_cons (NULL_TREE, id_type,
+               tree_cons (NULL_TREE, objc_id_type, 
+                   tree_cons (NULL_TREE, objc_id_type,
                        OBJC_VOID_AT_END)));
   objc_exception_match_decl
        = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
@@ -5562,7 +5593,7 @@
   else if (context == METHOD_DEF)
     arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
   else
-    arglist = build_tree_list (NULL_TREE, id_type);
+    arglist = build_tree_list (NULL_TREE, objc_id_type);
 
   /* Selector type - will eventually change to `int'.  */
   chainon (arglist, build_tree_list (NULL_TREE, selector_type));
@@ -5609,7 +5640,8 @@
 
       if (hsh->list)
         {
-         /* We have two or more methods with the same name but different 
types.  */
+         /* We have two or more methods with the same name 
+            but different types.  */
          attr loop;
          char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
 
@@ -5820,7 +5852,8 @@
                     IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
              return error_mark_node;
            }
-         rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+         rtype 
+           = lookup_interface (CLASS_SUPER_NAME (implementation_template));
        }
       else if (self)
        rtype = lookup_interface (CLASS_NAME (implementation_template));
@@ -5840,16 +5873,84 @@
          rtype = NULL_TREE;
        }
       else
-       is_class = TYPE_NAME (rtype) = get_identifier ("Class");
+       {
+         rprotos = TYPE_PROTOCOL_LIST (rtype);
+         is_class = TYPE_NAME (rtype) = get_identifier ("Class");
+
+         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, 
+                                             is_class != NULL_TREE);
+         if (!method_prototype && is_class != NULL_TREE)
+           {
+             /* Check if any root classes implement the protocol
+                in which case we also have to check the instance methods.  */
+             tree proto_ch;        /* protocol chain */
+             tree inter_ch;        /* interface chain */
+             tree categ_ch;        /* category chain */
+             tree proto_value;     /* protocol value */
+             tree proto_candidate; /* prototype candidate */
+
+             for (proto_ch = rprotos;
+                  proto_ch && method_prototype == NULL_TREE;
+                  proto_ch = TREE_CHAIN (proto_ch))
+               {
+                 proto_value = TREE_VALUE(proto_ch);
+
+                 if (TREE_CODE (proto_value) != PROTOCOL_INTERFACE_TYPE)
+                   continue;
+
+                 /* Find protocols that declare the method
+                    as an instance method.  */
+                 proto_candidate 
+                   = lookup_method (PROTOCOL_NST_METHODS (proto_value),
+                                    sel_name);
+                 /* Check inherited protocols.  */
+                 if (!proto_candidate)
+                   proto_candidate 
+                     = lookup_method_in_protocol_list 
+                     (PROTOCOL_LIST (proto_value), sel_name, 0);
+
+                 /* If we found one, check all root classes
+                    to see if any declare it.  */
+                 if (proto_candidate)
+                   for (inter_ch = interface_chain;
+                        inter_ch && method_prototype == NULL_TREE;
+                        inter_ch = TREE_CHAIN (inter_ch))
+                     {
+                       if (CLASS_SUPER_NAME (inter_ch))
+                         continue;
+                       
+                       if (!method_prototype
+                           && lookup_protocol_in_reflist
+                           (CLASS_PROTOCOL_LIST (inter_ch),
+                            proto_value))
+                         method_prototype = proto_candidate;
+
+                       /* We've already retrieved the prototype from
+                          the protocol, so there is no need to check
+                          the category before the interface declaration.  */
+                       for (categ_ch = CLASS_CATEGORY_LIST (inter_ch);
+                            categ_ch && !method_prototype;
+                            categ_ch = CLASS_CATEGORY_LIST (categ_ch))
+                              if (lookup_protocol_in_reflist
+                                  (CLASS_PROTOCOL_LIST (categ_ch),
+                                   proto_value))
+                                method_prototype = proto_candidate;
+                     }
+               }
+           }
+       }
       if (!method_prototype && !rprotos)
        method_prototype
          = (is_class
-            ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 
1)
+            ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name),
+                                1)
             : lookup_method_in_hash_lists (sel_name));
     }
   else
@@ -5970,7 +6071,7 @@
                 (!flag_next_runtime || flag_nil_receivers
                  ? umsg_decl
                  : umsg_nonnil_decl));
-  tree rcv_p = (super_flag ? super_type : id_type);
+  tree rcv_p = (super_flag ? super_type : objc_id_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.
@@ -5978,7 +6079,7 @@
   tree ret_type
     = (method_prototype
        ? groktypename (TREE_TYPE (method_prototype))
-       : id_type);
+       : objc_id_type);
   tree sender_cast
     = build_pointer_type
       (build_function_type 
@@ -6345,7 +6446,9 @@
 
   while (inter)
     {
-      tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS 
(inter);
+      tree chain = (is_class 
+                   ? CLASS_CLS_METHODS (inter) 
+                   : CLASS_NST_METHODS (inter));
       tree category = inter;
 
       /* First, look up the method in the class itself.  */
@@ -6355,7 +6458,9 @@
       /* Failing that, look for the method in each category of the class.  */
       while ((category = CLASS_CATEGORY_LIST (category)))
        {
-         chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS 
(category);
+         chain = (is_class 
+                  ? CLASS_CLS_METHODS (category) 
+                  : CLASS_NST_METHODS (category));
 
          /* Check directly in each category.  */
          if ((meth = lookup_method (chain, ident)))
@@ -6400,7 +6505,9 @@
   tree mth;
   hash hsh;
 
-  if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : 
CLASS_NST_METHODS (class), method)))
+  if (!(mth = lookup_method ((is_class 
+                             ? CLASS_CLS_METHODS (class) 
+                             : CLASS_NST_METHODS (class)), method)))
     {
       /* put method on list in reverse order */
       if (is_class)
@@ -6424,15 +6531,19 @@
           || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
          && !comp_proto_with_proto (method, mth))
        error ("duplicate declaration of method `%c%s'",
-               is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME 
(mth)));
+               (is_class ? '+' : '-'),
+              IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
     }
 
-  if (!(hsh = hash_lookup (is_class 
-                          ? cls_method_hash_list
-                          : nst_method_hash_list, METHOD_SEL_NAME (method))))
+  if (!(hsh 
+       = hash_lookup ((is_class 
+                       ? cls_method_hash_list
+                       : nst_method_hash_list), METHOD_SEL_NAME (method))))
     {
       /* Install on a global chain.  */
-      hash_enter (is_class ? cls_method_hash_list : nst_method_hash_list, 
method);
+      hash_enter ((is_class 
+                  ? cls_method_hash_list 
+                  : nst_method_hash_list), method);
     }
   else
     {
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.16.4.2
diff -u -r1.16.4.2 objc-act.h
--- gcc/objc/objc-act.h 27 Aug 2003 00:19:24 -0000      1.16.4.2
+++ gcc/objc/objc-act.h 17 Sep 2003 17:02:21 -0000
@@ -60,7 +60,7 @@
 tree get_class_ivars_from_name                 PARAMS ((tree));
 tree get_class_reference                       PARAMS ((tree));
 tree get_static_reference                      PARAMS ((tree, tree));
-tree get_object_reference                      PARAMS ((tree));
+tree get_protocol_reference                    PARAMS ((tree, tree));
 tree build_message_expr                                PARAMS ((tree));
 tree finish_message_expr                       PARAMS ((tree, tree, tree));
 tree build_selector_expr                       PARAMS ((tree));
@@ -259,7 +259,8 @@
 
     OCTI_OBJ_ID,
     OCTI_CLS_ID,
-    OCTI_ID_ID,
+    OCTI_TYPE_ID_ID,
+    OCTI_TYPE_CLS_ID,
     OCTI_CNST_STR_ID,
     OCTI_CNST_STR_TYPE,
     OCTI_CNST_STR_GLOB_ID,
@@ -313,7 +314,7 @@
 
 #define super_type             objc_global_trees[OCTI_SUPER_TYPE]
 #define selector_type          objc_global_trees[OCTI_SEL_TYPE]
-#define id_type                        objc_global_trees[OCTI_ID_TYPE]
+#define objc_id_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]
@@ -321,7 +322,7 @@
 /* Type checking macros.  */
 
 #define IS_ID(TYPE) \
-  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
+  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (objc_id_type))
 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
   (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
 #define IS_SUPER(TYPE) \
@@ -419,7 +420,8 @@
                                
 #define objc_object_id         objc_global_trees[OCTI_OBJ_ID]
 #define objc_class_id          objc_global_trees[OCTI_CLS_ID]
-#define objc_id_id             objc_global_trees[OCTI_ID_ID]
+#define objc_type_id_id                objc_global_trees[OCTI_TYPE_ID_ID]
+#define objc_type_cls_id       objc_global_trees[OCTI_TYPE_CLS_ID]
 #define constant_string_id     objc_global_trees[OCTI_CNST_STR_ID]
 #define constant_string_type   objc_global_trees[OCTI_CNST_STR_TYPE]
 #define constant_string_global_id              \
@@ -428,3 +430,4 @@
 #define UOBJC_SUPER_decl       objc_global_trees[OCTI_SUPER_DECL]
 
 #endif /* GCC_OBJC_ACT_H */
+
#include <objc/objc.h>
#include <objc/objc-api.h>
#include <objc/Object.h>


@protocol MyProto1
-(char)getVal1;
@end

@protocol MyProto2
-(long)getVal1;
@end

@interface MyClass1 : Object <MyProto1>
+(Class)class;
@end

@implementation MyClass1
+(Class)class
{
  return self;
}
-(char)getVal1
{
  return 'a';
}

@end

@interface MyClass2 <MyProto2>
{
  Class isa;
}
+(Class)class;
+(id)new;
@end

@implementation MyClass2
+(Class)class
{
  return self;
}
+(id)new
{
  return class_create_instance(self);
}
-(long)getVal1
{
  return 11L;
}
@end
/*----------------------------------------*/
@protocol MyProto3
-(char)getVal2;
@end
@protocol MyProto4
-(long)getVal2;
@end

@interface MyClass1 (Category1) <MyProto3>
@end

@interface MyClass2 (Category2) <MyProto4>
@end

@implementation MyClass1 (Category1)
-(char)getVal2
{
  return 'b';
}
@end
@implementation MyClass2 (Category1)
-(long)getVal2
{
  return 22L;
}
@end
/*----------------------------------------*/
@protocol MyProto5 <MyProto1>
-(char)getVal3;
@end

@protocol MyProto6 <MyProto2>
-(long)getVal3;
@end

@interface MyClass1 (Category3) <MyProto5>
@end
@interface MyClass2 (Category4) <MyProto6>
@end

@implementation MyClass1 (Category3)
-(char)getVal1
{
  return 'A';
}
-(char)getVal3
{
  return 'c';
}
@end

@implementation MyClass2 (Category4)
-(long)getVal1;
{
  return 1111L;
}
-(long)getVal3;
{
  return 33L;
}
@end

int main ()
{
  Class <MyProto1> varProto1Class1;
  Class <MyProto2> varProto2Class2;
  Class <MyProto3> varProto3Class1;
  Class <MyProto4> varProto4Class2;
  Class <MyProto5> varProto5Class1;
  Class <MyProto6> varProto6Class2;
  Class            varClass1;
  Class            varClass2;
  id <MyProto1>    varProto1Id1;
  id <MyProto2>    varProto2Id2;
  id <MyProto3>    varProto3Id1;
  id <MyProto4>    varProto4Id2;
  id <MyProto5>    varProto5Id1;
  id <MyProto6>    varProto6Id2;
  id               varId1;
  id               varId2;
  char             retChar;
  long             retLong;

  varProto1Class1 = [MyClass1 class];
  varProto2Class2 = [MyClass2 class];
  varProto3Class1 = [MyClass1 class];
  varProto4Class2 = [MyClass2 class];
  varProto5Class1 = [MyClass1 class];
  varProto6Class2 = [MyClass2 class];
  varClass1       = [MyClass1 class];
  varClass2       = [MyClass2 class];
  varProto1Id1    = [MyClass1 new];
  varProto2Id2    = [MyClass2 new];
  varProto3Id1    = [MyClass1 new];
  varProto4Id2    = [MyClass2 new];
  varId1          = [MyClass1 new];
  varId2          = [MyClass2 new];

  retChar = [varProto1Class1 getVal1]; /*`+getVal1' not implemented by 
protocol(s*/
  retLong = [varProto2Class2 getVal1];
  retChar = [varClass1 getVal1];       /*`Class' may not respond to `+getVal1'*/
  retLong = [varClass2 getVal1];       /*`Class' may not respond to `+getVal1'*/
  retChar = [varProto1Id1 getVal1];
  retLong = [varProto2Id2 getVal1];
  retChar = [varId1 getVal1];          /*multiple methods named `-getVal1' 
found*/
  retLong = [varId2 getVal1];          /*multiple methods named `-getVal1' 
found*/

  retChar = [varProto3Class1 getVal2]; /*`+getVal2' not implemented by 
protocol(s)*/
  retLong = [varProto4Class2 getVal2];
  retChar = [varClass1 getVal2];       /*`Class' may not respond to `+getVal2'*/
  retLong = [varClass2 getVal2];       /*`Class' may not respond to `+getVal2'*/
  retChar = [varProto3Id1 getVal2];
  retLong = [varProto4Id2 getVal2];
  retChar = [varId1 getVal2];          /*multiple methods named `-getVal2' 
found*/
  retLong = [varId2 getVal2];          /*multiple methods named `-getVal2' 
found*/

  retChar = [varProto5Class1 getVal1]; /*`+getVal1' not implemented by 
protocol(s)*/
  retLong = [varProto6Class2 getVal1];
  retChar = [varProto5Class1 getVal3]; /*`+getVal3' not implemented by 
protocol(s)*/
  retLong = [varProto6Class2 getVal3];
  retChar = [varClass1 getVal1];       /*`Class' may not respond to `+getVal1'*/
  retLong = [varClass2 getVal1];       /*`Class' may not respond to `+getVal1'*/
  retChar = [varClass1 getVal3];       /*`Class' may not respond to `+getVal1'*/
  retLong = [varClass2 getVal3];       /*`Class' may not respond to `+getVal1'*/
  retChar = [varProto5Id1 getVal1];
  retLong = [varProto6Id2 getVal1];
  retChar = [varProto5Id1 getVal3];
  retLong = [varProto6Id2 getVal3];
  retChar = [varId1 getVal1];          /*multiple methods named `-getVal1' 
found*/
  retLong = [varId2 getVal1];          /*multiple methods named `-getVal1' 
found*/
  retChar = [varId1 getVal3];          /*multiple methods named `-getVal3' 
found*/
  retLong = [varId2 getVal3];          /*multiple methods named `-getVal3' 
found*/

  return(0);
}

 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]