]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for contextualizing...
authorZiemowit Laski <zlaski@apple.com>
Wed, 1 Aug 2001 08:10:00 +0000 (08:10 +0000)
committerStan Shebs <shebs@gcc.gnu.org>
Wed, 1 Aug 2001 08:10:00 +0000 (08:10 +0000)
2001-08-01  Ziemowit Laski  <zlaski@apple.com>

        * c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for
contextualizing Objective-C class name lookup by the lexer.
(typespec_reserved_nonattr): Disable ObjC class name lookup after
seeing a TYPESPEC.
(protocoldef): Add support for forward @protocol declarations.
(yylexname): Suppress ObjC class name lookup in certain contexts;
re-enable after lookup is complete.
(_yylex): Re-enable ObjC class name lookup when certain
punctuation marks are seen.

* objc/objc-act.c (check_protocol_recursively): New function used
for finding circular dependencies in protocols.
(objc_declare_protocols): New function for handling forward
@protocol declarations.
(receiver_is_class_object): Detect the case when 'self' is used
inside of a class method.
(build_message_expr): Issue a warning if class method is desired
but instance method is found instead.
(conforms_to_protocol): Streamline.
(objc_comptypes): Detect the fact that 'Bar<Foo> foo' conforms to
protocol Foo, even if 'Bar foo' does not.
(check_protocols): Streamline.
(start_protocol): Add checks for circular and duplicate protocol
definitions.
(encode_aggregate_within): For typedefs of structs, encode the
underlying struct.
* objc/objc-act.h (PROTOCOL_DEFINED): New tree accessor.
(objc_declare_protocols): New prototype.

From-SVN: r44536

gcc/ChangeLog
gcc/c-parse.in
gcc/objc/objc-act.c
gcc/objc/objc-act.h

index 857a75db7d570791b2aafae523161c6aa034dfc9..01ef78a5bef078c33c27aaebe67b4badeccb60a4 100644 (file)
@@ -1,3 +1,34 @@
+2001-08-01  Ziemowit Laski  <zlaski@apple.com>
+
+        * c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for
+       contextualizing Objective-C class name lookup by the lexer.
+       (typespec_reserved_nonattr): Disable ObjC class name lookup after
+       seeing a TYPESPEC.
+       (protocoldef): Add support for forward @protocol declarations.
+       (yylexname): Suppress ObjC class name lookup in certain contexts;
+       re-enable after lookup is complete.
+       (_yylex): Re-enable ObjC class name lookup when certain
+       punctuation marks are seen.
+
+       * objc/objc-act.c (check_protocol_recursively): New function used
+       for finding circular dependencies in protocols.
+       (objc_declare_protocols): New function for handling forward
+       @protocol declarations.
+       (receiver_is_class_object): Detect the case when 'self' is used
+       inside of a class method.
+       (build_message_expr): Issue a warning if class method is desired
+       but instance method is found instead.
+       (conforms_to_protocol): Streamline.
+       (objc_comptypes): Detect the fact that 'Bar<Foo> foo' conforms to
+       protocol Foo, even if 'Bar foo' does not.
+       (check_protocols): Streamline.
+       (start_protocol): Add checks for circular and duplicate protocol
+       definitions.
+       (encode_aggregate_within): For typedefs of structs, encode the
+       underlying struct.
+       * objc/objc-act.h (PROTOCOL_DEFINED): New tree accessor.
+       (objc_declare_protocols): New prototype.
+
 2001-08-01  Neil Booth  <neil@cat.daikokuya.demon.co.uk>
 
        * cpphash.h (struct cpp_reader): New members line, pseudo_newlines.
index 7d87e2004fd28f10e5c8db0377852afb407f829a..d1320565bfc54997b1f67f2e7cf862e2ab96dabf 100644 (file)
@@ -29,10 +29,10 @@ Boston, MA 02111-1307, USA.  */
    written by AT&T, but I have never seen it.  */
 
 ifobjc
-%expect 31
+%expect 31 /* shift/reduce conflicts, and 1 reduce/reduce conflict.  */
 end ifobjc
 ifc
-%expect 10
+%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts.  */
 end ifc
 
 %{
@@ -295,8 +295,18 @@ int objc_receiver_context;
 int objc_public_flag;
 int objc_pq_context;
 
+/* The following flag is needed to contextualize ObjC lexical analysis.
+   In some cases (e.g., 'int NSObject;'), it is undesirable to bind 
+   an identifier to an ObjC class, even if a class with that name 
+   exists.  */
+int objc_need_raw_identifier;
+#define OBJC_NEED_RAW_IDENTIFIER(VAL)  objc_need_raw_identifier = VAL
 end ifobjc
 
+ifc
+#define OBJC_NEED_RAW_IDENTIFIER(VAL)  /* nothing */
+end ifc
+
 /* Tell yyparse how to print a token's value, if yydebug is set.  */
 
 #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
@@ -444,7 +454,7 @@ identifier:
        | TYPENAME
 ifobjc
        | OBJECTNAME
-        | CLASSNAME
+       | CLASSNAME
 end ifobjc
        ;
 
@@ -1384,6 +1394,7 @@ typespec_attr:
 
 typespec_reserved_nonattr:
          TYPESPEC
+               { OBJC_NEED_RAW_IDENTIFIER (1); }
        | structsp_nonattr
        ;
 
@@ -1694,6 +1705,9 @@ parm_declarator_starttypename:
        | parm_declarator_starttypename array_declarator  %prec '.'
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | TYPENAME
+ifobjc
+       | OBJECTNAME
+end ifobjc
        ;
 
 parm_declarator_nostarttypename:
@@ -2836,6 +2850,13 @@ protocoldef:
                  finish_protocol(objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
+       /* 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 ';'
+               {
+                 objc_declare_protocols ($2);
+               }
        ;
 
 protocolrefs:
@@ -3119,8 +3140,9 @@ keywordselector:
 
 selector:
          IDENTIFIER
-        | TYPENAME
-       | OBJECTNAME
+       | TYPENAME
+       | CLASSNAME
+       | OBJECTNAME
        | reservedwords
        ;
 
@@ -3615,12 +3637,26 @@ static int
 yylexname ()
 {
   tree decl;
-
+  
+ifobjc
+  int objc_force_identifier = objc_need_raw_identifier;
+  OBJC_NEED_RAW_IDENTIFIER (0);
+end ifobjc
+  
   if (C_IS_RESERVED_WORD (yylval.ttype))
     {
       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
@@ -3653,8 +3689,11 @@ ifobjc
   else
     {
       tree objc_interface_decl = is_class_name (yylval.ttype);
-
-      if (objc_interface_decl)
+      /* ObjC class names are in the same namespace as variables and
+        typedefs, and hence are shadowed by local declarations.  */
+      if (objc_interface_decl 
+         && (global_bindings_p () 
+             || (!objc_force_identifier && !decl)))
        {
          yylval.ttype = objc_interface_decl;
          return CLASSNAME;
@@ -3692,10 +3731,7 @@ _yylex ()
     case CPP_AND_AND:                                  return ANDAND;
     case CPP_OR_OR:                                    return OROR;
     case CPP_QUERY:                                    return '?';
-    case CPP_COLON:                                    return ':';
-    case CPP_COMMA:                                    return ',';
     case CPP_OPEN_PAREN:                               return '(';
-    case CPP_CLOSE_PAREN:                              return ')';
     case CPP_EQ_EQ:    yylval.code = EQ_EXPR;          return EQCOMPARE;
     case CPP_NOT_EQ:   yylval.code = NE_EXPR;          return EQCOMPARE;
     case CPP_GREATER_EQ:yylval.code = GE_EXPR;         return ARITHCOMPARE;
@@ -3716,7 +3752,6 @@ _yylex ()
     case CPP_CLOSE_SQUARE:                             return ']';
     case CPP_OPEN_BRACE:                               return '{';
     case CPP_CLOSE_BRACE:                              return '}';
-    case CPP_SEMICOLON:                                        return ';';
     case CPP_ELLIPSIS:                                 return ELLIPSIS;
 
     case CPP_PLUS_PLUS:                                        return PLUSPLUS;
@@ -3724,6 +3759,13 @@ _yylex ()
     case CPP_DEREF:                                    return POINTSAT;
     case CPP_DOT:                                      return '.';
 
+      /* The following tokens may affect the interpretation of any
+        identifiers following, if doing Objective-C.  */
+    case CPP_COLON:            OBJC_NEED_RAW_IDENTIFIER (0);   return ':';
+    case CPP_COMMA:            OBJC_NEED_RAW_IDENTIFIER (0);   return ',';
+    case CPP_CLOSE_PAREN:      OBJC_NEED_RAW_IDENTIFIER (0);   return ')';
+    case CPP_SEMICOLON:                OBJC_NEED_RAW_IDENTIFIER (0);   return ';';
+
     case CPP_EOF:
       if (cpp_pop_buffer (parse_in) == 0)
        return 0;
@@ -3741,8 +3783,8 @@ _yylex ()
     case CPP_WSTRING:
       return STRING;
       
-      /* This token is Objective-C specific.  It gives the next
-        token special significance.  */
+      /* This token is Objective-C specific.  It gives the next token
+        special significance.  */
     case CPP_ATSIGN:
 ifobjc
       {
index 0b99ece7feaf9c412c260fd2d6514a01d95ed6ce..03c3ae4f2627ba80e14ea54f9d911d882a5f8b76 100644 (file)
@@ -253,6 +253,7 @@ static tree build_selector_reference_decl   PARAMS ((void));
 
 static tree add_protocol                       PARAMS ((tree));
 static tree lookup_protocol                    PARAMS ((tree));
+static void check_protocol_recursively         PARAMS ((tree, tree));
 static tree lookup_and_install_protocols       PARAMS ((tree));
 
 /* Type encoding.  */
@@ -336,6 +337,8 @@ static tree check_duplicates                        PARAMS ((hash));
 static tree receiver_is_class_object           PARAMS ((tree));
 static int check_methods                       PARAMS ((tree, tree, int));
 static int conforms_to_protocol                        PARAMS ((tree, tree));
+static void check_protocol                     PARAMS ((tree, const char *,
+                                                      const char *));
 static void check_protocols                    PARAMS ((tree, const char *,
                                                       const char *));
 static tree encode_method_def                  PARAMS ((tree));
@@ -1010,6 +1013,12 @@ objc_comptypes (lhs, rhs, reflexive)
                      tree cat;
 
                      rproto_list = CLASS_PROTOCOL_LIST (rinter);
+                     /* If the underlying ObjC class does not have
+                        protocols attached to it, perhaps there are
+                        "one-off" protocols attached to the rhs?
+                        E.g., 'id<MyProt> foo;'.  */
+                     if (!rproto_list)
+                       rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
                      rproto = lookup_protocol_in_reflist (rproto_list, p);
 
                      /* Check for protocols adopted by categories.  */
@@ -1202,6 +1211,32 @@ get_object_reference (protocols)
   return type;
 }
 
+/* Check for circular dependencies in protocols.  The arguments are
+   PROTO, the protocol to check, and LIST, a list of protocol it
+   conforms to.  */
+
+static void 
+check_protocol_recursively (proto, list)
+     tree proto;
+     tree list;
+{
+  tree p;
+
+  for (p = list; p; p = TREE_CHAIN (p))
+    {
+      tree pp = TREE_VALUE (p);
+
+      if (TREE_CODE (pp) == IDENTIFIER_NODE)
+       pp = lookup_protocol (pp);
+
+      if (pp == proto)
+       fatal_error ("protocol `%s' has circular dependency",
+                    IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));      
+      if (pp)
+       check_protocol_recursively (proto, PROTOCOL_LIST (pp));
+    }
+}
+
 static tree
 lookup_and_install_protocols (protocols)
      tree protocols;
@@ -4871,18 +4906,27 @@ check_duplicates (hsh)
   return meth;
 }
 
-/* If RECEIVER is a class reference, return the identifier node for the
-   referenced class.  RECEIVER is created by get_class_reference, so we
-   check the exact form created depending on which runtimes are used.  */
+/* If RECEIVER is a class reference, return the identifier node for
+   the referenced class.  RECEIVER is created by get_class_reference,
+   so we check the exact form created depending on which runtimes are
+   used.  */
 
 static tree
 receiver_is_class_object (receiver)
       tree receiver;
 {
   tree chain, exp, arg;
+
   if (flag_next_runtime)
     {
-      /* The receiver is a variable created by build_class_reference_decl.  */
+      /* The receiver is 'self' in the context of a class method.  */
+      if (objc_method_context
+         && receiver == self_decl
+         && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
+       return CLASS_NAME (objc_implementation_context);
+
+      /* The receiver is a variable created by
+         build_class_reference_decl.  */
       if (TREE_CODE (receiver) == VAR_DECL
          && TREE_TYPE (receiver) == objc_class_type)
        /* Look up the identifier.  */
@@ -4899,7 +4943,7 @@ receiver_is_class_object (receiver)
          && (exp = TREE_OPERAND (exp, 0))
          && TREE_CODE (exp) == FUNCTION_DECL
          && exp == objc_get_class_decl
-         /* we have a call to objc_getClass! */
+         /* We have a call to objc_getClass!  */
          && (arg = TREE_OPERAND (receiver, 1))
          && TREE_CODE (arg) == TREE_LIST
          && (arg = TREE_VALUE (arg)))
@@ -5143,7 +5187,8 @@ build_message_expr (mess)
            method_prototype = lookup_class_method_static (iface, sel_name);
        }
 
-      if (!method_prototype)
+      if (!method_prototype 
+          || TREE_CODE (method_prototype) != CLASS_METHOD_DECL)
        {
          warning ("cannot find class (factory) method.");
          warning ("return type for `%s' defaults to id",
@@ -5960,16 +6005,17 @@ check_methods (chain, list, mtype)
     return first;
 }
 
+/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
+
 static int
 conforms_to_protocol (class, protocol)
      tree class;
      tree protocol;
 {
-   while (protocol)
+   if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
      {
        tree p = CLASS_PROTOCOL_LIST (class);
-
-       while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
+       while (p && TREE_VALUE (p) != protocol)
         p = TREE_CHAIN (p);
 
        if (!p)
@@ -5981,8 +6027,6 @@ conforms_to_protocol (class, protocol)
           if (!tmp)
             return 0;
         }
-
-       protocol = TREE_CHAIN (protocol);
      }
 
    return 1;
@@ -6054,57 +6098,81 @@ check_methods_accessible (chain, context, mtype)
     return first;
 }
 
+/* Check whether the current interface (accessible via
+   'implementation_context') actually implements protocol P, along
+   with any protocols that P inherits.  */
+   
 static void
-check_protocols (proto_list, type, name)
-     tree proto_list;
+check_protocol (p, type, name)
+     tree p;
      const char *type;
      const char *name;
 {
-  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
+  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
     {
-      tree p = TREE_VALUE (proto_list);
+      int f1, f2;
 
-      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+      /* Ensure that all protocols have bodies!  */
+      if (flag_warn_protocol)
        {
-         int f1, f2;
-         
-         /* Ensure that all protocols have bodies.  */
-         if (flag_warn_protocol) {
-           f1 = check_methods (PROTOCOL_CLS_METHODS (p),
-                               CLASS_CLS_METHODS (implementation_context),
-                               '+');
-           f2 = check_methods (PROTOCOL_NST_METHODS (p),
-                               CLASS_NST_METHODS (implementation_context),
-                               '-');
-         } else {
-           f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
-                                          implementation_context,
-                                          '+');
-           f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
-                                          implementation_context,
-                                          '-');
-         }
-
-         if (!f1 || !f2)
-           warning ("%s `%s' does not fully implement the `%s' protocol",
-                    type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
-
+         f1 = check_methods (PROTOCOL_CLS_METHODS (p),
+                             CLASS_CLS_METHODS (implementation_context),
+                             '+');
+         f2 = check_methods (PROTOCOL_NST_METHODS (p),
+                             CLASS_NST_METHODS (implementation_context),
+                             '-');
        }
       else
-        {
-         ; /* An identifier if we could not find a protocol.  */
-        }
+       {
+         f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
+                                        implementation_context,
+                                        '+');
+         f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
+                                        implementation_context,
+                                        '-');
+       }
 
-      /* Check protocols recursively.  */
-      if (PROTOCOL_LIST (p))
+      if (!f1 || !f2)
+       warning ("%s `%s' does not fully implement the `%s' protocol",
+                type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+    }
+    
+  /* Check protocols recursively.  */
+  if (PROTOCOL_LIST (p))
+    {
+      tree subs = PROTOCOL_LIST (p);
+      tree super_class =
+       lookup_interface (CLASS_SUPER_NAME (implementation_template));
+      while (subs) 
        {
-         tree super_class
-           = lookup_interface (CLASS_SUPER_NAME (implementation_template));
-         if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
-           check_protocols (PROTOCOL_LIST (p), type, name);
+         tree sub = TREE_VALUE (subs);
+
+         /* If the superclass does not conform to the protocols
+            inherited by P, then we must!  */
+         if (!super_class || !conforms_to_protocol (super_class, sub))
+           check_protocol (sub, type, name);
+         subs = TREE_CHAIN (subs);
        }
     }
 }
+       
+/* Check whether the current interface (accessible via
+   'implementation_context') actually implements the protocols listed
+   in PROTO_LIST.  */
+   
+static void
+check_protocols (proto_list, type, name)
+     tree proto_list;
+     const char *type;
+     const char *name;
+{
+  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
+    {
+      tree p = TREE_VALUE (proto_list);
+
+      check_protocol (p, type, name);
+    }
+}
 \f
 /* Make sure that the class CLASS_NAME is defined
    CODE says which kind of thing CLASS_NAME ought to be.
@@ -6430,6 +6498,33 @@ lookup_protocol (ident)
   return NULL_TREE;
 }
 
+/* This function forward declares the protocols named by NAMES.  If
+   they are already declared or defined, the function has no effect.  */
+
+void
+objc_declare_protocols (names)
+     tree names;
+{
+  tree list;
+
+  for (list = names; list; list = TREE_CHAIN (list))
+    {
+      tree name = TREE_VALUE (list);
+
+      if (lookup_protocol (name) == NULL_TREE)
+       {
+         tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
+
+         TYPE_BINFO (protocol) = make_tree_vec (2);
+         PROTOCOL_NAME (protocol) = name;
+         PROTOCOL_LIST (protocol) = NULL_TREE;
+         add_protocol (protocol);
+         PROTOCOL_DEFINED (protocol) = 0;
+         PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
+       }
+    }
+}
+
 tree
 start_protocol (code, name, list)
      enum tree_code code;
@@ -6438,26 +6533,38 @@ start_protocol (code, name, list)
 {
   tree protocol;
 
-  /* This is as good a place as any.  Need to invoke push_tag_toplevel.  */
+  /* This is as good a place as any.  Need to invoke
+     push_tag_toplevel.  */
   if (!objc_protocol_template)
     objc_protocol_template = build_protocol_template ();
 
-  protocol = make_node (code);
-  TYPE_BINFO (protocol) = make_tree_vec (2);
+  protocol = lookup_protocol (name);
 
-  PROTOCOL_NAME (protocol) = name;
-  PROTOCOL_LIST (protocol) = list;
+  if (!protocol)
+    {
+      protocol = make_node (code);
+      TYPE_BINFO (protocol) = make_tree_vec (2);
 
-  lookup_and_install_protocols (list);
+      PROTOCOL_NAME (protocol) = name;
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
+      add_protocol (protocol);
+      PROTOCOL_DEFINED (protocol) = 1;
+      PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
 
-  if (lookup_protocol (name))
-    warning ("duplicate declaration for protocol `%s'",
-          IDENTIFIER_POINTER (name));
-  else
-    add_protocol (protocol);
-
-  PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
+      check_protocol_recursively (protocol, list);
+    }
+  else if (! PROTOCOL_DEFINED (protocol))
+    {
+      PROTOCOL_DEFINED (protocol) = 1;
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
 
+      check_protocol_recursively (protocol, list);
+    }
+  else
+    {
+      warning ("duplicate declaration for protocol `%s'",
+              IDENTIFIER_POINTER (name));
+    }
   return protocol;
 }
 
@@ -6595,6 +6702,11 @@ encode_aggregate_within (type, curtype, format, left, right)
      int left;
      int right;
 {
+  /* The RECORD_TYPE may in fact be a typedef!  For purposes
+     of encoding, we need the real underlying enchilada.  */
+  if (TYPE_MAIN_VARIANT (type))
+    type = TYPE_MAIN_VARIANT (type);
+
   if (obstack_object_size (&util_obstack) > 0
       && *(obstack_next_free (&util_obstack) - 1) == '^')
     {
index f13acc8f1927b60fe39b056d851f2a8f1c1e761c..e659f916525ebef23b5755a60458134e2f4af879 100644 (file)
@@ -1,5 +1,5 @@
 /* Declarations for objc-act.c.
-   Copyright (C) 1990, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1990, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -59,6 +59,7 @@ extern tree objc_ellipsis_node;
 
 void objc_declare_alias                                PARAMS ((tree, tree));
 void objc_declare_class                                PARAMS ((tree));
+void objc_declare_protocols                    PARAMS ((tree));
 
 extern int objc_receiver_context;
 
@@ -101,6 +102,7 @@ tree build_encode_expr                              PARAMS ((tree));
 #define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
 #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 TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context)
 
 /* Define the Objective-C or Objective-C++ language-specific tree codes.  */