OSDN Git Service

*** empty log message ***
authorrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 16 Mar 1992 04:38:38 +0000 (04:38 +0000)
committerrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 16 Mar 1992 04:38:38 +0000 (04:38 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@497 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/objc/objc-act.c

index 3e525cf..558b064 100644 (file)
@@ -36,7 +36,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  *
  *      code generation `options':
  *
- *      - OBJC_INT_SELECTORS, OBJC_NONUNIQUE_SELECTORS
+ *      - OBJC_INT_SELECTORS, OBJC_NONUNIQUE_SELECTORS, NEXT_OBJC_RUNTIME
  */
 
 #include <stdio.h>
@@ -203,13 +203,12 @@ static void dump_interfaces ();
 
 /* some commonly used instances of "identifier_node". */
 
-static tree self_id, _cmd_id, _msg_id, _msgSuper_id;
-static tree objc_getClass_id, objc_getMetaClass_id;
+static tree self_id, _cmd_id;
 
 static tree self_decl, _msg_decl, _msgSuper_decl;
 static tree objc_getClass_decl, objc_getMetaClass_decl;
 
-static tree super_type, _selector_type, id_type, class_type;
+static tree super_type, selector_type, id_type, class_type;
 static tree instance_type;
 
 static tree interface_chain = NULLT;
@@ -267,9 +266,6 @@ static tree objc_symtab_template, objc_module_template;
 static tree objc_super_template, objc_object_reference;
 
 static tree objc_object_id, objc_class_id;
-#ifdef OBJC_NONUNIQUE_SELECTORS
-static tree _OBJC_SELECTOR_REFERENCES_id;
-#endif
 static tree _OBJC_SUPER_decl;
 
 static tree method_context = NULLT;
@@ -475,6 +471,27 @@ get_static_reference (interface)
   return xref_tag (RECORD_TYPE, CLASS_NAME (interface));
 }
 
+/* Create and push a decl for a built-in external variable or field NAME.
+   CODE says which.
+   TYPE is its data type.  */
+
+static tree
+create_builtin_decl (code, type, name)
+     enum tree_code code;
+     char *name;
+     tree type;
+{
+  tree decl = build_decl (code, get_identifier (name), type);
+  if (code == VAR_DECL)
+    {
+      TREE_EXTERNAL (decl) = 1;
+      TREE_PUBLIC (decl) = 1;
+      make_decl_rtl (decl, 0, 1);
+      pushdecl (decl);
+    }
+  return decl;
+}
+
 /*
  *     purpose: "play" parser, creating/installing representations
  *              of the declarations that are required by Objective-C.
@@ -490,138 +507,68 @@ get_static_reference (interface)
 static void
 synth_module_prologue ()
 {
-  tree sc_spec, type_spec, decl_specs, expr_decl, parms, record;
+  tree expr_decl, temp_type;
 
   /* defined in `objc.h' */
   objc_object_id = get_identifier (TAG_OBJECT);
 
   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
 
-  id_type = groktypename (build_tree_list (
-                                          build_tree_list (NULLT, objc_object_reference),
-                                          build1 (INDIRECT_REF, NULLT, NULLT)));
+  id_type = build_pointer_type (objc_object_reference);
 
   objc_class_id = get_identifier (TAG_CLASS);
   
-  class_type = groktypename (build_tree_list
-                            (build_tree_list
-                             (NULLT, xref_tag (RECORD_TYPE, objc_class_id)),
-                             build1 (INDIRECT_REF, NULLT, NULLT)));
+  class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
 
-/* Declare SEL type before prototypes for objc_msgSend(), or else those
-   struct tags are considered local to the prototype and won't match the one
-   in <objc/objc-runtime.h>. */
+  /* Declare type of selector-objects that represent an operation name.  */
 
 #ifdef OBJC_INT_SELECTORS
   /* `unsigned int' */
-  _selector_type = unsigned_type_node;
+  selector_type = unsigned_type_node;
 #else
   /* `struct objc_selector *' */
-  _selector_type = groktypename (build_tree_list (
-            build_tree_list (NULLT,
-                             xref_tag (RECORD_TYPE,
-                                       get_identifier (TAG_SELECTOR))),
-            build1 (INDIRECT_REF, NULLT, NULLT)));
+  selector_type
+    = build_pointer_type (xref_tag (RECORD_TYPE,
+                                   get_identifier (TAG_SELECTOR)));
 #endif /* not OBJC_INT_SELECTORS */
 
-  /* forward declare type...or else the prototype for `super' will bitch */
-  groktypename (build_tree_list (build_tree_list (NULLT,
-                                                 xref_tag (RECORD_TYPE, get_identifier (TAG_SUPER))),
-                                build1 (INDIRECT_REF, NULLT, NULLT)));
-
-  _msg_id = get_identifier ("objc_msgSend");
-  _msgSuper_id = get_identifier ("objc_msgSendSuper");
-  objc_getClass_id = get_identifier ("objc_getClass");
-  objc_getMetaClass_id = get_identifier ("objc_getMetaClass");
-
   /* struct objc_object *objc_msgSend (id, SEL, ...); */
-  pushlevel (0);
-  decl_specs = build_tree_list (NULLT, objc_object_reference);
-  push_parm_decl (build_tree_list (decl_specs,
-                                  build1 (INDIRECT_REF, NULLT, NULLT)));
-
-#ifdef OBJC_INT_SELECTORS
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
-  expr_decl = NULLT;
-#else
-  decl_specs = build_tree_list (NULLT,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier (TAG_SELECTOR)));
-  expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
-#endif /* not OBJC_INT_SELECTORS */
 
-  push_parm_decl (build_tree_list (decl_specs, expr_decl));
-  parms = get_parm_info (0);
-  poplevel (0, 0, 0);
+  temp_type
+    = build_function_type (id_type,
+                          tree_cons (NULL_TREE, id_type,
+                                     tree_cons (NULLT, selector_type, NULLT)));
 
-  decl_specs = build_tree_list (NULLT, objc_object_reference);
-  expr_decl = build_nt (CALL_EXPR, _msg_id, parms, NULLT);
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
+  _msg_decl = builtin_function ("objc_msgSend", temp_type, NOT_BUILT_IN, 0);
 
-  _msg_decl = define_decl (expr_decl, decl_specs);
+  /* struct objc_object *objc_msgSendSuper (void *, SEL, ...); */
 
-  /* struct objc_object *objc_msgSendSuper (struct objc_super *, SEL, ...); */
-  pushlevel (0);
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                get_identifier (TAG_SUPER)));
-  push_parm_decl (build_tree_list (decl_specs,
-                                  build1 (INDIRECT_REF, NULLT, NULLT)));
+  temp_type
+    = build_function_type (id_type,
+                          tree_cons (NULL_TREE, ptr_type_node,
+                                     tree_cons (NULLT, selector_type, NULLT)));
 
-#ifdef OBJC_INT_SELECTORS
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
-  expr_decl = NULLT;
-#else /* not OBJC_INT_SELECTORS */
-  decl_specs = build_tree_list (NULLT,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier (TAG_SELECTOR)));
-  expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
-#endif /* not OBJC_INT_SELECTORS */
-
-  push_parm_decl (build_tree_list (decl_specs, expr_decl));
-  parms = get_parm_info (0);
-  poplevel (0, 0, 0);
-
-  decl_specs = build_tree_list (NULLT, objc_object_reference);
-  expr_decl = build_nt (CALL_EXPR, _msgSuper_id, parms, NULLT);
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
-
-  _msgSuper_decl = define_decl (expr_decl, decl_specs);
+  _msgSuper_decl = builtin_function ("objc_msgSendSuper",
+                                    temp_type, NOT_BUILT_IN, 0);
 
   /* id objc_getClass (); */
-  parms = build_tree_list (NULLT, NULLT);
-  expr_decl = build_nt (CALL_EXPR, objc_getClass_id, parms, NULLT);
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
+  
+  temp_type = build_function_type (id_type, NULLT);
 
-  objc_getClass_decl = define_decl (expr_decl, decl_specs);
+  objc_getClass_decl
+    = builtin_function ("objc_getClass", temp_type, NOT_BUILT_IN, 0);
 
   /* id objc_getMetaClass (); */
-  parms = build_tree_list (NULLT, NULLT);
-  expr_decl = build_nt (CALL_EXPR, objc_getMetaClass_id, parms, NULLT);
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
 
-  objc_getMetaClass_decl = define_decl (expr_decl, decl_specs);
-
-#ifdef OBJC_NONUNIQUE_SELECTORS
-  _OBJC_SELECTOR_REFERENCES_id = get_identifier ("_OBJC_SELECTOR_REFERENCES");
+  objc_getMetaClass_decl
+    = builtin_function ("objc_getMetaClass", temp_type, NOT_BUILT_IN, 0);
 
   /* extern SEL _OBJC_SELECTOR_REFERENCES[]; */
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
-  
-#ifdef OBJC_INT_SELECTORS
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], sc_spec);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
-  expr_decl = _OBJC_SELECTOR_REFERENCES_id;
-#else  /* not OBJC_INT_SELECTORS */
-  decl_specs = build_tree_list (NULLT,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier (TAG_SELECTOR)));
-  expr_decl = build1 (INDIRECT_REF, NULLT, _OBJC_SELECTOR_REFERENCES_id);
-#endif /* not OBJC_INT_SELECTORS */
 
-  expr_decl = build_nt (ARRAY_REF, expr_decl, NULLT);
-  _OBJC_SELECTOR_REFERENCES_decl = define_decl (expr_decl, decl_specs);
+#ifdef OBJC_NONUNIQUE_SELECTORS
+  _OBJC_SELECTOR_REFERENCES_decl
+    = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
+                          "_OBJC_SELECTOR_REFERENCES");
 #endif
 }
 
@@ -650,73 +597,68 @@ my_build_string (len, str)
 
   return aString;
 }
+\f
+/* Take care of defining and initializing _OBJC_SYMBOLS.  */
+
+/* Predefine the following data type:
+
+       struct _objc_symtab {
+               long sel_ref_cnt;
+               SEL *refs;
+               short cls_def_cnt;
+               short cat_def_cnt;
+               void *defs[cls_def_cnt + cat_def_cnt];
+       }; */
 
-/*
- *     struct objc_symtab {
- *             long sel_ref_cnt;
- *             char *refs;
- *             long cls_def_cnt;
- *             long cat_def_cnt;
- *             void *defs[cls_def_cnt + cat_def_cnt];
- *     };
- */
 static void
 build_objc_symtab_template ()
 {
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain, index;
 
   objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (_TAG_SYMTAB));
 
   /* long sel_ref_cnt; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
-  field_decl = get_identifier ("sel_ref_cnt");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   long_integer_type_node,
+                                   "sel_ref_cnt");
   field_decl_chain = field_decl;
 
-#ifdef OBJC_INT_SELECTORS
-  /* unsigned int *sel_ref; */
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("refs"));
-#else /* not OBJC_INT_SELECTORS */
-  /* struct objc_selector **sel_ref; */
-  decl_specs = build_tree_list (NULLT,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier (TAG_SELECTOR)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("refs"));
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
-#endif /* not OBJC_INT_SELECTORS */
+  /* SEL *refs; */
 
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   build_pointer_type (selector_type),
+                                   "refs");
   chainon (field_decl_chain, field_decl);
 
   /* short cls_def_cnt; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_SHORT]);
-  field_decl = get_identifier ("cls_def_cnt");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   short_integer_type_node,
+                                   "cls_def_cnt");
   chainon (field_decl_chain, field_decl);
 
   /* short cat_def_cnt; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_SHORT]);
-  field_decl = get_identifier ("cat_def_cnt");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   short_integer_type_node,
+                                   "cat_def_cnt");
   chainon (field_decl_chain, field_decl);
 
   /* void *defs[cls_def_cnt + cat_def_cnt]; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_VOID]);
-  field_decl = build_nt (ARRAY_REF, get_identifier ("defs"),
-                        build_int_2 (imp_count + cat_count, 0));
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  index = build_index_type (build_int_2 (imp_count + cat_count - 1, 0));
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   build_array_type (ptr_type_node, index),
+                                   "defs");
   chainon (field_decl_chain, field_decl);
 
   finish_struct (objc_symtab_template, field_decl_chain);
 }
 
+/* Create the initial value for the `defs' field of _objc_symtab.
+   This is a CONSTRUCTOR.  */
+
 static tree
 init_def_list ()
 {
@@ -745,15 +687,8 @@ init_def_list ()
   return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
 }
 
-/*
- *     struct objc_symtab {
- *             long sel_ref_cnt;
- *             char *refs;
- *             long cls_def_cnt;
- *             long cat_def_cnt;
- *             void *defs[cls_def_cnt + cat_def_cnt];
- *     };
- */
+/* Construct the initial value for all of _objc_symtab.  */
+
 static tree
 init_objc_symtab ()
 {
@@ -793,6 +728,9 @@ init_objc_symtab ()
   return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
 }
 
+/* Push forward-declarations of all the categories
+   so that init_def_list can use them in a CONSTRUCTOR.  */
+
 static void
 forward_declare_categories ()
 {
@@ -802,20 +740,19 @@ forward_declare_categories ()
     {
       if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
        {
-         tree sc_spec, decl_specs, decl;
-
-         sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
-         decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
-
+         /* Set an invisible arg to synth_id_with_class_suffix.  */
          implementation_context = impent->imp_context;
-         impent->class_decl = define_decl (
-                                           synth_id_with_class_suffix ("_OBJC_CATEGORY"),
-                                           decl_specs);
+         impent->class_decl
+           = create_builtin_decl (VAR_DECL, objc_category_template,
+                                  synth_id_with_class_suffix ("_OBJC_CATEGORY"));
        }
     }
   implementation_context = sav;
 }
 
+/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
+   and initialized appropriately.  */
+
 static void
 generate_objc_symtab_decl ()
 {
@@ -838,7 +775,7 @@ generate_objc_symtab_decl ()
 
   finish_decl (_OBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
 }
-
+\f
 /*
  *     tree_node------->tree_node----->...
  *          |                |
@@ -1133,7 +1070,7 @@ build_selector_reference (idx)
     decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */
   else 
     {
-      decl = build_decl (VAR_DECL, ident, _selector_type);
+      decl = build_decl (VAR_DECL, ident, selector_type);
       TREE_EXTERNAL (decl) = 1;
       TREE_PUBLIC (decl) = 1;
       TREE_USED (decl) = 1;
@@ -1153,7 +1090,7 @@ init_selector (offset)
      int offset;
 {
   tree expr = build_msg_pool_reference (offset);
-  TREE_TYPE (expr) = _selector_type; /* cast */
+  TREE_TYPE (expr) = selector_type; /* cast */
   return expr;
 }
 
@@ -1167,7 +1104,9 @@ build_selector_translation_table ()
   tree decl, var_decl;
   int idx = 0;
   char buf[256];
-#else/
+#else
+  tree _OBJC_SELECTOR_REFERENCES_id
+    = get_identifier ("_OBJC_SELECTOR_REFERENCES");
 
   sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
 
@@ -2506,19 +2445,14 @@ build_method_decl (code, ret_type, selector, add_args)
 
 #define METHOD_DEF 0
 #define METHOD_REF 1
-/*
- * used by `build_message_expr' and `comp_method_types'.
- *
- * add_args is a tree_list node the following info on a parameter list:
- *
- *    The TREE_PURPOSE is a chain of decls of those parms.
- *    The TREE_VALUE is a list of structure, union and enum tags defined.
- *    The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
- *    This tree_list node is later fed to `grokparms'.
- *
- *    VOID_AT_END nonzero means append `void' to the end of the type-list.
- *    Zero means the parmlist ended with an ellipsis so don't append `void'.
- */
+/* Used by `build_message_expr' and `comp_method_types'.
+   Return an argument list for method METH.
+   CONTEXT is either METHOD_DEF or METHOD_REF,
+    saying whether we are trying to define a method or call one.
+   SUPERFLAG says this is for a send to super;
+    this makes a difference for the NeXT calling sequence
+    in which the lookup and the method call are done together.  */
+
 static tree
 get_arg_type_list (meth, context, superflag)
      tree meth;
@@ -2527,10 +2461,14 @@ get_arg_type_list (meth, context, superflag)
 {
   tree arglist, akey;
 
+#ifdef NEXT_OBJC_RUNTIME
   /* receiver type */
   if (superflag)
-    arglist = build_tree_list (NULLT, super_type);
+    {
+      arglist = build_tree_list (NULLT, super_type);
+    }
   else
+#endif
     {
       if (context == METHOD_DEF)
        arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
@@ -2539,7 +2477,7 @@ get_arg_type_list (meth, context, superflag)
     }
 
   /* selector type - will eventually change to `int' */
-  chainon (arglist, build_tree_list (NULLT, _selector_type));
+  chainon (arglist, build_tree_list (NULLT, selector_type));
 
   /* build a list of argument types */
   for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
@@ -2616,11 +2554,11 @@ receiver_is_class_object (receiver)
 
          if (arg != 0
              && TREE_CODE (arg) == TREE_LIST
-             && arg = TREE_VALUE (arg)
+             && (arg = TREE_VALUE (arg))
              && TREE_CODE (arg) == NOP_EXPR
-             && arg = TREE_OPERAND (arg, 0)
+             && (arg = TREE_OPERAND (arg, 0))
              && TREE_CODE (arg) == ADDR_EXPR
-             && arg = TREE_OPERAND (arg, 0)
+             && (arg = TREE_OPERAND (arg, 0))
              && TREE_CODE (arg) == STRING_CST)
            /* finally, we have the class name */
            return get_identifier (TREE_STRING_POINTER (arg));
@@ -4166,7 +4104,7 @@ really_start_method (method, parmlist)
 {
   tree sc_spec, ret_spec, ret_decl, decl_specs;
   tree method_decl, method_id;
-  char buf[256];
+  char *buf;
 
   /* synth the storage class & assemble the return type */
   sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
@@ -4174,28 +4112,41 @@ really_start_method (method, parmlist)
   decl_specs = chainon (sc_spec, ret_spec);
 
   if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
+    {
+      /* Make sure this is big enough for any plausible method label.  */
+      buf = (char *) alloca (50
+                            + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
+                            + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
 #ifdef OBJC_GEN_METHOD_LABEL
-    OBJC_GEN_METHOD_LABEL (buf,
-      TREE_CODE (method) == INSTANCE_METHOD_DECL,
-      IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
-      NULL,
-      IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
+      OBJC_GEN_METHOD_LABEL (buf,
+                            TREE_CODE (method) == INSTANCE_METHOD_DECL,
+                            IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
+                            NULL,
+                            IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
 #else
-    sprintf (buf, "_%d_%s", ++method_slot,
-            IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
+      sprintf (buf, "_%d_%s", ++method_slot,
+              IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
 #endif
+    }
   else                         /* we have a category */
+    {
+      /* Make sure this is big enough for any plausible method label.  */
+      buf = (char *) alloca (50
+                            + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
+                            + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
+                            + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
 #ifdef OBJC_GEN_METHOD_LABEL
-    OBJC_GEN_METHOD_LABEL (buf,
-      TREE_CODE (method) == INSTANCE_METHOD_DECL,
-      IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
-      IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
-      IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
+      OBJC_GEN_METHOD_LABEL (buf,
+                            TREE_CODE (method) == INSTANCE_METHOD_DECL,
+                            IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
+                            IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
+                            IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
 #else
-    sprintf (buf, "_%d_%s_%s", ++method_slot,
-            IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
-            IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+      sprintf (buf, "_%d_%s_%s", ++method_slot,
+              IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
+              IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
 #endif
+    }
 
   method_id = get_identifier (buf);