OSDN Git Service

($(OBJC_O)): Also depend on $(GCC_PASSES).
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-act.c
index ec4cf3c..4e05b32 100644 (file)
@@ -1,6 +1,6 @@
 /* Implement classes and message passing for Objective C.
-   Copyright (C) 1992 Free Software Foundation, Inc.
-   Author: Steve Naroff.
+   Copyright (C) 1992, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+   Contributed by Steve Naroff.
 
 This file is part of GNU CC.
 
@@ -16,7 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* Purpose: This module implements the Objective-C 4.0 language.
 
@@ -45,22 +46,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "flags.h"
 #include "objc-act.h"
 #include "input.h"
+#include "except.h"
 #include "function.h"
 
+
 /* This is the default way of generating a method name.  */
 /* I am not sure it is really correct.
    Perhaps there's a danger that it will make name conflicts
    if method names contain underscores. -- rms.  */
 #ifndef OBJC_GEN_METHOD_LABEL
-#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM)       \
-  do {                                 \
-    char *temp;                                \
-    sprintf ((BUF), "_%s_%s_%s",       \
-            ((IS_INST) ? "i" : "c"),   \
-            (CLASS_NAME),              \
-            (SEL_NAME));               \
-    for (temp = (BUF); *temp; temp++)  \
-      if (*temp == ':') *temp = '_';   \
+#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
+  do {                                     \
+    char *temp;                                    \
+    sprintf ((BUF), "_%s_%s_%s_%s",        \
+            ((IS_INST) ? "i" : "c"),       \
+            (CLASS_NAME),                  \
+            ((CAT_NAME)? (CAT_NAME) : ""), \
+            (SEL_NAME));                   \
+    for (temp = (BUF); *temp; temp++)      \
+      if (*temp == ':') *temp = '_';       \
   } while (0)
 #endif
 
@@ -122,43 +126,55 @@ static struct obstack util_obstack;
    so we can free the whole contents.  */
 char *util_firstobj;
 
+/* List of classes with list of their static instances.  */
+static tree objc_static_instances = NULL_TREE;
+
+/* The declaration of the array administrating the static instances.  */
+static tree static_instances_decl = NULL_TREE;
+
 /* for encode_method_def */
 #include "rtl.h"
 #include "c-parse.h"
 
-#define OBJC_VERSION   5
+#define OBJC_VERSION   (flag_next_runtime ? 5 : 8)
 #define PROTOCOL_VERSION 2
 
-#define NULLT  (tree) 0
-
 #define OBJC_ENCODE_INLINE_DEFS        0
 #define OBJC_ENCODE_DONT_INLINE_DEFS   1
 
 /*** Private Interface (procedures) ***/
 
-/* used by compile_file */
+/* Used by compile_file.  */
 
 static void init_objc                          PROTO((void));
 static void finish_objc                                PROTO((void));
 
-/* code generation */
+/* Code generation.  */
 
 static void synth_module_prologue              PROTO((void));
+static tree build_constructor                  PROTO((tree, tree));
 static char *build_module_descriptor           PROTO((void));
-static tree init_module_descriptor             PROTO((void));
-static tree build_objc_method_call             PROTO((int, tree, tree, tree, tree, tree));
+static tree init_module_descriptor             PROTO((tree));
+static tree build_objc_method_call             PROTO((int, tree, tree,
+                                                      tree, tree, tree));
 static void generate_strings                   PROTO((void));
+static tree get_proto_encoding                         PROTO((tree));
 static void build_selector_translation_table   PROTO((void));
 static tree build_ivar_chain                   PROTO((tree, int));
 
+static tree objc_add_static_instance           PROTO((tree, tree));
+
 static tree build_ivar_template                        PROTO((void));
 static tree build_method_template              PROTO((void));
 static tree build_private_template             PROTO((tree));
 static void build_class_template               PROTO((void));
+static void build_selector_template            PROTO((void));
 static void build_category_template            PROTO((void));
 static tree build_super_template               PROTO((void));
-static tree build_category_initializer         PROTO((tree, tree, tree, tree, tree));
-static tree build_protocol_initializer         PROTO((tree, tree, tree, tree));
+static tree build_category_initializer         PROTO((tree, tree, tree,
+                                                      tree, tree, tree));
+static tree build_protocol_initializer         PROTO((tree, tree, tree,
+                                                      tree, tree));
 
 static void synth_forward_declarations         PROTO((void));
 static void generate_ivar_lists                        PROTO((void));
@@ -172,7 +188,10 @@ static tree init_selector                  PROTO((int));
 static tree build_keyword_selector             PROTO((tree));
 static tree synth_id_with_class_suffix         PROTO((char *, tree));
 
-/* misc. bookkeeping */
+/* From expr.c */
+extern int apply_args_register_offset           PROTO((int));
+
+/* Misc. bookkeeping */
 
 typedef struct hashed_entry    *hash;
 typedef struct hashed_attribute  *attr;
@@ -203,20 +222,22 @@ enum string_section
 {
   class_names,         /* class, category, protocol, module names */
   meth_var_names,      /* method and variable names */
-  meth_var_types,      /* method and variable type descriptors */
+  meth_var_types       /* method and variable type descriptors */
 };
 
-static tree add_objc_string                    PROTO((tree, enum string_section));
-static tree build_objc_string_decl             PROTO((tree, enum string_section));
+static tree add_objc_string                    PROTO((tree,
+                                                      enum string_section));
+static tree build_objc_string_decl             PROTO((tree,
+                                                      enum string_section));
 static tree build_selector_reference_decl      PROTO((tree));
 
-/* protocol additions */
+/* Protocol additions.  */
 
 static tree add_protocol                       PROTO((tree));
 static tree lookup_protocol                    PROTO((tree));
 static tree lookup_and_install_protocols       PROTO((tree));
 
-/* type encoding */
+/* Type encoding.  */
 
 static void encode_type_qualifiers             PROTO((tree));
 static void encode_pointer                     PROTO((tree, int, int));
@@ -232,7 +253,7 @@ static int comp_proto_with_proto            PROTO((tree, tree));
 static tree get_arg_type_list                  PROTO((tree, int, int));
 static tree expr_last                          PROTO((tree));
 
-/* utilities for debugging and error diagnostics: */
+/* Utilities for debugging and error diagnostics.  */
 
 static void warn_with_method                   PROTO((char *, int, tree));
 static void error_with_ivar                    PROTO((char *, tree, tree));
@@ -243,27 +264,29 @@ static int is_complex_decl                        PROTO((tree));
 static void adorn_decl                         PROTO((tree, char *));
 static void dump_interface                     PROTO((FILE *, tree));
 
-/* everything else. */
+/* Everything else.  */
 
 static void objc_fatal                         PROTO((void));
 static tree define_decl                                PROTO((tree, tree));
 static tree lookup_method_in_protocol_list     PROTO((tree, tree, int));
 static tree lookup_protocol_in_reflist         PROTO((tree, tree));
-static tree create_builtin_decl                        PROTO((enum tree_code, tree, char *));
+static tree create_builtin_decl                        PROTO((enum tree_code,
+                                                      tree, char *));
 static tree my_build_string                    PROTO((int, char *));
 static void build_objc_symtab_template         PROTO((void));
-static tree init_def_list                      PROTO((void));
-static tree init_objc_symtab                   PROTO((void));
+static tree init_def_list                      PROTO((tree));
+static tree init_objc_symtab                   PROTO((tree));
 static void forward_declare_categories         PROTO((void));
 static void generate_objc_symtab_decl          PROTO((void));
 static tree build_selector                     PROTO((tree));
 static tree build_msg_pool_reference           PROTO((int));
+static tree build_typed_selector_reference             PROTO((tree, tree));
 static tree build_selector_reference           PROTO((tree));
 static tree build_class_reference_decl         PROTO((tree));
 static void add_class_reference                        PROTO((tree));
 static tree objc_copy_list                     PROTO((tree, tree *));
 static tree build_protocol_template            PROTO((void));
-static tree build_descriptor_table_initializer PROTO((tree, int *));
+static tree build_descriptor_table_initializer PROTO((tree, tree));
 static tree build_method_prototype_list_template PROTO((tree, int));
 static tree build_method_prototype_template    PROTO((void));
 static int forwarding_offset                   PROTO((tree));
@@ -277,11 +300,15 @@ static void generate_protocols                    PROTO((void));
 static void check_ivars                                PROTO((tree, tree));
 static tree build_ivar_list_template           PROTO((tree, int));
 static tree build_method_list_template         PROTO((tree, int));
-static tree build_ivar_list_initializer                PROTO((tree, int *));
-static tree generate_ivars_list                        PROTO((tree, char *, int, tree));
-static tree build_dispatch_table_initializer   PROTO((tree, int *));
-static tree generate_dispatch_table            PROTO((tree, char *, int, tree));
-static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, int, tree, tree, tree));
+static tree build_ivar_list_initializer                PROTO((tree, tree));
+static tree generate_ivars_list                        PROTO((tree, char *,
+                                                      int, tree));
+static tree build_dispatch_table_initializer   PROTO((tree, tree));
+static tree generate_dispatch_table            PROTO((tree, char *,
+                                                      int, tree));
+static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
+                                                      tree, int, tree, tree,
+                                                      tree));
 static void generate_category                  PROTO((tree));
 static int is_objc_type_qualifier              PROTO((tree));
 static tree adjust_type_for_id_default         PROTO((tree));
@@ -297,7 +324,7 @@ static void handle_class_ref                        PROTO((tree));
 
 /*** Private Interface (data) ***/
 
-/* reserved tag definitions: */
+/* Reserved tag definitions.  */
 
 #define TYPE_ID                        "id"
 #define TAG_OBJECT             "objc_object"
@@ -312,8 +339,10 @@ static void handle_class_ref                       PROTO((tree));
 #define UTAG_METHOD_LIST       "_objc_method_list"
 #define UTAG_CATEGORY          "_objc_category"
 #define UTAG_MODULE            "_objc_module"
+#define UTAG_STATICS           "_objc_statics"
 #define UTAG_SYMTAB            "_objc_symtab"
 #define UTAG_SUPER             "_objc_super"
+#define UTAG_SELECTOR          "_objc_selector"
 
 #define UTAG_PROTOCOL          "_objc_protocol"
 #define UTAG_PROTOCOL_LIST     "_objc_protocol_list"
@@ -323,11 +352,11 @@ static void handle_class_ref                      PROTO((tree));
 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
 
-static charTAG_GETCLASS;
-static charTAG_GETMETACLASS;
-static charTAG_MSGSEND;
-static charTAG_MSGSENDSUPER;
-static charTAG_EXECCLASS;
+static char *TAG_GETCLASS;
+static char *TAG_GETMETACLASS;
+static char *TAG_MSGSEND;
+static char *TAG_MSGSENDSUPER;
+static char *TAG_EXECCLASS;
 
 /* Set by `continue_class' and checked by `is_public'.  */
 
@@ -338,6 +367,7 @@ static char* TAG_EXECCLASS;
 /* Some commonly used instances of "identifier_node".  */
 
 static tree self_id, ucmd_id;
+static tree unused_list;
 
 static tree self_decl, umsg_decl, umsg_super_decl;
 static tree objc_get_class_decl, objc_get_meta_class_decl;
@@ -354,28 +384,29 @@ static tree instance_type, protocol_type;
 #define IS_SUPER(TYPE) \
   (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
 
-static tree class_chain = NULLT;
-static tree alias_chain = NULLT;
-static tree interface_chain = NULLT;
-static tree protocol_chain = NULLT;
+static tree class_chain = NULL_TREE;
+static tree alias_chain = NULL_TREE;
+static tree interface_chain = NULL_TREE;
+static tree protocol_chain = NULL_TREE;
 
-/* chains to manage selectors that are referenced and defined in the module */
+/* Chains to manage selectors that are referenced and defined in the
+   module.  */
 
-static tree cls_ref_chain = NULLT;     /* classes referenced */
-static tree sel_ref_chain = NULLT;     /* selectors referenced */
+static tree cls_ref_chain = NULL_TREE; /* Classes referenced.  */
+static tree sel_ref_chain = NULL_TREE; /* Selectors referenced.  */
 
-/* chains to manage uniquing of strings */
+/* Chains to manage uniquing of strings.  */
 
-static tree class_names_chain = NULLT;
-static tree meth_var_names_chain = NULLT;
-static tree meth_var_types_chain = NULLT;
+static tree class_names_chain = NULL_TREE;
+static tree meth_var_names_chain = NULL_TREE;
+static tree meth_var_types_chain = NULL_TREE;
 
-/* hash tables to manage the global pool of method prototypes */
+/* Hash tables to manage the global pool of method prototypes.  */
 
 static hash *nst_method_hash_list = 0;
 static hash *cls_method_hash_list = 0;
 
-/* backend data declarations */
+/* Backend data declarations.  */
 
 static tree UOBJC_SYMBOLS_decl;
 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
@@ -390,8 +421,8 @@ static tree UOBJC_STRINGS_decl;
    none exists this will be equal to implementation_context...it is
    set in start_class.  */
 
-static tree implementation_context = NULLT,
-           implementation_template = NULLT;
+static tree implementation_context = NULL_TREE;
+static tree implementation_template = NULL_TREE;
 
 struct imp_entry
 {
@@ -409,7 +440,7 @@ static int imp_count = 0;   /* `@implementation' */
 static int cat_count = 0;      /* `@category' */
 
 static tree objc_class_template, objc_category_template, uprivate_record;
-static tree objc_protocol_template;
+static tree objc_protocol_template, objc_selector_template;
 static tree ucls_super_ref, uucls_super_ref;
 
 static tree objc_method_template, objc_ivar_template;
@@ -421,18 +452,18 @@ static tree constant_string_id;
 static tree constant_string_type;
 static tree UOBJC_SUPER_decl;
 
-static tree method_context = NULLT;
-static int  method_slot = 0;   /* used by start_method_def */
+static tree method_context = NULL_TREE;
+static int  method_slot = 0;   /* Used by start_method_def, */
 
 #define BUFSIZE                1024
 
-static char *errbuf;   /* a buffer for error diagnostics */
+static char *errbuf;   /* Buffer for error diagnostics */
 
-/* data imported from tree.c */
+/* Data imported from tree.c.  */
 
-extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
+extern enum debug_info_type write_symbols;
 
-/* data imported from toplev.c  */
+/* Data imported from toplev.c.  */
 
 extern char *dump_base_name;
 \f
@@ -444,6 +475,8 @@ int flag_next_runtime = 1;
 int flag_next_runtime = 0;
 #endif
 
+int flag_typed_selectors;
+
 /* Open and close the file for outputting class declarations, if requested.  */
 
 int flag_gen_declaration = 0;
@@ -451,7 +484,7 @@ int flag_gen_declaration = 0;
 FILE *gen_declaration_file;
 
 /* Warn if multiple methods are seen for the same selector, but with
-   different argument types. */
+   different argument types.  */
 
 int warn_selector = 0;
 
@@ -461,22 +494,28 @@ int warn_selector = 0;
 
 int flag_warn_protocol = 1;
 
-/* tells "encode_pointer/encode_aggregate" whether we are generating
+/* Tells "encode_pointer/encode_aggregate" whether we are generating
    type descriptors for instance variables (as opposed to methods).
    Type descriptors for instance variables contain more information
    than methods (for static typing and embedded structures). This
-   was added to support features being planned for dbkit2. */
+   was added to support features being planned for dbkit2.  */
 
 static int generating_instance_variables = 0;
 
 void
 lang_init ()
 {
-  /* the beginning of the file is a new line; check for # */
-  /* With luck, we discover the real source file's name from that
+  /* The beginning of the file is a new line; check for #.
+     With luck, we discover the real source file's name from that
      and put it in input_filename.  */
   ungetc (check_newline (), finput);
 
+  /* The line number can be -1 if we had -g3 and the input file
+     had a directive specifying line 0.  But we want predefined
+     functions to have a line number of 0, not -1.  */
+  if (lineno == -1)
+    lineno = 0;
+
   /* If gen_declaration desired, open the output file.  */
   if (flag_gen_declaration)
     {
@@ -504,6 +543,7 @@ lang_init ()
       TAG_MSGSEND = "objc_msg_lookup";
       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
       TAG_EXECCLASS = "__objc_exec_class";
+      flag_typed_selectors = 1;
     }
 
   if (doing_objc_thang)
@@ -517,7 +557,7 @@ objc_fatal ()
 }
 
 void
-objc_finish ()
+finish_file ()
 {
   if (doing_objc_thang)
     finish_objc ();            /* Objective-C finalization */
@@ -572,8 +612,8 @@ define_decl (declarator, declspecs)
      tree declarator;
      tree declspecs;
 {
-  tree decl = start_decl (declarator, declspecs, 0);
-  finish_decl (decl, NULLT, NULLT);
+  tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
+  finish_decl (decl, NULL_TREE, NULL_TREE);
   return decl;
 }
 
@@ -614,19 +654,21 @@ lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
 
        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);
+           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.  */
+         ; /* An identifier...if we could not find a protocol.  */
 
        if (fnd)
          return fnd;
      }
+
    return 0;
 }
 
@@ -637,29 +679,29 @@ lookup_protocol_in_reflist (rproto_list, lproto)
 {
    tree rproto, p;
 
-   /* make sure the protocol is support by the object on the rhs */
+   /* Make sure the protocol is support by the object on the rhs.  */
    if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
      {
-     tree fnd = 0;
-     for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
-       {
-          p = TREE_VALUE (rproto);
+       tree fnd = 0;
+       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+        {
+          p = TREE_VALUE (rproto);
 
-         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
-           {
-           if (lproto == p)
-             fnd = lproto;
+          if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+            {
+              if (lproto == p)
+                fnd = lproto;
 
-           else if (PROTOCOL_LIST (p))
-             fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
-           }
+              else if (PROTOCOL_LIST (p))
+                fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
+            }
 
-         if (fnd)
-           return fnd;
-       }
+          if (fnd)
+            return fnd;
+        }
      }
    else
-     ; /* an identifier...if we could not find a protocol. */
+     ; /* An identifier...if we could not find a protocol.  */
 
    return 0;
 }
@@ -675,7 +717,7 @@ objc_comptypes (lhs, rhs, reflexive)
      tree rhs;
      int reflexive;
 {
-  /* new clause for protocols */
+  /* New clause for protocols.  */
 
   if (TREE_CODE (lhs) == POINTER_TYPE
       && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
@@ -727,8 +769,7 @@ objc_comptypes (lhs, rhs, reflexive)
                      rproto_list = CLASS_PROTOCOL_LIST (rinter);
                      rproto = lookup_protocol_in_reflist (rproto_list, p);
 
-                     /* NEW!!! */
-                     /* Check for protocols adopted by categories. */
+                     /* Check for protocols adopted by categories.  */
                      cat = CLASS_CATEGORY_LIST (rinter);
                      while (cat && !rproto)
                        {
@@ -740,6 +781,7 @@ objc_comptypes (lhs, rhs, reflexive)
 
                      rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
                    }
+
                  if (!rproto)
                    warning ("class `%s' does not implement the `%s' protocol",
                             IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
@@ -747,26 +789,23 @@ objc_comptypes (lhs, rhs, reflexive)
                }
            }
 
-          return 1; /* may change...based on whether there was any mismatch */
+         /* May change...based on whether there was any mismatch */
+          return 1;
         }
       else if (rhs_is_proto)
-        {
-         /* lhs is not a protocol...warn if it is statically typed */
+       /* Lhs is not a protocol...warn if it is statically typed */
+       return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
 
-         if (TYPED_OBJECT (TREE_TYPE (lhs)))
-           return 0;
-         else
-           return 1;   /* one of the types is a protocol */
-       }
       else
-       return -1;      /* defer to comptypes */
+       /* Defer to comptypes .*/
+       return -1;
     }
+
   else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
-    ; /* fall thru...this is the case we have been handling all along */
+    ; /* Fall thru.  This is the case we have been handling all along */
   else
-    return -1; /* defer to comptypes */
-
-  /* End of new protocol support.  */
+    /* Defer to comptypes.  */
+    return -1;
 
   /* `id' = `<class> *', `<class> *' = `id' */
 
@@ -810,7 +849,8 @@ objc_comptypes (lhs, rhs, reflexive)
       return 0;
     }
   else
-    return -1; /* defer to comptypes */
+    /* Defer to comptypes.  */
+    return -1;
 }
 
 /* Called from c-decl.c before all calls to rest_of_decl_compilation.  */
@@ -850,18 +890,17 @@ get_static_reference (interface, protocols)
   if (protocols)
     {
       tree t, m = TYPE_MAIN_VARIANT (type);
-      struct obstack *ambient_obstack = current_obstack;
 
-      current_obstack = &permanent_obstack;
+      push_obstacks_nochange ();
+      end_temporary_allocation ();
       t = copy_node (type);
       TYPE_BINFO (t) = make_tree_vec (2);
+      pop_obstacks ();
 
       /* Add this type to the chain of variants of TYPE.  */
       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
       TYPE_NEXT_VARIANT (m) = t;
 
-      current_obstack = ambient_obstack;
-
       /* Look up protocols and install in lang specific list.  */
       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
 
@@ -869,7 +908,7 @@ get_static_reference (interface, protocols)
         (in build_pointer_type)...so that the new template
         we just created will actually be used...what a hack!  */
       if (TYPE_POINTER_TO (t))
-       TYPE_POINTER_TO (t) = NULL;
+       TYPE_POINTER_TO (t) = 0;
 
       type = t;
     }
@@ -892,29 +931,27 @@ get_object_reference (protocols)
                gen_declaration (type, errbuf));
     }
   else
-    {
-      fatal ("Undefined type `id', please import <objc/objc.h>");
-    }
+    fatal ("Undefined type `id', please import <objc/objc.h>");
 
   /* This clause creates a new pointer type that is qualified with
      the protocol specification...this info is used later to do more
      elaborate type checking.  */
+
   if (protocols)
     {
       tree t, m = TYPE_MAIN_VARIANT (type);
-      struct obstack *ambient_obstack = current_obstack;
 
-      current_obstack = &permanent_obstack;
+      push_obstacks_nochange ();
+      end_temporary_allocation ();
       t = copy_node (type);
       TYPE_BINFO (t) = make_tree_vec (2);
+      pop_obstacks ();
 
       /* Add this type to the chain of variants of TYPE.  */
       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
       TYPE_NEXT_VARIANT (m) = t;
 
-      current_obstack = ambient_obstack;
-
-      /* look up protocols...and install in lang specific list */
+      /* Look up protocols...and install in lang specific list */
       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
 
       /* This forces a new pointer type to be created later
@@ -952,11 +989,12 @@ lookup_and_install_protocols (protocols)
        }
       else
        {
-         /* replace identifier with actual protocol node */
+         /* Replace identifier with actual protocol node.  */
          TREE_VALUE (proto) = p;
          prev = proto;
        }
     }
+
   return return_value;
 }
 
@@ -971,19 +1009,22 @@ create_builtin_decl (code, type, name)
      char *name;
 {
   tree decl = build_decl (code, get_identifier (name), type);
+
   if (code == VAR_DECL)
     {
       TREE_STATIC (decl) = 1;
       make_decl_rtl (decl, 0, 1);
       pushdecl (decl);
     }
+
+  DECL_ARTIFICIAL (decl) = 1;
   return decl;
 }
 
-/* purpose: "play" parser, creating/installing representations
+/* Purpose: "play" parser, creating/installing representations
    of the declarations that are required by Objective-C.
 
-   model:
+   Model:
 
        type_spec--------->sc_spec
        (tree_list)        (tree_list)
@@ -997,7 +1038,7 @@ synth_module_prologue ()
   tree temp_type;
   tree super_p;
 
-  /* defined in `objc.h' */
+  /* Defined in `objc.h' */
   objc_object_id = get_identifier (TAG_OBJECT);
 
   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
@@ -1035,15 +1076,17 @@ synth_module_prologue ()
   temp_type
     = build_function_type (id_type,
                           tree_cons (NULL_TREE, id_type,
-                                     tree_cons (NULLT, selector_type, NULLT)));
+                                     tree_cons (NULL_TREE, selector_type,
+                                                NULL_TREE)));
 
   if (! flag_next_runtime)
     {
       umsg_decl = build_decl (FUNCTION_DECL,
                              get_identifier (TAG_MSGSEND), temp_type);
       DECL_EXTERNAL (umsg_decl) = 1;
-      TREE_PUBLIC (umsg_decl) = 0;
+      TREE_PUBLIC (umsg_decl) = 1;
       DECL_INLINE (umsg_decl) = 1;
+      DECL_ARTIFICIAL (umsg_decl) = 1;
 
       if (flag_traditional && TAG_MSGSEND[0] != '_')
        DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
@@ -1059,7 +1102,8 @@ synth_module_prologue ()
   temp_type
     = build_function_type (id_type,
                           tree_cons (NULL_TREE, super_p,
-                                     tree_cons (NULLT, selector_type, NULLT)));
+                                     tree_cons (NULL_TREE, selector_type,
+                                                NULL_TREE)));
 
   umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
                                     temp_type, NOT_BUILT_IN, 0);
@@ -1067,9 +1111,10 @@ synth_module_prologue ()
   /* id objc_getClass (const char *); */
 
   temp_type = build_function_type (id_type,
-                       tree_cons (NULLT,
+                       tree_cons (NULL_TREE,
                                   const_string_type_node,
-                                  tree_cons (NULLT, void_type_node, NULLT)));
+                                  tree_cons (NULL_TREE, void_type_node,
+                                             NULL_TREE)));
 
   objc_get_class_decl
     = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
@@ -1082,9 +1127,30 @@ synth_module_prologue ()
   /* static SEL _OBJC_SELECTOR_TABLE[]; */
 
   if (! flag_next_runtime)
-    UOBJC_SELECTOR_TABLE_decl
-      = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
-                            "_OBJC_SELECTOR_TABLE");
+    {
+      if (flag_typed_selectors)
+       {
+         /* Suppress outputting debug symbols, because
+            dbxout_init hasn'r been called yet.  */
+         enum debug_info_type save_write_symbols = write_symbols;
+         write_symbols = NO_DEBUG;
+
+         build_selector_template ();
+         temp_type = build_array_type (objc_selector_template, NULL_TREE);
+
+         write_symbols = save_write_symbols;
+       }
+      else
+       temp_type = build_array_type (selector_type, NULL_TREE);
+
+      layout_type (temp_type);
+      UOBJC_SELECTOR_TABLE_decl
+       = create_builtin_decl (VAR_DECL, temp_type,
+                              "_OBJC_SELECTOR_TABLE");
+
+      /* Avoid warning when not sending messages.  */
+      TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
+    }
 
   generate_forward_declaration_to_string_table ();
 
@@ -1102,15 +1168,16 @@ my_build_string (len, str)
 {
   int wide_flag = 0;
   tree a_string = build_string (len, str);
+
   /* Some code from combine_strings, which is local to c-parse.y.  */
   if (TREE_TYPE (a_string) == int_array_type_node)
     wide_flag = 1;
 
-  TREE_TYPE (a_string) =
-    build_array_type (wide_flag ? integer_type_node : char_type_node,
-                     build_index_type (build_int_2 (len - 1, 0)));
+  TREE_TYPE (a_string)
+    build_array_type (wide_flag ? integer_type_node : char_type_node,
+                       build_index_type (build_int_2 (len - 1, 0)));
 
-  TREE_CONSTANT (a_string) = 1;        /* puts string in the ".text" segment */
+  TREE_CONSTANT (a_string) = 1;        /* Puts string in the readonly segment */
   TREE_STATIC (a_string) = 1;
 
   return a_string;
@@ -1132,11 +1199,11 @@ build_objc_string (len, str)
 }
 
 /* Given a chain of OBJC_STRING_CST's, build a static instance of
-   NXConstantString which points at the concatenation of those strings.
+   NXConstanString which points at the concatenation of those strings.
    We place the string object in the __string_objects section of the
    __OBJC segment.  The Objective-C runtime will initialize the isa
-   pointers of the string objects to point at the NXConstantString
-   class object.  */
+   pointers of the string objects to point at the NXConstandString class
+   object.  */
 
 tree
 build_objc_string_object (strings)
@@ -1148,33 +1215,105 @@ build_objc_string_object (strings)
   if (!doing_objc_thang)
     objc_fatal ();
 
-  if (lookup_interface (constant_string_id) == NULLT)
+  if (lookup_interface (constant_string_id) == NULL_TREE)
     {
       error ("Cannot find interface declaration for `%s'",
-              IDENTIFIER_POINTER (constant_string_id));
+            IDENTIFIER_POINTER (constant_string_id));
       return error_mark_node;
     }
 
   add_class_reference (constant_string_id);
 
-  /* combine_strings will work for OBJC_STRING_CST's too.  */
+  /* Combine_strings will work for OBJC_STRING_CST's too.  */
   string = combine_strings (strings);
   TREE_SET_CODE (string, STRING_CST);
   length = TREE_STRING_LENGTH (string) - 1;
 
+  if (! flag_next_runtime)
+    {
+      push_obstacks_nochange ();
+      end_temporary_allocation ();
+      if (! TREE_PERMANENT (strings))
+       string = my_build_string (length + 1,
+                                 TREE_STRING_POINTER (string));
+    }
+
   /* & ((NXConstantString) {0, string, length})  */
 
-  initlist = build_tree_list (NULLT, build_int_2 (0, 0));
-  initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
-                       initlist);
-  initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
-  constructor = build (CONSTRUCTOR, constant_string_type, NULLT,
-                      nreverse (initlist));
+  initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+  initlist
+    = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
+                initlist);
+  initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
+  constructor = build_constructor (constant_string_type, nreverse (initlist));
+
+  if (!flag_next_runtime)
+    {
+      constructor
+       = objc_add_static_instance (constructor, constant_string_type);
+      pop_obstacks ();
+    }
+
+  return (build_unary_op (ADDR_EXPR, constructor, 1));
+}
+
+/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
+
+static tree
+objc_add_static_instance (constructor, class_decl)
+     tree constructor, class_decl;
+{
+  static int num_static_inst;
+  tree *chain, decl, decl_spec, decl_expr;
+  char buf[256];
+
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
+
+  /* Find the list of static instances for the CLASS_DECL.  Create one if
+     not found.  */
+  for (chain = &objc_static_instances;
+       *chain && TREE_VALUE (*chain) != class_decl;
+       chain = &TREE_CHAIN (*chain));
+  if (!*chain)
+    {
+      *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
+      add_objc_string (TYPE_NAME (class_decl), class_names);
+    }
+
+  sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
+  decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
+  DECL_COMMON (decl) = 1;
+  TREE_STATIC (decl) = 1;
+  DECL_ARTIFICIAL (decl) = 1;
+  pushdecl_top_level (decl);
+  rest_of_decl_compilation (decl, 0, 1, 0);
+
+  /* Do this here so it gets output later instead of possibly
+     inside something else we are writing.  */
+  DECL_INITIAL (decl) = constructor;
+
+  /* Add the DECL to the head of this CLASS' list.  */
+  TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
+
+  pop_obstacks ();
+  return decl;
+}
+
+/* Build a static constant CONSTRUCTOR
+   with type TYPE and elements ELTS.  */
+
+static tree
+build_constructor (type, elts)
+     tree type, elts;
+{
+  tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
+
   TREE_CONSTANT (constructor) = 1;
   TREE_STATIC (constructor) = 1;
   TREE_READONLY (constructor) = 1;
 
-  return build_unary_op (ADDR_EXPR, constructor, 1);
+  return constructor;
 }
 \f
 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
@@ -1195,7 +1334,8 @@ build_objc_symtab_template ()
 {
   tree field_decl, field_decl_chain, index;
 
-  objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
+  objc_symtab_template
+    = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
 
   /* long sel_ref_cnt; */
 
@@ -1227,24 +1367,28 @@ build_objc_symtab_template ()
 
   /* void *defs[cls_def_cnt + cat_def_cnt]; */
 
-  index = build_index_type (build_int_2 (imp_count + cat_count - 1,
-                                        imp_count == 0 && cat_count == 0
-                                        ? -1 : 0));
+  if (!flag_next_runtime)
+    index = build_index_type (build_int_2 (imp_count + cat_count, 0));
+  else
+    index = build_index_type (build_int_2 (imp_count + cat_count - 1,
+                                          imp_count == 0 && cat_count == 0
+                                          ? -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);
+  finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
 }
 
 /* Create the initial value for the `defs' field of _objc_symtab.
    This is a CONSTRUCTOR.  */
 
 static tree
-init_def_list ()
+init_def_list (type)
+     tree type;
 {
-  tree expr, initlist = NULLT;
+  tree expr, initlist = NULL_TREE;
   struct imp_entry *impent;
 
   if (imp_count)
@@ -1253,7 +1397,7 @@ init_def_list ()
        if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
          {
            expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
-           initlist = tree_cons (NULLT, expr, initlist);
+           initlist = tree_cons (NULL_TREE, expr, initlist);
          }
       }
 
@@ -1263,44 +1407,69 @@ init_def_list ()
        if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
          {
            expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
-           initlist = tree_cons (NULLT, expr, initlist);
+           initlist = tree_cons (NULL_TREE, expr, initlist);
          }
       }
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+
+  if (!flag_next_runtime)
+    {
+      /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
+      tree expr;
+
+      if (static_instances_decl)
+       expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+      else
+       expr = build_int_2 (0, 0);
+
+      initlist = tree_cons (NULL_TREE, expr, initlist);
+    }
+
+  return build_constructor (type, nreverse (initlist));
 }
 
 /* Construct the initial value for all of _objc_symtab.  */
 
 static tree
-init_objc_symtab ()
+init_objc_symtab (type)
+     tree type;
 {
   tree initlist;
 
   /* sel_ref_cnt = { ..., 5, ... } */
 
-  initlist = build_tree_list (NULLT, build_int_2 (0, 0));
+  initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
 
   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
 
   if (flag_next_runtime || ! sel_ref_chain)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
-    initlist = tree_cons (NULLT, UOBJC_SELECTOR_TABLE_decl, initlist);
+    initlist = tree_cons (NULL_TREE,
+                         build_unary_op (ADDR_EXPR,
+                                         UOBJC_SELECTOR_TABLE_decl, 1),
+                         initlist);
 
   /* cls_def_cnt = { ..., 5, ... } */
 
-  initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
+  initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
 
   /* cat_def_cnt = { ..., 5, ... } */
 
-  initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
+  initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
 
   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
 
-  if (imp_count || cat_count)
-    initlist = tree_cons (NULLT, init_def_list (), initlist);
+  if (imp_count || cat_count || static_instances_decl)
+    {
+
+      tree field = TYPE_FIELDS (type);
+      field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+      initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
+                           initlist);
+    }
+
+  return build_constructor (type, nreverse (initlist));
 }
 
 /* Push forward-declarations of all the categories
@@ -1311,6 +1480,7 @@ forward_declare_categories ()
 {
   struct imp_entry *impent;
   tree sav = implementation_context;
+
   for (impent = imp_list; impent; impent = impent->next)
     {
       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
@@ -1343,36 +1513,42 @@ generate_objc_symtab_decl ()
   if (!objc_symtab_template)
     build_objc_symtab_template ();
 
-  sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
+  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
 
   UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
-                                  tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
+                                  tree_cons (NULL_TREE,
+                                             objc_symtab_template, sc_spec),
+                                  1,
+                                  NULL_TREE, NULL_TREE);
 
-  end_temporary_allocation (); /* start_decl trying to be smart about inits */
   TREE_USED (UOBJC_SYMBOLS_decl) = 1;
   DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
-  finish_decl (UOBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
+  DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
+  finish_decl (UOBJC_SYMBOLS_decl,
+              init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
+              NULL_TREE);
 }
 \f
 static tree
-init_module_descriptor ()
+init_module_descriptor (type)
+     tree type;
 {
   tree initlist, expr;
 
   /* version = { 1, ... } */
 
   expr = build_int_2 (OBJC_VERSION, 0);
-  initlist = build_tree_list (NULLT, expr);
+  initlist = build_tree_list (NULL_TREE, expr);
 
   /* size = { ..., sizeof (struct objc_module), ... } */
 
   expr = size_in_bytes (objc_module_template);
-  initlist = tree_cons (NULLT, expr, initlist);
+  initlist = tree_cons (NULL_TREE, expr, initlist);
 
   /* name = { ..., "foo.m", ... } */
 
   expr = add_objc_string (get_identifier (input_filename), class_names);
-  initlist = tree_cons (NULLT, expr, initlist);
+  initlist = tree_cons (NULL_TREE, expr, initlist);
 
   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
 
@@ -1380,9 +1556,9 @@ init_module_descriptor ()
     expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
   else
     expr = build_int_2 (0, 0);
-  initlist = tree_cons (NULLT, expr, initlist);
+  initlist = tree_cons (NULL_TREE, expr, initlist);
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (type, nreverse (initlist));
 }
 
 /* Write out the data structures to describe Objective C classes defined.
@@ -1391,67 +1567,73 @@ init_module_descriptor ()
    the Objective C data structures for this file (and perhaps for other files
    also).
 
-   struct objc_module { ... } _OBJC_MODULE = { ... };
-
-*/
+   struct objc_module { ... } _OBJC_MODULE = { ... };   */
 
 static char *
 build_module_descriptor ()
 {
   tree decl_specs, field_decl, field_decl_chain;
 
-  objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
+  objc_module_template
+    = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
 
-  /* long version; */
+  /* Long version; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
   field_decl = get_identifier ("version");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* long  size; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
   field_decl = get_identifier ("size");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* char  *name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_symtab *symtab; */
 
   decl_specs = get_identifier (UTAG_SYMTAB);
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_module_template, field_decl_chain);
+  finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
 
-  /* create an instance of "objc_module" */
+  /* Create an instance of "objc_module".  */
 
-  decl_specs = tree_cons (NULLT, objc_module_template,
-                         build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
+  decl_specs = tree_cons (NULL_TREE, objc_module_template,
+                         build_tree_list (NULL_TREE,
+                                          ridpointers[(int) RID_STATIC]));
 
   UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
-                                  decl_specs, 1);
+                                  decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  end_temporary_allocation (); /* start_decl trying to be smart about inits */
+  DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
   DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
-  finish_decl (UOBJC_MODULES_decl, init_module_descriptor (), NULLT);
+  finish_decl (UOBJC_MODULES_decl,
+              init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
+              NULL_TREE);
 
-  /* Mark the decl to avoid "defined but not used" warning. */
+  /* Mark the decl to avoid "defined but not used" warning.  */
   DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
 
   /* Generate a constructor call for the module descriptor.
      This code was generated by reading the grammar rules
-     of c-parse.y;  Therefore, it may not be the most efficient
-     way of generating the requisite code. */
+     of c-parse.in;  Therefore, it may not be the most efficient
+     way of generating the requisite code.  */
 
   if (flag_next_runtime)
     return 0;
@@ -1459,49 +1641,10 @@ build_module_descriptor ()
   {
     tree parms, function_decl, decelerator, void_list_node;
     tree function_type;
-    char *buf;
-    char *global_object_name = 0;
-    tree t;
-
-    /* Use a global object (which is already required to be unique over
-       the program) rather than the file name (which imposes extra
-       constraints).  -- Raeburn@MIT.EDU, 10 Jan 1990.  */
-
-    /* Find the name of some global object defined in this file.  */
-    for (t = getdecls (); t; t = TREE_CHAIN (t))
-      if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
-       {
-         global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
-         break;
-       }
+    extern tree get_file_function_name ();
+    tree init_function_name = get_file_function_name ('I');
 
-    /* If none, use the name of the file.  */
-    if (!global_object_name)
-      {
-       char *p, *q;
-       global_object_name
-         = (char *) alloca (strlen (main_input_filename) + 1);
-
-       p = main_input_filename;
-       q = global_object_name;
-
-       /* Replace any weird characters in the file name.  */
-       for (; *p; p++)
-         if (! ((*p >= '0' && *p <= '9')
-                || (*p >= 'A' && *p <= 'Z')
-                || (*p >= 'a' && *p <= 'z')))
-           *q++ = '_';
-         else
-           *q++ = *p;
-       *q = 0;
-      }
-
-    /* Make the constructor name from the name we have found.  */
-    buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
-                           + strlen (global_object_name));
-    sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
-
-    /* Declare void __objc_execClass (void*); */
+    /* Declare void __objc_execClass (void *); */
 
     void_list_node = build_tree_list (NULL_TREE, void_type_node);
     function_type
@@ -1512,25 +1655,27 @@ build_module_descriptor ()
                                get_identifier (TAG_EXECCLASS),
                                function_type);
     DECL_EXTERNAL (function_decl) = 1;
+    DECL_ARTIFICIAL (function_decl) = 1;
     TREE_PUBLIC (function_decl) = 1;
+
     pushdecl (function_decl);
     rest_of_decl_compilation (function_decl, 0, 0, 0);
 
     parms
-      = build_tree_list (NULLT,
+      = build_tree_list (NULL_TREE,
                         build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
     decelerator = build_function_call (function_decl, parms);
 
     /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);}  */
 
     start_function (void_list_node,
-                   build_parse_node (CALL_EXPR, get_identifier (buf),
+                   build_parse_node (CALL_EXPR, init_function_name,
                                      /* This has the format of the output
                                         of get_parm_info.  */
                                      tree_cons (NULL_TREE, NULL_TREE,
                                                 void_list_node),
                                      NULL_TREE),
-                   0);
+                   NULL_TREE, NULL_TREE, 0);
 #if 0 /* This should be turned back on later
         for the systems where collect is not needed.  */
     /* Make these functions nonglobal
@@ -1543,10 +1688,13 @@ build_module_descriptor ()
     assemble_external (function_decl);
     c_expand_expr_stmt (decelerator);
 
+    TREE_PUBLIC (current_function_decl) = 1;
+
+    function_decl = current_function_decl;
     finish_function (0);
 
     /* Return the name of the constructor function.  */
-    return buf;
+    return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
   }
 }
 
@@ -1557,15 +1705,118 @@ generate_forward_declaration_to_string_table ()
 {
   tree sc_spec, decl_specs, expr_decl;
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
 
-  expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
+  expr_decl
+    = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
 
   UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
 }
 
-/* Output all strings. */
+/* Return the DECL of the string IDENT in the SECTION.  */
+
+static tree
+get_objc_string_decl (ident, section)
+     tree ident;
+     enum string_section section;
+{
+  tree chain, decl;
+
+  if (section == class_names)
+    chain = class_names_chain;
+  else if (section == meth_var_names)
+    chain = meth_var_names_chain;
+  else if (section == meth_var_types)
+    chain = meth_var_types_chain;
+
+  for (; chain != 0; chain = TREE_VALUE (chain))
+    if (TREE_VALUE (chain) == ident)
+      return (TREE_PURPOSE (chain));
+
+  abort ();
+  return NULL_TREE;
+}
+
+/* Output references to all statically allocated objects.  Return the DECL
+   for the array built.  */
+
+static tree
+generate_static_references ()
+{
+  tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
+  tree class_name, class, decl, instance, idecl, initlist;
+  tree cl_chain, in_chain, type;
+  int num_inst, num_class;
+  char buf[256];
+
+  if (flag_next_runtime)
+    abort ();
+
+  for (cl_chain = objc_static_instances, num_class = 0;
+       cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
+    {
+      for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
+          in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
+
+      sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
+      ident = get_identifier (buf);
+
+      expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
+      decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
+                            build_tree_list (NULL_TREE,
+                                             ridpointers[(int) RID_STATIC]));
+      decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+      DECL_CONTEXT (decl) = 0;
+      DECL_ARTIFICIAL (decl) = 1;
+
+      /* Output {class_name, ...}.  */
+      class = TREE_VALUE (cl_chain);
+      class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
+      initlist = build_tree_list (NULL_TREE,
+                                 build_unary_op (ADDR_EXPR, class_name, 1));
+
+      /* Output {..., instance, ...}.  */
+      for (in_chain = TREE_PURPOSE (cl_chain);
+          in_chain; in_chain = TREE_CHAIN (in_chain))
+       {
+         expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
+         initlist = tree_cons (NULL_TREE, expr, initlist);
+       }
+
+      /* Output {..., NULL}.  */
+      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
+      expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+      finish_decl (decl, expr, NULL_TREE);
+      TREE_USED (decl) = 1;
+
+      type = build_array_type (build_pointer_type (void_type_node), 0);
+      decl = build_decl (VAR_DECL, ident, type);
+      make_decl_rtl (decl, 0, 1);
+      TREE_USED (decl) = 1;
+      decls
+       = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
+    }
+
+  decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
+  ident = get_identifier ("_OBJC_STATIC_INSTANCES");
+  expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
+  decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
+                        build_tree_list (NULL_TREE,
+                                         ridpointers[(int) RID_STATIC]));
+  static_instances_decl
+    = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+  TREE_USED (static_instances_decl) = 1;
+  DECL_CONTEXT (static_instances_decl) = 0;
+  DECL_ARTIFICIAL (static_instances_decl) = 1;
+  end_temporary_allocation ();
+  expr = build_constructor (TREE_TYPE (static_instances_decl),
+                           nreverse (decls));
+  finish_decl (static_instances_decl, expr, NULL_TREE);
+}
+
+/* Output all strings.  */
 
 static void
 generate_strings ()
@@ -1578,42 +1829,43 @@ generate_strings ()
     {
       string = TREE_VALUE (chain);
       decl = TREE_PURPOSE (chain);
-      sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-      decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
-      decl = start_decl (expr_decl, decl_specs, 1);
+      sc_spec
+       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
       end_temporary_allocation ();
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
-                               IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULLT);
+                                    IDENTIFIER_POINTER (string));
+      finish_decl (decl, string_expr, NULL_TREE);
     }
 
   for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
     {
       string = TREE_VALUE (chain);
       decl = TREE_PURPOSE (chain);
-      sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-      decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
-      decl = start_decl (expr_decl, decl_specs, 1);
-      end_temporary_allocation ();
+      sc_spec
+       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
-                               IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULLT);
+                                    IDENTIFIER_POINTER (string));
+      finish_decl (decl, string_expr, NULL_TREE);
     }
 
   for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
     {
       string = TREE_VALUE (chain);
       decl = TREE_PURPOSE (chain);
-      sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-      decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
-      decl = start_decl (expr_decl, decl_specs, 1);
-      end_temporary_allocation ();
+      sc_spec
+       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULLT);
+      finish_decl (decl, string_expr, NULL_TREE);
     }
 }
 
@@ -1623,14 +1875,13 @@ build_selector_reference_decl (name)
 {
   tree decl, ident;
   char buf[256];
-  struct obstack *save_current_obstack = current_obstack;
-  struct obstack *save_rtl_obstack = rtl_obstack;
   static int idx = 0;
 
   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
 
-  /* new stuff */
-  rtl_obstack = current_obstack = &permanent_obstack;
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
+
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, selector_type);
@@ -1638,12 +1889,13 @@ build_selector_reference_decl (name)
   TREE_PUBLIC (decl) = 1;
   TREE_USED (decl) = 1;
   TREE_READONLY (decl) = 1;
+  DECL_ARTIFICIAL (decl) = 1;
+  DECL_CONTEXT (decl) = 0;
 
-  make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
-  pushdecl_top_level (decl);  /* our `extended/custom' pushdecl in c-decl.c */
+  make_decl_rtl (decl, 0, 1);
+  pushdecl_top_level (decl);
 
-  current_obstack = save_current_obstack;
-  rtl_obstack = save_rtl_obstack;
+  pop_obstacks ();
 
   return decl;
 }
@@ -1655,8 +1907,10 @@ build_selector (ident)
      tree ident;
 {
   tree expr = add_objc_string (ident, meth_var_names);
-
-  return build_c_cast (selector_type, expr); /* cast! */
+  if (flag_typed_selectors)
+    return expr;
+  else
+    return build_c_cast (selector_type, expr); /* cast! */
 }
 
 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
@@ -1674,8 +1928,9 @@ build_msg_pool_reference (offset)
   expr = build_array_ref (UOBJC_STRINGS_decl, expr);
   expr = build_unary_op (ADDR_EXPR, expr, 0);
 
-  cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
-                         build1 (INDIRECT_REF, NULLT, NULLT));
+  cast = build_tree_list (build_tree_list (NULL_TREE,
+                                          ridpointers[(int) RID_CHAR]),
+                         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
   TREE_TYPE (expr) = groktypename (cast);
   return expr;
 }
@@ -1685,7 +1940,7 @@ init_selector (offset)
      int offset;
 {
   tree expr = build_msg_pool_reference (offset);
-  TREE_TYPE (expr) = selector_type; /* cast */
+  TREE_TYPE (expr) = selector_type;
   return expr;
 }
 
@@ -1693,7 +1948,7 @@ static void
 build_selector_translation_table ()
 {
   tree sc_spec, decl_specs;
-  tree chain, initlist = NULLT;
+  tree chain, initlist = NULL_TREE;
   int offset = 0;
   tree decl, var_decl, name;
 
@@ -1712,28 +1967,37 @@ build_selector_translation_table ()
        {
          name = DECL_NAME (TREE_PURPOSE (chain));
 
-         sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
+         sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
 
          /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
-         decl_specs = tree_cons (NULLT, selector_type, sc_spec);
+         decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
 
          var_decl = name;
 
-         /* the `decl' that is returned from start_decl is the one that we
+         /* The `decl' that is returned from start_decl is the one that we
             forward declared in `build_selector_reference'  */
-         decl = start_decl (var_decl, decl_specs, 1);
+         decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
        }
 
       /* add one for the '\0' character */
       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
 
       if (flag_next_runtime)
+       finish_decl (decl, expr, NULL_TREE);
+      else 
        {
-         end_temporary_allocation ();
-         finish_decl (decl, expr, NULLT);
+         if (flag_typed_selectors)
+           {
+             tree eltlist = NULL_TREE;
+             tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
+             eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
+             eltlist = tree_cons (NULL_TREE, encoding, eltlist);
+             expr = build_constructor (objc_selector_template,
+                                       nreverse (eltlist));
+           }
+         initlist = tree_cons (NULL_TREE, expr, initlist);
+         
        }
-      else
-       initlist = tree_cons (NULLT, expr, initlist);
     }
 
   if (! flag_next_runtime)
@@ -1741,23 +2005,77 @@ build_selector_translation_table ()
       /* Cause the variable and its initial value to be actually output.  */
       DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
       TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
-      /* NULL terminate the list and fix the decl for output. */
-      initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+      /* NULL terminate the list and fix the decl for output.  */
+      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
       DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
-      initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
-      finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
+      initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
+                                   nreverse (initlist));
+      finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
+      current_function_decl = NULL_TREE;
+    }
+}
+
+static tree
+get_proto_encoding (proto)
+     tree proto;
+{
+  tree encoding;
+  if (proto)
+    {
+      tree tmp_decl;
+
+      if (! METHOD_ENCODING (proto))
+       {
+           tmp_decl = build_tmp_function_decl ();
+           hack_method_prototype (proto, tmp_decl);
+           encoding = encode_method_prototype (proto, tmp_decl);
+           METHOD_ENCODING (proto) = encoding;
+         }
+      else
+       encoding = METHOD_ENCODING (proto);
+
+      return add_objc_string (encoding, meth_var_types);
     }
+  else
+    return build_int_2 (0, 0);
 }
 
 /* sel_ref_chain is a list whose "value" fields will be instances of
    identifier_node that represent the selector.  */
 
 static tree
+build_typed_selector_reference (ident, proto)
+     tree ident, proto;
+{
+  tree *chain = &sel_ref_chain;
+  tree expr;
+  int index = 0;
+
+  while (*chain)
+    {
+      if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
+       goto return_at_index;
+
+      index++;
+      chain = &TREE_CHAIN (*chain);
+    }
+
+  *chain = perm_tree_cons (proto, ident, NULL_TREE);
+
+ return_at_index:
+  expr = build_unary_op (ADDR_EXPR,
+                        build_array_ref (UOBJC_SELECTOR_TABLE_decl,
+                                         build_int_2 (index, 0)),
+                        1);
+  return build_c_cast (selector_type, expr);
+}
+
+static tree
 build_selector_reference (ident)
      tree ident;
 {
   tree *chain = &sel_ref_chain;
-  tree decl;
+  tree expr;
   int index = 0;
 
   while (*chain)
@@ -1772,12 +2090,12 @@ build_selector_reference (ident)
       chain = &TREE_CHAIN (*chain);
     }
 
-  decl = build_selector_reference_decl (ident);
+  expr = build_selector_reference_decl (ident);
 
-  *chain = perm_tree_cons (decl, ident, NULLT);
+  *chain = perm_tree_cons (expr, ident, NULL_TREE);
 
   return (flag_next_runtime
-         ? decl
+         ? expr
          : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
                             build_int_2 (index, 0)));
 }
@@ -1788,14 +2106,13 @@ build_class_reference_decl (name)
 {
   tree decl, ident;
   char buf[256];
-  struct obstack *save_current_obstack = current_obstack;
-  struct obstack *save_rtl_obstack = rtl_obstack;
   static int idx = 0;
 
   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
 
-  /* new stuff */
-  rtl_obstack = current_obstack = &permanent_obstack;
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
+
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, objc_class_type);
@@ -1803,12 +2120,13 @@ build_class_reference_decl (name)
   TREE_PUBLIC (decl) = 1;
   TREE_USED (decl) = 1;
   TREE_READONLY (decl) = 1;
+  DECL_CONTEXT (decl) = 0;
+  DECL_ARTIFICIAL (decl) = 1;
 
-  make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
-  pushdecl_top_level (decl);  /* our `extended/custom' pushdecl in c-decl.c */
+  make_decl_rtl (decl, 0, 1);
+  pushdecl_top_level (decl);
 
-  current_obstack = save_current_obstack;
-  rtl_obstack = save_rtl_obstack;
+  pop_obstacks ();
 
   return decl;
 }
@@ -1835,11 +2153,11 @@ add_class_reference (ident)
         }
       while (chain);
 
-      /* append to the end of the list */
-      TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
+      /* Append to the end of the list */
+      TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
     }
   else
-    cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
+    cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
 }
 
 /* Get a class reference, creating it if necessary.  Also create the
@@ -1859,11 +2177,12 @@ get_class_reference (ident)
          {
            if (! TREE_PURPOSE (*chain))
              TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
+
            return TREE_PURPOSE (*chain);
          }
 
       decl = build_class_reference_decl (ident);
-      *chain = perm_tree_cons (decl, ident, NULLT);
+      *chain = perm_tree_cons (decl, ident, NULL_TREE);
       return decl;
     }
   else
@@ -1872,7 +2191,7 @@ get_class_reference (ident)
 
       add_class_reference (ident);
 
-      params = build_tree_list (NULLT,
+      params = build_tree_list (NULL_TREE,
                                my_build_string (IDENTIFIER_LENGTH (ident) + 1,
                                                 IDENTIFIER_POINTER (ident)));
 
@@ -1881,14 +2200,14 @@ get_class_reference (ident)
     }
 }
 
-/* sel_refdef_chain is a list whose "value" fields will be instances
+/* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
    of identifier_node that represent the selector. It returns the
    offset of the selector from the beginning of the _OBJC_STRINGS
    pool. This offset is typically used by init_selector during code
    generation.
 
    For each string section we have a chain which maps identifier nodes
-   to decls for the strings. */
+   to decls for the strings.  */
 
 static tree
 add_objc_string (ident, section)
@@ -1907,16 +2226,16 @@ add_objc_string (ident, section)
   while (*chain)
     {
       if (TREE_VALUE (*chain) == ident)
-       return TREE_PURPOSE (*chain);
+       return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
 
       chain = &TREE_CHAIN (*chain);
     }
 
   decl = build_objc_string_decl (ident, section);
 
-  *chain = perm_tree_cons (decl, ident, NULLT);
+  *chain = perm_tree_cons (decl, ident, NULL_TREE);
 
-  return decl;
+  return build_unary_op (ADDR_EXPR, decl, 1);
 }
 
 static tree
@@ -1926,8 +2245,6 @@ build_objc_string_decl (name, section)
 {
   tree decl, ident;
   char buf[256];
-  struct obstack *save_current_obstack = current_obstack;
-  struct obstack *save_rtl_obstack = rtl_obstack;
   static int class_names_idx = 0;
   static int meth_var_names_idx = 0;
   static int meth_var_types_idx = 0;
@@ -1939,7 +2256,8 @@ build_objc_string_decl (name, section)
   else if (section == meth_var_types)
     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
 
-  rtl_obstack = current_obstack = &permanent_obstack;
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
@@ -1948,12 +2266,13 @@ build_objc_string_decl (name, section)
   TREE_USED (decl) = 1;
   TREE_READONLY (decl) = 1;
   TREE_CONSTANT (decl) = 1;
+  DECL_CONTEXT (decl) = 0;
+  DECL_ARTIFICIAL (decl) = 1;
+  make_decl_rtl (decl, 0, 1);
+  pushdecl_top_level (decl);
 
-  make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
-  pushdecl_top_level (decl);  /* our `extended/custom' pushdecl in c-decl.c */
-
-  current_obstack = save_current_obstack;
-  rtl_obstack = save_rtl_obstack;
+  pop_obstacks ();
 
   return decl;
 }
@@ -2000,7 +2319,7 @@ objc_declare_class (ident_list)
         {
          tree record = xref_tag (RECORD_TYPE, ident);
          TREE_STATIC_TEMPLATE (record) = 1;
-         class_chain = tree_cons (NULLT, ident, class_chain);
+         class_chain = tree_cons (NULL_TREE, ident, class_chain);
        }
     }
 }
@@ -2040,7 +2359,7 @@ lookup_interface (ident)
       if (ident == CLASS_NAME (chain))
        return chain;
     }
-  return NULLT;
+  return NULL_TREE;
 }
 
 static tree
@@ -2068,6 +2387,7 @@ objc_copy_list (list, head)
       newlist = chainon (newlist, tail);
       list = TREE_CHAIN (list);
     }
+
   *head = newlist;
   return tail;
 }
@@ -2104,13 +2424,15 @@ build_ivar_chain (interface, copy)
          error ("Cannot find interface declaration for `%s', superclass of `%s'",
                 IDENTIFIER_POINTER (super_name),
                 IDENTIFIER_POINTER (my_name));
-         exit (34);
+         exit (FATAL_EXIT_CODE);
         }
+
       if (super_interface == interface)
         {
           fatal ("Circular inheritance in interface declaration for `%s'",
                  IDENTIFIER_POINTER (super_name));
         }
+
       interface = super_interface;
       my_name = CLASS_NAME (interface);
       super_name = CLASS_SUPER_NAME (interface);
@@ -2151,19 +2473,24 @@ build_private_template (class)
 
       ivar_context = build_ivar_chain (class, 0);
 
-      finish_struct (uprivate_record, ivar_context);
+      finish_struct (uprivate_record, ivar_context, NULL_TREE);
 
       CLASS_STATIC_TEMPLATE (class) = uprivate_record;
 
       /* mark this record as class template - for class type checking */
       TREE_STATIC_TEMPLATE (uprivate_record) = 1;
     }
-  instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
-                                                build1 (INDIRECT_REF, NULLT, NULLT)));
+
+  instance_type
+    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+                                                     uprivate_record),
+                                    build1 (INDIRECT_REF, NULL_TREE,
+                                            NULL_TREE)));
+
   return ivar_context;
 }
 \f
-/* Begin code generation for protocols... */
+/* Begin code generation for protocols...  */
 
 /* struct objc_protocol {
      char *protocol_name;
@@ -2182,65 +2509,88 @@ build_protocol_template ()
 
   /* struct objc_class *isa; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
+  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
                                        get_identifier (UTAG_CLASS)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* char *protocol_name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_protocol **protocol_list; */
 
-  decl_specs = build_tree_list (NULLT, template);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, template);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method_list *instance_methods; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                       get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs
+    = build_tree_list (NULL_TREE,
+                      xref_tag (RECORD_TYPE,
+                                get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method_list *class_methods; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                       get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs
+    = build_tree_list (NULL_TREE,
+                      xref_tag (RECORD_TYPE,
+                                get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  return finish_struct (template, field_decl_chain);
+  return finish_struct (template, field_decl_chain, NULL_TREE);
 }
 
 static tree
-build_descriptor_table_initializer (entries, size)
+build_descriptor_table_initializer (type, entries)
+     tree type;
      tree entries;
-     int *size;
 {
-  tree initlist = NULLT;
+  tree initlist = NULL_TREE;
 
   do
     {
-      initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist);
+      tree eltlist = NULL_TREE;
 
-      initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist);
+      eltlist
+       = tree_cons (NULL_TREE,
+                    build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
+      eltlist
+       = tree_cons (NULL_TREE,
+                    add_objc_string (METHOD_ENCODING (entries),
+                                     meth_var_types),
+                    eltlist);
+
+      initlist
+       = tree_cons (NULL_TREE,
+                    build_constructor (type, nreverse (eltlist)), initlist);
 
-      (*size)++;
       entries = TREE_CHAIN (entries);
     }
   while (entries);
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (build_array_type (type, 0), nreverse (initlist));
 }
 
 /* struct objc_method_prototype_list {
@@ -2259,28 +2609,30 @@ build_method_prototype_list_template (list_type, size)
   tree objc_ivar_list_record;
   tree decl_specs, field_decl, field_decl_chain;
 
-  /* generate an unnamed struct definition */
+  /* Generate an unnamed struct definition.  */
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
+  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
 
   /* int method_count; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
   field_decl = get_identifier ("method_count");
 
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* struct objc_method method_list[]; */
 
-  decl_specs = build_tree_list (NULLT, list_type);
+  decl_specs = build_tree_list (NULL_TREE, list_type);
   field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
                         build_int_2 (size, 0));
 
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain);
+  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
 
   return objc_ivar_list_record;
 }
@@ -2291,33 +2643,41 @@ build_method_prototype_template ()
   tree proto_record;
   tree decl_specs, field_decl, field_decl_chain;
 
-  proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
+  proto_record
+    = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
 
 #ifdef OBJC_INT_SELECTORS
   /* unsigned int _cmd; */
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
+  decl_specs
+    = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
   field_decl = get_identifier ("_cmd");
 #else /* OBJC_INT_SELECTORS */
   /* struct objc_selector *_cmd; */
-  decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
-                         get_identifier (TAG_SELECTOR)), NULLT);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
+  decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
+                         get_identifier (TAG_SELECTOR)), NULL_TREE);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
 #endif /* OBJC_INT_SELECTORS */
 
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (proto_record, field_decl_chain);
+  finish_struct (proto_record, field_decl_chain, NULL_TREE);
 
   return proto_record;
 }
 
+/* True if last call to forwarding_offset yielded a register offset.  */
+static int offset_is_register;
+
 static int
 forwarding_offset (parm)
       tree parm;
@@ -2339,30 +2699,26 @@ forwarding_offset (parm)
        offset_in_bytes = 0;
 
       offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
+      offset_is_register = 0;
     }
-#ifdef OBJC_FORWARDING_REG_OFFSET
   else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
     {
       int regno = REGNO (DECL_INCOMING_RTL (parm));
-
-      offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG)
-                       + OBJC_FORWARDING_REG_OFFSET;
+      offset_in_bytes = apply_args_register_offset (regno);
+      offset_is_register = 1;
     }
-#endif /* OBJC_FORWARDING_REG_OFFSET */
   else
     return 0;
 
   /* This is the case where the parm is passed as an int or double
-      and it is converted to a char, short or float and stored back
-      in the parmlist.  In this case, describe the parm
-      with the variable's declared type, and adjust the address
-      if the least significant bytes (which we are using) are not
-      the first ones.  */
-#if BYTES_BIG_ENDIAN
-  if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
+     and it is converted to a char, short or float and stored back
+     in the parmlist.  In this case, describe the parm
+     with the variable's declared type, and adjust the address
+     if the least significant bytes (which we are using) are not
+     the first ones.  */
+  if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
     offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
                        - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
-#endif
 
   return offset_in_bytes;
 }
@@ -2379,15 +2735,15 @@ encode_method_prototype (method_decl, func_decl)
   char buf[40];
   tree result;
 
-  /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
+  /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
 
-  /* C type */
+  /* C type */
   encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
               obstack_object_size (&util_obstack),
               OBJC_ENCODE_INLINE_DEFS);
 
-  /* stack size */
+  /* Stack size.  */
   for (parms = DECL_ARGUMENTS (func_decl); parms;
        parms = TREE_CHAIN (parms))
     {
@@ -2395,7 +2751,7 @@ encode_method_prototype (method_decl, func_decl)
                      + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
                         / BITS_PER_UNIT));
 
-      if (parm_end > max_parm_end)
+      if (!offset_is_register && max_parm_end < parm_end)
        max_parm_end = parm_end;
     }
 
@@ -2406,24 +2762,29 @@ encode_method_prototype (method_decl, func_decl)
 
   user_args = METHOD_SEL_ARGS (method_decl);
 
-  /* argument types */
+  /* Argument types.  */
   for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
        parms = TREE_CHAIN (parms), i++)
     {
-      /* process argument qualifiers for user supplied arguments */
+      /* Process argument qualifiers for user supplied arguments.  */
       if (i > 1)
         {
          encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
          user_args = TREE_CHAIN (user_args);
        }
 
-      /* type */
+      /* Type.  */
       encode_type (TREE_TYPE (parms),
                   obstack_object_size (&util_obstack),
                   OBJC_ENCODE_INLINE_DEFS);
 
-      /* compute offset */
+      /* Compute offset.  */
       sprintf (buf, "%d", forwarding_offset (parms));
+
+      /* Indicate register.  */
+      if (offset_is_register)
+       obstack_1grow (&util_obstack, '+');
+      
       obstack_grow (&util_obstack, buf, strlen (buf));
     }
 
@@ -2443,17 +2804,17 @@ generate_descriptor_table (type, name, size, list, proto)
 {
   tree sc_spec, decl_specs, decl, initlist;
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-  decl_specs = tree_cons (NULLT, type, sc_spec);
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
 
   decl = start_decl (synth_id_with_class_suffix (name, proto),
-                               decl_specs, 1);
-  end_temporary_allocation ();
+                               decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  initlist = build_tree_list (NULLT, build_int_2 (size, 0));
-  initlist = tree_cons (NULLT, list, initlist);
+  initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
+  initlist = tree_cons (NULL_TREE, list, initlist);
 
-  finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
+  finish_decl (decl, build_constructor (type, nreverse (initlist)),
+              NULL_TREE);
 
   return decl;
 }
@@ -2470,26 +2831,28 @@ generate_method_descriptors (protocol)  /* generate_dispatch_tables */
   if (!objc_method_prototype_template)
     objc_method_prototype_template = build_method_prototype_template ();
 
-  cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                               get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
+  cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
+                               get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
+                         NULL_TREE);
   variable_length_type = groktypename (cast);
 
   chain = PROTOCOL_CLS_METHODS (protocol);
   if (chain)
     {
-      size = 0;
-
-      initlist = build_descriptor_table_initializer (chain, &size);
+      size = list_length (chain);
 
       method_list_template
        = build_method_prototype_list_template (objc_method_prototype_template,
                                                size);
 
+      initlist 
+       = build_descriptor_table_initializer (objc_method_prototype_template,
+                                             chain);
+
       UOBJC_CLASS_METHODS_decl
        = generate_descriptor_table (method_list_template,
                                     "_OBJC_PROTOCOL_CLASS_METHODS",
                                     size, initlist, protocol);
-      /* cast! */
       TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
     }
   else
@@ -2498,18 +2861,19 @@ generate_method_descriptors (protocol)  /* generate_dispatch_tables */
   chain = PROTOCOL_NST_METHODS (protocol);
   if (chain)
     {
-      size = 0;
-      initlist = build_descriptor_table_initializer (chain, &size);
+      size = list_length (chain);
 
       method_list_template
        = build_method_prototype_list_template (objc_method_prototype_template,
                                                size);
+      initlist
+       = build_descriptor_table_initializer (objc_method_prototype_template,
+                                             chain);
 
       UOBJC_INSTANCE_METHODS_decl
        = generate_descriptor_table (method_list_template,
                                     "_OBJC_PROTOCOL_INSTANCE_METHODS",
                                     size, initlist, protocol);
-      /* cast! */
       TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
     }
   else
@@ -2520,24 +2884,31 @@ static tree
 build_tmp_function_decl ()
 {
   tree decl_specs, expr_decl, parms;
+  static int xxx = 0;
+  char buffer[80];
 
   /* struct objc_object *objc_xxx (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)));
-
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
+  decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+  push_parm_decl (build_tree_list
+                 (build_tree_list (decl_specs,
+                                   build1 (INDIRECT_REF, NULL_TREE,
+                                           NULL_TREE)),
+                  build_tree_list (NULL_TREE, NULL_TREE)));
+
+  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
                                          get_identifier (TAG_SELECTOR)));
-  expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
+  expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
 
-  push_parm_decl (build_tree_list (decl_specs, expr_decl));
+  push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
+                                  build_tree_list (NULL_TREE, NULL_TREE)));
   parms = get_parm_info (0);
   poplevel (0, 0, 0);
 
-  decl_specs = build_tree_list (NULLT, objc_object_reference);
-  expr_decl = build_nt (CALL_EXPR, get_identifier ("objc_xxx"), parms, NULLT);
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
+  decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+  sprintf (buffer, "__objc_tmp_%x", xxx++);
+  expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
+  expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
 
   return define_decl (expr_decl, decl_specs);
 }
@@ -2548,8 +2919,9 @@ hack_method_prototype (nst_methods, tmp_decl)
      tree tmp_decl;
 {
   tree parms;
+  tree parm;
 
-  /* Hack to avoid problem with static typing of self arg. */
+  /* Hack to avoid problem with static typing of self arg.  */
   TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
   start_method_def (nst_methods);
   TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
@@ -2563,9 +2935,8 @@ hack_method_prototype (nst_methods, tmp_decl)
 
   /* Usually called from store_parm_decls -> init_function_start.  */
 
-  init_emit ();        /* needed to make assign_parms work (with -O).  */
-
   DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
+  current_function_decl = tmp_decl;
 
   {
     /* Code taken from start_function.  */
@@ -2577,11 +2948,17 @@ hack_method_prototype (nst_methods, tmp_decl)
     DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
   }
 
+  for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
+    DECL_CONTEXT (parm) = tmp_decl;
+
+  init_function_start (tmp_decl, "objc-act", 0);
+
   /* Typically called from expand_function_start for function definitions.  */
   assign_parms (tmp_decl, 0);
 
   /* install return type */
   TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
+
 }
 
 static void
@@ -2590,7 +2967,7 @@ generate_protocol_references (plist)
 {
   tree lproto;
 
-  /* forward declare protocols referenced */
+  /* Forward declare protocols referenced.  */
   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
     {
       tree proto = TREE_VALUE (lproto);
@@ -2620,7 +2997,7 @@ generate_protocols ()
   if (! objc_protocol_template)
     objc_protocol_template = build_protocol_template ();
 
-  /* if a protocol was directly referenced, pull in indirect references */
+  /* If a protocol was directly referenced, pull in indirect references.  */
   for (p = protocol_chain; p; p = TREE_CHAIN (p))
     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
       generate_protocol_references (PROTOCOL_LIST (p));
@@ -2630,27 +3007,32 @@ generate_protocols ()
       tree nst_methods = PROTOCOL_NST_METHODS (p);
       tree cls_methods = PROTOCOL_CLS_METHODS (p);
 
-      /* if protocol wasn't referenced, don't generate any code */
+      /* If protocol wasn't referenced, don't generate any code.  */
       if (! PROTOCOL_FORWARD_DECL (p))
        continue;
 
-      /* Make sure we link in the Protocol class. */
+      /* Make sure we link in the Protocol class.  */
       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
 
       while (nst_methods)
        {
-         hack_method_prototype (nst_methods, tmp_decl);
-         encoding = encode_method_prototype (nst_methods, tmp_decl);
-         METHOD_ENCODING (nst_methods) = encoding;
-
+         if (! METHOD_ENCODING (nst_methods))
+           {
+             hack_method_prototype (nst_methods, tmp_decl);
+             encoding = encode_method_prototype (nst_methods, tmp_decl);
+             METHOD_ENCODING (nst_methods) = encoding;
+           }
          nst_methods = TREE_CHAIN (nst_methods);
        }
 
       while (cls_methods)
        {
-         hack_method_prototype (cls_methods, tmp_decl);
-         encoding = encode_method_prototype (cls_methods, tmp_decl);
-         METHOD_ENCODING (cls_methods) = encoding;
+         if (! METHOD_ENCODING (cls_methods))
+           {
+             hack_method_prototype (cls_methods, tmp_decl);
+             encoding = encode_method_prototype (cls_methods, tmp_decl);
+             METHOD_ENCODING (cls_methods) = encoding;
+           }
 
          cls_methods = TREE_CHAIN (cls_methods);
        }
@@ -2663,12 +3045,12 @@ generate_protocols ()
 
       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
 
-      sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-      decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
+      sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
+                          NULL_TREE);
+      decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
 
       decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
-                        decl_specs, 1);
-      end_temporary_allocation ();
+                        decl_specs, 1, NULL_TREE, NULL_TREE);
 
       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
 
@@ -2676,9 +3058,12 @@ generate_protocols ()
        {
          if (!cast_type2)
            cast_type2
-             = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
-                                              build1 (INDIRECT_REF, NULLT,
-                                                      build1 (INDIRECT_REF, NULLT, NULLT))));
+             = groktypename
+               (build_tree_list (build_tree_list (NULL_TREE,
+                                                  objc_protocol_template),
+                                 build1 (INDIRECT_REF, NULL_TREE,
+                                         build1 (INDIRECT_REF, NULL_TREE,
+                                                 NULL_TREE))));
 
          refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
          TREE_TYPE (refs_expr) = cast_type2;
@@ -2688,61 +3073,65 @@ generate_protocols ()
 
       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
         by generate_method_descriptors, which is called above.  */
-      initlist = build_protocol_initializer (protocol_name_expr, refs_expr,
+      initlist = build_protocol_initializer (TREE_TYPE (decl),
+                                            protocol_name_expr, refs_expr,
                                             UOBJC_INSTANCE_METHODS_decl,
                                             UOBJC_CLASS_METHODS_decl);
-      finish_decl (decl, initlist, NULLT);
+      finish_decl (decl, initlist, NULL_TREE);
 
-      /* Mark the decl as used to avoid "defined but not used" warning. */
+      /* Mark the decl as used to avoid "defined but not used" warning.  */
       TREE_USED (decl) = 1;
     }
 }
 
 static tree
-build_protocol_initializer (protocol_name, protocol_list,
+build_protocol_initializer (type, protocol_name, protocol_list,
                            instance_methods, class_methods)
+     tree type;
      tree protocol_name;
      tree protocol_list;
      tree instance_methods;
      tree class_methods;
 {
-  tree initlist = NULLT, expr;
+  tree initlist = NULL_TREE, expr;
   static tree cast_type = 0;
 
   if (!cast_type)
     cast_type
-      = groktypename (build_tree_list
-                     (build_tree_list (NULLT,
-                                       xref_tag (RECORD_TYPE,
-                                                 get_identifier (UTAG_CLASS))),
-                      build1 (INDIRECT_REF, NULLT, NULLT)));
+      = groktypename
+       (build_tree_list
+        (build_tree_list (NULL_TREE,
+                          xref_tag (RECORD_TYPE,
+                                    get_identifier (UTAG_CLASS))),
+         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
 
-  /* filling the "isa" in with one allows the runtime system to
-     detect that the version change...should remove before final release */
+  /* Filling the "isa" in with one allows the runtime system to
+     detect that the version change...should remove before final release */
 
   expr = build_int_2 (PROTOCOL_VERSION, 0);
   TREE_TYPE (expr) = cast_type;
-  initlist = tree_cons (NULLT, expr, initlist);
-  initlist = tree_cons (NULLT, protocol_name, initlist);
-  initlist = tree_cons (NULLT, protocol_list, initlist);
+  initlist = tree_cons (NULL_TREE, expr, initlist);
+  initlist = tree_cons (NULL_TREE, protocol_name, initlist);
+  initlist = tree_cons (NULL_TREE, protocol_list, initlist);
 
   if (!instance_methods)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
+
   if (!class_methods)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+
+  return build_constructor (type, nreverse (initlist));
 }
-/* end code generation for protocols... */
 \f
 /* struct objc_category {
      char *category_name;
@@ -2761,45 +3150,89 @@ build_category_template ()
                                         get_identifier (UTAG_CATEGORY));
   /* char *category_name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* char *class_name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method_list *instance_methods; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                get_identifier (UTAG_METHOD_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE,
+                               xref_tag (RECORD_TYPE,
+                                         get_identifier (UTAG_METHOD_LIST)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method_list *class_methods; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                get_identifier (UTAG_METHOD_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE,
+                               xref_tag (RECORD_TYPE,
+                                         get_identifier (UTAG_METHOD_LIST)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_protocol **protocol_list; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                          get_identifier (UTAG_PROTOCOL)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
-;
+  decl_specs = build_tree_list (NULL_TREE,
+                               xref_tag (RECORD_TYPE,
+                                         get_identifier (UTAG_PROTOCOL)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+  chainon (field_decl_chain, field_decl);
+
+  finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
+}
+
+/* struct objc_selector {
+     void *sel_id;
+     char *sel_type;
+   }; */
+
+static void
+build_selector_template ()
+{
+
+  tree decl_specs, field_decl, field_decl_chain;
+
+  objc_selector_template 
+    = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
+
+  /* void *sel_id; */
+
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+  field_decl_chain = field_decl;
+
+  /* char *sel_type; */
+
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_category_template, field_decl_chain);
+  finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
 }
 
 /* struct objc_class {
@@ -2826,112 +3259,136 @@ build_class_template ()
 {
   tree decl_specs, field_decl, field_decl_chain;
 
-  objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
+  objc_class_template
+    = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
 
   /* struct objc_class *isa; */
 
-  decl_specs = build_tree_list (NULLT, objc_class_template);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* struct objc_class *super_class; */
 
-  decl_specs = build_tree_list (NULLT, objc_class_template);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* char *name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* long version; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
   field_decl = get_identifier ("version");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* long info; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
   field_decl = get_identifier ("info");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* long instance_size; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
   field_decl = get_identifier ("instance_size");
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_ivar_list *ivars; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                get_identifier (UTAG_IVAR_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE,
+                               xref_tag (RECORD_TYPE,
+                                         get_identifier (UTAG_IVAR_LIST)));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method_list *methods; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                get_identifier (UTAG_METHOD_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = build_tree_list (NULL_TREE,
+                               xref_tag (RECORD_TYPE,
+                                         get_identifier (UTAG_METHOD_LIST)));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
+  field_decl
+    = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   if (flag_next_runtime)
     {
       /* struct objc_cache *cache; */
 
-      decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                    get_identifier ("objc_cache")));
-      field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
-      field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+      decl_specs = build_tree_list (NULL_TREE,
+                                   xref_tag (RECORD_TYPE,
+                                             get_identifier ("objc_cache")));
+      field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
+      field_decl = grokfield (input_filename, lineno, field_decl,
+                             decl_specs, NULL_TREE);
       chainon (field_decl_chain, field_decl);
     }
   else
     {
       /* struct sarray *dtable; */
 
-      decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                                    get_identifier ("sarray")));
-      field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
-      field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+      decl_specs = build_tree_list (NULL_TREE,
+                                   xref_tag (RECORD_TYPE,
+                                             get_identifier ("sarray")));
+      field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
+      field_decl = grokfield (input_filename, lineno, field_decl,
+                             decl_specs, NULL_TREE);
       chainon (field_decl_chain, field_decl);
 
       /* struct objc_class *subclass_list; */
 
-      decl_specs = build_tree_list (NULLT, objc_class_template);
-      field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
-      field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+      decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+      field_decl
+       = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
+      field_decl = grokfield (input_filename, lineno, field_decl,
+                             decl_specs, NULL_TREE);
       chainon (field_decl_chain, field_decl);
 
       /* struct objc_class *sibling_class; */
 
-      decl_specs = build_tree_list (NULLT, objc_class_template);
-      field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
-      field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+      decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+      field_decl
+       = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
+      field_decl = grokfield (input_filename, lineno, field_decl,
+                             decl_specs, NULL_TREE);
       chainon (field_decl_chain, field_decl);
     }
 
   /* struct objc_protocol **protocol_list; */
 
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
+  decl_specs = build_tree_list (NULL_TREE, 
+                               xref_tag (RECORD_TYPE,
                                          get_identifier (UTAG_PROTOCOL)));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+  field_decl = grokfield (input_filename, lineno, field_decl,
+                         decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
 
-  finish_struct (objc_class_template, field_decl_chain);
+  finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
 }
 
 /* Generate appropriate forward declarations for an implementation.  */
@@ -2945,10 +3402,11 @@ synth_forward_declarations ()
 
   an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
 
-  sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
-  decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
+  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
+  decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
   UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
   TREE_USED (UOBJC_CLASS_decl) = 1;
+  DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
 
   /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
 
@@ -2957,8 +3415,9 @@ synth_forward_declarations ()
 
   UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
   TREE_USED (UOBJC_METACLASS_decl) = 1;
+  DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
 
-  /* pre-build the following entities - for speed/convenience. */
+  /* Pre-build the following entities - for speed/convenience.  */
 
   an_id = get_identifier ("super_class");
   ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
@@ -2981,9 +3440,9 @@ error_with_ivar (message, decl, rawdecl)
   fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
 }
 
-#define USERTYPE(t)    (TREE_CODE (t) == RECORD_TYPE || \
                       TREE_CODE (t) == UNION_TYPE ||  \
-                        TREE_CODE (t) == ENUMERAL_TYPE)
+#define USERTYPE(t) \
(TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
+  ||  TREE_CODE (t) == ENUMERAL_TYPE)
 
 static void
 check_ivars (inter, imp)
@@ -3006,6 +3465,7 @@ check_ivars (inter, imp)
          error ("inconsistent instance variable specification");
          break;
        }
+
       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
 
       if (!comptypes (t1, t2))
@@ -3023,6 +3483,7 @@ check_ivars (inter, imp)
              break;
            }
        }
+
       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
        {
          error_with_ivar ("conflicting instance variable name",
@@ -3030,6 +3491,7 @@ check_ivars (inter, imp)
          error_with_ivar ("previous declaration of",
                           intdecls, rawintdecls);
        }
+
       intdecls = TREE_CHAIN (intdecls);
       impdecls = TREE_CHAIN (impdecls);
       rawintdecls = TREE_CHAIN (rawintdecls);
@@ -3050,29 +3512,30 @@ build_super_template ()
 
   /* struct objc_object *self; */
 
-  decl_specs = build_tree_list (NULLT, objc_object_reference);
+  decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
   field_decl = get_identifier ("self");
-  field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
   field_decl = grokfield (input_filename, lineno,
-                         field_decl, decl_specs, NULLT);
+                         field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* struct objc_class *class; */
 
   decl_specs = get_identifier (UTAG_CLASS);
-  decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
+  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
 
   field_decl = grokfield (input_filename, lineno,
-                         field_decl, decl_specs, NULLT);
+                         field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (record, field_decl_chain);
+  finish_struct (record, field_decl_chain, NULL_TREE);
 
   /* `struct objc_super *' */
-  super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
+  super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+                                                              record),
                                              build1 (INDIRECT_REF,
-                                                     NULLT, NULLT)));
+                                                     NULL_TREE, NULL_TREE)));
   return record;
 }
 
@@ -3093,32 +3556,32 @@ build_ivar_template ()
 
   /* char *ivar_name; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
 
   field_decl = grokfield (input_filename, lineno, field_decl,
-                         decl_specs, NULLT);
+                         decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* char *ivar_type; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
 
   field_decl = grokfield (input_filename, lineno, field_decl,
-                         decl_specs, NULLT);
+                         decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* int ivar_offset; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
   field_decl = get_identifier ("ivar_offset");
 
   field_decl = grokfield (input_filename, lineno, field_decl,
-                         decl_specs, NULLT);
+                         decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_record, field_decl_chain);
+  finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
 
   return objc_ivar_record;
 }
@@ -3136,28 +3599,28 @@ build_ivar_list_template (list_type, size)
   tree objc_ivar_list_record;
   tree decl_specs, field_decl, field_decl_chain;
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
+  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
 
   /* int ivar_count; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
   field_decl = get_identifier ("ivar_count");
 
   field_decl = grokfield (input_filename, lineno, field_decl,
-                         decl_specs, NULLT);
+                         decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* struct objc_ivar ivar_list[]; */
 
-  decl_specs = build_tree_list (NULLT, list_type);
+  decl_specs = build_tree_list (NULL_TREE, list_type);
   field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
                         build_int_2 (size, 0));
 
   field_decl = grokfield (input_filename, lineno,
-                         field_decl, decl_specs, NULLT);
+                         field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain);
+  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
 
   return objc_ivar_list_record;
 }
@@ -3176,86 +3639,99 @@ build_method_list_template (list_type, size)
   tree objc_ivar_list_record;
   tree decl_specs, field_decl, field_decl_chain;
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
+  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
 
   /* int method_next; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
-  field_decl = get_identifier ("method_next");
-
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs
+    = build_tree_list
+      (NULL_TREE, 
+       xref_tag (RECORD_TYPE,
+                get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+  field_decl
+    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
+  field_decl = grokfield (input_filename, lineno, field_decl,
+                         decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
   /* int method_count; */
 
-  decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
   field_decl = get_identifier ("method_count");
 
   field_decl = grokfield (input_filename, lineno,
-                         field_decl, decl_specs, NULLT);
+                         field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* struct objc_method method_list[]; */
 
-  decl_specs = build_tree_list (NULLT, list_type);
+  decl_specs = build_tree_list (NULL_TREE, list_type);
   field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
                         build_int_2 (size, 0));
 
   field_decl = grokfield (input_filename, lineno,
-                         field_decl, decl_specs, NULLT);
+                         field_decl, decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain);
+  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
 
   return objc_ivar_list_record;
 }
 
 static tree
-build_ivar_list_initializer (field_decl, size)
+build_ivar_list_initializer (type, field_decl)
+     tree type;
      tree field_decl;
-     int *size;
 {
-  tree initlist = NULLT;
+  tree initlist = NULL_TREE;
 
   do
     {
-      /* set name */
+      tree ivar = NULL_TREE;
+
+      /* Set name.  */
       if (DECL_NAME (field_decl))
-       initlist = tree_cons (NULLT,
-                             add_objc_string (DECL_NAME (field_decl),
-                                              meth_var_names),
-                             initlist);
+       ivar = tree_cons (NULL_TREE,
+                         add_objc_string (DECL_NAME (field_decl),
+                                          meth_var_names),
+                         ivar);
       else
-       /* unnamed bit-field ivar (yuck). */
-       initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+       /* Unnamed bit-field ivar (yuck).  */
+       ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
 
-      /* set type */
+      /* Set type.  */
       encode_field_decl (field_decl,
                         obstack_object_size (&util_obstack),
                         OBJC_ENCODE_DONT_INLINE_DEFS);
-      obstack_1grow (&util_obstack, 0);    /* null terminate string */
-      initlist
+
+      /* Null terminate string.  */
+      obstack_1grow (&util_obstack, 0);
+      ivar
        = tree_cons
-         (NULLT,
+         (NULL_TREE,
           add_objc_string (get_identifier (obstack_finish (&util_obstack)),
                            meth_var_types),
-          initlist);
+          ivar);
       obstack_free (&util_obstack, util_firstobj);
 
       /* set offset */
-      initlist
+      ivar
        = tree_cons
-         (NULLT,
+         (NULL_TREE,
           build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
                         / BITS_PER_UNIT),
                        0),
-          initlist);
-      (*size)++;
+          ivar);
+
+      initlist = tree_cons (NULL_TREE, 
+                           build_constructor (type, nreverse (ivar)),
+                           initlist);
+
       field_decl = TREE_CHAIN (field_decl);
     }
   while (field_decl);
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (build_array_type (type, 0), nreverse (initlist));
 }
 
 static tree
@@ -3267,17 +3743,18 @@ generate_ivars_list (type, name, size, list)
 {
   tree sc_spec, decl_specs, decl, initlist;
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-  decl_specs = tree_cons (NULLT, type, sc_spec);
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
 
   decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
-                    decl_specs, 1);
-  end_temporary_allocation ();
+                    decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  initlist = build_tree_list (NULLT, build_int_2 (size, 0));
-  initlist = tree_cons (NULLT, list, initlist);
+  initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
+  initlist = tree_cons (NULL_TREE, list, initlist);
 
-  finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
+  finish_decl (decl,
+              build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+              NULL_TREE);
 
   return decl;
 }
@@ -3296,26 +3773,25 @@ generate_ivar_lists ()
 
   cast
     = build_tree_list
-      (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
+      (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
                                         get_identifier (UTAG_IVAR_LIST))),
-       NULLT);
+       NULL_TREE);
   variable_length_type = groktypename (cast);
 
-  /* only generate class variables for the root of the inheritance
-     hierarchy since these will be the same for every class */
+  /* Only generate class variables for the root of the inheritance
+     hierarchy since these will be the same for every class */
 
-  if (CLASS_SUPER_NAME (implementation_template) == NULLT
+  if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
       && (chain = TYPE_FIELDS (objc_class_template)))
     {
-      size = 0;
-      initlist = build_ivar_list_initializer (chain, &size);
+      size = list_length (chain);
 
       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
+      initlist = build_ivar_list_initializer (objc_ivar_template, chain);
 
-      UOBJC_CLASS_VARIABLES_decl =
-       generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
-                            size, initlist);
-      /* cast! */
+      UOBJC_CLASS_VARIABLES_decl
+       = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
+                              size, initlist);
       TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
     }
   else
@@ -3324,15 +3800,13 @@ generate_ivar_lists ()
   chain = CLASS_IVARS (implementation_template);
   if (chain)
     {
-      size = 0;
-      initlist = build_ivar_list_initializer (chain, &size);
-
+      size = list_length (chain);
       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
+      initlist = build_ivar_list_initializer (objc_ivar_template, chain);
 
-      UOBJC_INSTANCE_VARIABLES_decl =
-       generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
-                            size, initlist);
-      /* cast! */
+      UOBJC_INSTANCE_VARIABLES_decl
+       = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
+                              size, initlist);
       TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
     }
   else
@@ -3342,38 +3816,48 @@ generate_ivar_lists ()
 }
 
 static tree
-build_dispatch_table_initializer (entries, size)
+build_dispatch_table_initializer (type, entries)
+     tree type;
      tree entries;
-     int *size;
 {
-  tree initlist = NULLT;
+  tree initlist = NULL_TREE;
 
   do
     {
-      initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
-                           initlist);
+      tree elemlist = NULL_TREE;
 
-      initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
-                                                   meth_var_types),
-                           initlist);
+      elemlist = tree_cons (NULL_TREE,
+                           build_selector (METHOD_SEL_NAME (entries)),
+                           NULL_TREE);
+
+      elemlist = tree_cons (NULL_TREE,
+                           add_objc_string (METHOD_ENCODING (entries),
+                                            meth_var_types),
+                           elemlist);
 
-      initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
+      elemlist = tree_cons (NULL_TREE, 
+                           build_unary_op (ADDR_EXPR,
+                                           METHOD_DEFINITION (entries), 1),
+                           elemlist);
+
+      initlist = tree_cons (NULL_TREE, 
+                           build_constructor (type, nreverse (elemlist)),
+                           initlist);
 
-      (*size)++;
       entries = TREE_CHAIN (entries);
     }
   while (entries);
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (build_array_type (type, 0), nreverse (initlist));
 }
 
 /* To accomplish method prototyping without generating all kinds of
    inane warnings, the definition of the dispatch table entries were
    changed from:
 
-       struct objc_method { SEL _cmd; id (*_imp)(); };
+       struct objc_method { SEL _cmd; ...; id (*_imp)(); };
    to:
-       struct objc_method { SEL _cmd; void *_imp; };  */
+       struct objc_method { SEL _cmd; ...; void *_imp; };  */
 
 static tree
 build_method_template ()
@@ -3385,34 +3869,39 @@ build_method_template ()
 
 #ifdef OBJC_INT_SELECTORS
   /* unsigned int _cmd; */
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
+                         NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
   field_decl = get_identifier ("_cmd");
 #else /* not OBJC_INT_SELECTORS */
   /* struct objc_selector *_cmd; */
-  decl_specs = tree_cons (NULLT,
+  decl_specs = tree_cons (NULL_TREE,
                          xref_tag (RECORD_TYPE,
                                    get_identifier (TAG_SELECTOR)),
-                         NULLT);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
+                         NULL_TREE);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
 #endif /* not OBJC_INT_SELECTORS */
 
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  field_decl = grokfield (input_filename, lineno, field_decl,
+                         decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
 
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE,
+                      get_identifier ("method_types"));
+  field_decl = grokfield (input_filename, lineno, field_decl,
+                         decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
   /* void *_imp; */
 
-  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
-  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
-  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
+  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
+  field_decl = grokfield (input_filename, lineno, field_decl,
+                         decl_specs, NULL_TREE);
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (_SLT_record, field_decl_chain);
+  finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
 
   return _SLT_record;
 }
@@ -3427,18 +3916,19 @@ generate_dispatch_table (type, name, size, list)
 {
   tree sc_spec, decl_specs, decl, initlist;
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-  decl_specs = tree_cons (NULLT, type, sc_spec);
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
 
   decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
-                    decl_specs, 1);
-  end_temporary_allocation ();
+                    decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  initlist = build_tree_list (NULLT, build_int_2 (0, 0));
-  initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
-  initlist = tree_cons (NULLT, list, initlist);
+  initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+  initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
+  initlist = tree_cons (NULL_TREE, list, initlist);
 
-  finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
+  finish_decl (decl,
+              build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+              NULL_TREE);
 
   return decl;
 }
@@ -3455,19 +3945,22 @@ generate_dispatch_tables ()
 
   cast
     = build_tree_list
-      (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
-                                        get_identifier (UTAG_METHOD_LIST))),
-       NULLT);
+      (build_tree_list (NULL_TREE,
+                       xref_tag (RECORD_TYPE,
+                                 get_identifier (UTAG_METHOD_LIST))),
+       NULL_TREE);
+
   variable_length_type = groktypename (cast);
 
   chain = CLASS_CLS_METHODS (implementation_context);
   if (chain)
     {
-      size = 0;
-      initlist = build_dispatch_table_initializer (chain, &size);
+      size = list_length (chain);
 
-      method_list_template = build_method_list_template (objc_method_template,
-                                                        size);
+      method_list_template
+       = build_method_list_template (objc_method_template, size);
+      initlist
+       = build_dispatch_table_initializer (objc_method_template, chain);
 
       UOBJC_CLASS_METHODS_decl
        = generate_dispatch_table (method_list_template,
@@ -3476,7 +3969,6 @@ generate_dispatch_tables ()
                                    ? "_OBJC_CLASS_METHODS"
                                    : "_OBJC_CATEGORY_CLASS_METHODS"),
                                   size, initlist);
-      /* cast! */
       TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
     }
   else
@@ -3485,23 +3977,24 @@ generate_dispatch_tables ()
   chain = CLASS_NST_METHODS (implementation_context);
   if (chain)
     {
-      size = 0;
-      initlist = build_dispatch_table_initializer (chain, &size);
+      size = list_length (chain);
+
+      method_list_template
+       = build_method_list_template (objc_method_template, size);
+      initlist
+       = build_dispatch_table_initializer (objc_method_template, chain);
 
-      method_list_template = build_method_list_template (objc_method_template,
-                                                        size);
       if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
-       UOBJC_INSTANCE_METHODS_decl =
-           generate_dispatch_table (method_list_template,
+       UOBJC_INSTANCE_METHODS_decl
+         = generate_dispatch_table (method_list_template,
                                     "_OBJC_INSTANCE_METHODS",
                                     size, initlist);
       else
-       /* we have a category */
-       UOBJC_INSTANCE_METHODS_decl =
-           generate_dispatch_table (method_list_template,
+       /* We have a category.  */
+       UOBJC_INSTANCE_METHODS_decl
+         = generate_dispatch_table (method_list_template,
                                     "_OBJC_CATEGORY_INSTANCE_METHODS",
                                     size, initlist);
-      /* cast! */
       TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
     }
   else
@@ -3529,23 +4022,23 @@ generate_protocol_list (i_or_p)
     cast_type
       = groktypename
        (build_tree_list
-        (build_tree_list (NULLT,
+        (build_tree_list (NULL_TREE,
                           xref_tag (RECORD_TYPE,
                                     get_identifier (UTAG_PROTOCOL))),
-         build1 (INDIRECT_REF, NULLT, NULLT)));
+         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
 
-  /* compute size */
+  /* Compute size.  */
   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
        && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
       size++;
 
-  /* build initializer */
-  initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
+  /* Build initializer.  */
+  initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
 
   e = build_int_2 (size, 0);
   TREE_TYPE (e) = cast_type;
-  initlist = tree_cons (NULLT, e, initlist);
+  initlist = tree_cons (NULL_TREE, e, initlist);
 
   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
     {
@@ -3555,14 +4048,14 @@ generate_protocol_list (i_or_p)
          && PROTOCOL_FORWARD_DECL (pval))
        {
          e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
-         initlist = tree_cons (NULLT, e, initlist);
+         initlist = tree_cons (NULL_TREE, e, initlist);
        }
     }
 
   /* static struct objc_protocol *refs[n]; */
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-  decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
                                           get_identifier (UTAG_PROTOCOL)),
                          sc_spec);
 
@@ -3577,54 +4070,56 @@ generate_protocol_list (i_or_p)
                                                      i_or_p),
                          build_int_2 (size + 2, 0));
   else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
-    expr_decl = build_nt (ARRAY_REF,
-                         synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
-                                                     i_or_p),
-                         build_int_2 (size + 2, 0));
+    expr_decl
+      = build_nt (ARRAY_REF,
+                 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
+                                             i_or_p),
+                 build_int_2 (size + 2, 0));
 
-  expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
+  expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
 
-  refs_decl = start_decl (expr_decl, decl_specs, 1);
-  end_temporary_allocation ();
+  refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  finish_decl (refs_decl, build_nt (CONSTRUCTOR, NULLT,
-                                   nreverse (initlist)), NULLT);
+  finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
+                                            nreverse (initlist)),
+              NULL_TREE);
 
   return refs_decl;
 }
 
 static tree
-build_category_initializer (cat_name, class_name,
+build_category_initializer (type, cat_name, class_name,
                            instance_methods, class_methods, protocol_list)
+     tree type;
      tree cat_name;
      tree class_name;
      tree instance_methods;
      tree class_methods;
      tree protocol_list;
 {
-  tree initlist = NULLT, expr;
+  tree initlist = NULL_TREE, expr;
 
-  initlist = tree_cons (NULLT, cat_name, initlist);
-  initlist = tree_cons (NULLT, class_name, initlist);
+  initlist = tree_cons (NULL_TREE, cat_name, initlist);
+  initlist = tree_cons (NULL_TREE, class_name, initlist);
 
   if (!instance_methods)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
   if (!class_methods)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
 
   /* protocol_list = */
   if (!protocol_list)
-     initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
      {
        static tree cast_type2;
@@ -3633,18 +4128,18 @@ build_category_initializer (cat_name, class_name,
          cast_type2
            = groktypename
              (build_tree_list
-              (build_tree_list (NULLT,
+              (build_tree_list (NULL_TREE,
                                 xref_tag (RECORD_TYPE,
                                           get_identifier (UTAG_PROTOCOL))),
-               build1 (INDIRECT_REF, NULLT,
-                       build1 (INDIRECT_REF, NULLT, NULLT))));
+               build1 (INDIRECT_REF, NULL_TREE,
+                       build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
 
        expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
        TREE_TYPE (expr) = cast_type2;
-       initlist = tree_cons (NULLT, expr, initlist);
+       initlist = tree_cons (NULL_TREE, expr, initlist);
      }
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (type, nreverse (initlist));
 }
 
 /* struct objc_class {
@@ -3667,8 +4162,9 @@ build_category_initializer (cat_name, class_name,
    };  */
 
 static tree
-build_shared_structure_initializer (isa, super, name, size, status,
+build_shared_structure_initializer (type, isa, super, name, size, status,
                                    dispatch_table, ivar_list, protocol_list)
+     tree type;
      tree isa;
      tree super;
      tree name;
@@ -3678,62 +4174,62 @@ build_shared_structure_initializer (isa, super, name, size, status,
      tree ivar_list;
      tree protocol_list;
 {
-  tree initlist = NULLT, expr;
+  tree initlist = NULL_TREE, expr;
 
   /* isa = */
-  initlist = tree_cons (NULLT, isa, initlist);
+  initlist = tree_cons (NULL_TREE, isa, initlist);
 
   /* super_class = */
-  initlist = tree_cons (NULLT, super, initlist);
+  initlist = tree_cons (NULL_TREE, super, initlist);
 
   /* name = */
-  initlist = tree_cons (NULLT, name, initlist);
+  initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
 
   /* version = */
-  initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+  initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
 
   /* info = */
-  initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
+  initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
 
   /* instance_size = */
-  initlist = tree_cons (NULLT, size, initlist);
+  initlist = tree_cons (NULL_TREE, size, initlist);
 
   /* objc_ivar_list = */
   if (!ivar_list)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
 
   /* objc_method_list = */
   if (!dispatch_table)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
-      initlist = tree_cons (NULLT, expr, initlist);
+      initlist = tree_cons (NULL_TREE, expr, initlist);
     }
 
   if (flag_next_runtime)
     /* method_cache = */
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
     {
       /* dtable = */
-      initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
 
       /* subclass_list = */
-      initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
 
       /* sibling_class = */
-      initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
     }
 
   /* protocol_list = */
   if (! protocol_list)
-    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
+    initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
      {
      static tree cast_type2;
@@ -3742,21 +4238,22 @@ build_shared_structure_initializer (isa, super, name, size, status,
         cast_type2
          = groktypename
            (build_tree_list
-            (build_tree_list (NULLT,
+            (build_tree_list (NULL_TREE,
                               xref_tag (RECORD_TYPE,
                                         get_identifier (UTAG_PROTOCOL))),
-             build1 (INDIRECT_REF, NULLT,
-                     build1 (INDIRECT_REF, NULLT, NULLT))));
+             build1 (INDIRECT_REF, NULL_TREE,
+                     build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
 
      expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
      TREE_TYPE (expr) = cast_type2;
-     initlist = tree_cons (NULLT, expr, initlist);
+     initlist = tree_cons (NULL_TREE, expr, initlist);
      }
 
-  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
+  return build_constructor (type, nreverse (initlist));
 }
 
 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
+
 static void
 generate_category (cat)
      tree cat;
@@ -3788,21 +4285,21 @@ generate_category (cat)
   else
     protocol_decl = 0;
 
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
-  decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+  decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
 
   decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
                                                 implementation_context),
-                    decl_specs, 1);
-  end_temporary_allocation ();
+                    decl_specs, 1, NULL_TREE, NULL_TREE);
 
-  initlist = build_category_initializer (cat_name_expr, class_name_expr,
+  initlist = build_category_initializer (TREE_TYPE (decl),
+                                        cat_name_expr, class_name_expr,
                                         UOBJC_INSTANCE_METHODS_decl,
                                         UOBJC_CLASS_METHODS_decl,
                                         protocol_decl);
 
   TREE_USED (decl) = 1;
-  finish_decl (decl, initlist, NULLT);
+  finish_decl (decl, initlist, NULL_TREE);
 }
 
 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
@@ -3813,7 +4310,7 @@ generate_shared_structures ()
 {
   tree sc_spec, decl_specs, decl;
   tree name_expr, super_expr, root_expr;
-  tree my_root_id = NULLT, my_super_id = NULLT;
+  tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
   tree cast_type, initlist, protocol_decl;
 
   my_super_id = CLASS_SUPER_NAME (implementation_template);
@@ -3836,20 +4333,20 @@ generate_shared_structures ()
        }
       while (1);
     }
-  else                         /* no super class */
-    {
-      my_root_id = CLASS_NAME (implementation_template);
-    }
+  else
+    /* No super class.  */
+    my_root_id = CLASS_NAME (implementation_template);
 
   cast_type
-    = groktypename (build_tree_list (build_tree_list (NULLT,
+    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
                                                      objc_class_template),
-                                    build1 (INDIRECT_REF, NULLT, NULLT)));
+                                    build1 (INDIRECT_REF,
+                                            NULL_TREE, NULL_TREE)));
 
   name_expr = add_objc_string (CLASS_NAME (implementation_template),
                               class_names);
 
-  /* install class `isa' and `super' pointers at runtime */
+  /* Install class `isa' and `super' pointers at runtime.  */
   if (my_super_id)
     {
       super_expr = add_objc_string (my_super_id, class_names);
@@ -3863,7 +4360,8 @@ generate_shared_structures ()
 
   if (CLASS_PROTOCOL_LIST (implementation_template))
     {
-      generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
+      generate_protocol_references
+       (CLASS_PROTOCOL_LIST (implementation_template));
       protocol_decl = generate_protocol_list (implementation_template);
     }
   else
@@ -3871,15 +4369,16 @@ generate_shared_structures ()
 
   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
 
-  sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
-  decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
+  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+  decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
 
-  decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
-  end_temporary_allocation ();
+  decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
+                    NULL_TREE, NULL_TREE);
 
   initlist
     = build_shared_structure_initializer
-      (root_expr, super_expr, name_expr,
+      (TREE_TYPE (decl),
+       root_expr, super_expr, name_expr,
        build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
                    / BITS_PER_UNIT),
                    0),
@@ -3888,26 +4387,29 @@ generate_shared_structures ()
        UOBJC_CLASS_VARIABLES_decl,
        protocol_decl);
 
-  finish_decl (decl, initlist, NULLT);
+  finish_decl (decl, initlist, NULL_TREE);
 
   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
 
-  decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
-  end_temporary_allocation ();
+  decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
+                    NULL_TREE, NULL_TREE);
 
   initlist
     = build_shared_structure_initializer
-      (build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
+      (TREE_TYPE (decl),
+       build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
        super_expr, name_expr,
-       build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
-                   / BITS_PER_UNIT),
-                   0),
+       build_int_2
+       ((TREE_INT_CST_LOW
+        (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
+        / BITS_PER_UNIT),
+       0),
        1 /*CLS_FACTORY*/,
        UOBJC_INSTANCE_METHODS_decl,
        UOBJC_INSTANCE_VARIABLES_decl,
        protocol_decl);
 
-  finish_decl (decl, initlist, NULLT);
+  finish_decl (decl, initlist, NULL_TREE);
 }
 
 static tree
@@ -3928,7 +4430,7 @@ synth_id_with_class_suffix (preamble, ctxt)
   else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
           || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
     {
-      /* we have a category */
+      /* We have a category.  */
       char *class_name
        = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
       char *class_super_name
@@ -3942,7 +4444,8 @@ synth_id_with_class_suffix (preamble, ctxt)
   else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
     {
       char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
-      string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
+      string
+       = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
       sprintf (string, "%s_%s", preamble, protocol_name);
     }
   return get_identifier (string);
@@ -3972,8 +4475,8 @@ adjust_type_for_id_default (type)
   tree declspecs, chain;
 
   if (!type)
-    return build_tree_list (build_tree_list (NULLT, objc_object_reference),
-                           build1 (INDIRECT_REF, NULLT, NULLT));
+    return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
+                           build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
 
   declspecs = TREE_PURPOSE (type);
 
@@ -3986,27 +4489,28 @@ adjust_type_for_id_default (type)
        return type;
     }
 
-  return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
-                         build1 (INDIRECT_REF, NULLT, NULLT));
+  return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
+                                    declspecs),
+                         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
 }
 
-/*   usage:
+/*   Usage:
                keyworddecl:
                        selector ':' '(' typename ')' identifier
   
-     purpose:
-               transform an Objective-C keyword argument into
+     Purpose:
+               Transform an Objective-C keyword argument into
                the C equivalent parameter declarator.
   
-     in:       key_name, an "identifier_node" (optional).
+     In:       key_name, an "identifier_node" (optional).
                arg_type, a  "tree_list" (optional).
                arg_name, an "identifier_node".
   
-     note:     it would be really nice to strongly type the preceding
-               arguments in the function prototype; however, then i
+     Note:     It would be really nice to strongly type the preceding
+               arguments in the function prototype; however, then I
                could not use the "accessor" macros defined in "tree.h".
   
-     out:      an instance of "keyword_decl".  */
+     Out:      an instance of "keyword_decl".  */
 
 tree
 build_keyword_decl (key_name, arg_type, arg_name)
@@ -4016,7 +4520,7 @@ build_keyword_decl (key_name, arg_type, arg_name)
 {
   tree keyword_decl;
 
-  /* if no type is specified, default to "id" */
+  /* If no type is specified, default to "id".  */
   arg_type = adjust_type_for_id_default (arg_type);
 
   keyword_decl = make_node (KEYWORD_DECL);
@@ -4029,6 +4533,7 @@ build_keyword_decl (key_name, arg_type, arg_name)
 }
 
 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
+
 static tree
 build_keyword_selector (selector)
      tree selector;
@@ -4046,9 +4551,11 @@ build_keyword_selector (selector)
 
       if (key_name)
        len += IDENTIFIER_LENGTH (key_name) + 1;
-      else                     /* just a ':' arg */
+      else
+       /* Just a ':' arg.  */
        len++;
     }
+
   buf = (char *)alloca (len + 1);
   bzero (buf, len + 1);
 
@@ -4063,10 +4570,11 @@ build_keyword_selector (selector)
        strcat (buf, IDENTIFIER_POINTER (key_name));
       strcat (buf, ":");
     }
+
   return get_identifier (buf);
 }
 
-/* used for declarations and definitions */
+/* Used for declarations and definitions.  */
 
 tree
 build_method_decl (code, ret_type, selector, add_args)
@@ -4077,7 +4585,7 @@ build_method_decl (code, ret_type, selector, add_args)
 {
   tree method_decl;
 
-  /* if no type is specified, default to "id" */
+  /* If no type is specified, default to "id".  */
   ret_type = adjust_type_for_id_default (ret_type);
 
   method_decl = make_node (code);
@@ -4094,8 +4602,8 @@ build_method_decl (code, ret_type, selector, add_args)
   else
     {
       METHOD_SEL_NAME (method_decl) = selector;
-      METHOD_SEL_ARGS (method_decl) = NULLT;
-      METHOD_ADD_ARGS (method_decl) = NULLT;
+      METHOD_SEL_ARGS (method_decl) = NULL_TREE;
+      METHOD_ADD_ARGS (method_decl) = NULL_TREE;
     }
 
   return method_decl;
@@ -4119,22 +4627,22 @@ get_arg_type_list (meth, context, superflag)
 {
   tree arglist, akey;
 
-  /* receiver type */
+  /* Receiver type.  */
   if (flag_next_runtime && superflag)
-    arglist = build_tree_list (NULLT, super_type);
+    arglist = build_tree_list (NULL_TREE, super_type);
   else if (context == METHOD_DEF)
-    arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
+    arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
   else
-    arglist = build_tree_list (NULLT, id_type);
+    arglist = build_tree_list (NULL_TREE, id_type);
 
-  /* selector type - will eventually change to `int' */
-  chainon (arglist, build_tree_list (NULLT, selector_type));
+  /* Selector type - will eventually change to `int'.  */
+  chainon (arglist, build_tree_list (NULL_TREE, selector_type));
 
-  /* build a list of argument types */
+  /* Build a list of argument types.  */
   for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
     {
       tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
-      chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
+      chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
     }
 
   if (METHOD_ADD_ARGS (meth) == (tree)1)
@@ -4149,7 +4657,7 @@ get_arg_type_list (meth, context, superflag)
     }
   else
     /* finalize the arglist...simulate get_parm_info (1) */
-    chainon (arglist, build_tree_list (NULLT, void_type_node));
+    chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
 
   return arglist;
 }
@@ -4158,7 +4666,7 @@ static tree
 check_duplicates (hsh)
      hash hsh;
 {
-  tree meth = NULLT;
+  tree meth = NULL_TREE;
 
   if (hsh)
     {
@@ -4166,7 +4674,7 @@ check_duplicates (hsh)
 
       if (hsh->list)
         {
-         /* we have two methods with the same name and different types */
+         /* We have two methods with the same name and different types.  */
          attr loop;
          char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
 
@@ -4195,7 +4703,7 @@ receiver_is_class_object (receiver)
       /* 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. */
+       /* Look up the identifier.  */
        for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
          if (TREE_PURPOSE (chain) == receiver)
            return TREE_VALUE (chain);
@@ -4218,7 +4726,7 @@ receiver_is_class_object (receiver)
          if (TREE_CODE (arg) == ADDR_EXPR
              && (arg = TREE_OPERAND (arg, 0))
              && TREE_CODE (arg) == STRING_CST)
-           /* finally, we have the class name */
+           /* Finally, we have the class name.  */
            return get_identifier (TREE_STRING_POINTER (arg));
        }
     }
@@ -4227,7 +4735,7 @@ receiver_is_class_object (receiver)
 \f
 /* If we are currently building a message expr, this holds
    the identifier of the selector of the message.  This is
-   used when printing warnings about argument mismatches. */
+   used when printing warnings about argument mismatches.  */
 
 static tree building_objc_message_expr = 0;
 
@@ -4252,8 +4760,8 @@ build_message_expr (mess)
   tree selector, self_object;
   tree rtype, sel_name;
   tree args = TREE_VALUE (mess);
-  tree method_params = NULLT;
-  tree method_prototype = NULLT;
+  tree method_params = NULL_TREE;
+  tree method_prototype = NULL_TREE;
   tree retval;
   int statically_typed = 0, statically_allocated = 0;
   tree class_ident = 0;
@@ -4267,7 +4775,7 @@ build_message_expr (mess)
   if (TREE_CODE (receiver) == ERROR_MARK)
     return error_mark_node;
 
-  /* determine receiver type */
+  /* Determine receiver type.  */
   rtype = TREE_TYPE (receiver);
   super = IS_SUPER (rtype);
 
@@ -4290,10 +4798,11 @@ build_message_expr (mess)
          warning ("invalid receiver type `%s'",
                   gen_declaration (rtype, errbuf));
        }
+
       if (statically_allocated)
        receiver = build_unary_op (ADDR_EXPR, receiver, 0);
 
-      /* Don't evaluate the receiver twice. */
+      /* Don't evaluate the receiver twice.  */
       receiver = save_expr (receiver);
       self_object = receiver;
     }
@@ -4304,22 +4813,17 @@ build_message_expr (mess)
   /* Obtain the full selector name.  */
 
   if (TREE_CODE (args) == IDENTIFIER_NODE)
-    /* a unary selector */
+    /* A unary selector.  */
     sel_name = args;
   else if (TREE_CODE (args) == TREE_LIST)
     sel_name = build_keyword_selector (args);
 
-  /* Build the parameters list for looking up the method.
-     These are the object itself and the selector.  */
-
-  selector = build_selector_reference (sel_name);
-
   /* Build the parameter list to give to the method.  */
 
-  method_params = NULLT;
+  method_params = NULL_TREE;
   if (TREE_CODE (args) == TREE_LIST)
     {
-      tree chain = args, prev = NULLT;
+      tree chain = args, prev = NULL_TREE;
 
       /* We have a keyword selector--check for comma expressions.  */
       while (chain)
@@ -4348,7 +4852,8 @@ build_message_expr (mess)
 
       if (CLASS_SUPER_NAME (implementation_template))
        {
-         iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+         iface
+           = lookup_interface (CLASS_SUPER_NAME (implementation_template));
 
          if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
            method_prototype = lookup_instance_method_static (iface, sel_name);
@@ -4376,7 +4881,6 @@ build_message_expr (mess)
       if (iface)
        method_prototype = lookup_instance_method_static (iface, sel_name);
 
-      /* NEW!!! */
       if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
        method_prototype
          = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
@@ -4391,14 +4895,15 @@ build_message_expr (mess)
     {
       tree ctype = TREE_TYPE (rtype);
 
-      /* `self' is now statically_typed...all methods should be visible
-         within the context of the implementation...  */
+      /* `self' is now statically_typed.  All methods should be visible
+         within the context of the implementation.  */
       if (implementation_context
          && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
        {
-         method_prototype = lookup_instance_method_static (implementation_template, sel_name);
+         method_prototype
+           = lookup_instance_method_static (implementation_template,
+                                            sel_name);
 
-         /* NEW!!! */
          if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
            method_prototype
              = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
@@ -4406,7 +4911,8 @@ build_message_expr (mess)
 
          if (! method_prototype
              && implementation_template != implementation_context)
-           /* the method is not published in the interface...check locally */
+           /* The method is not published in the interface.  Check
+               locally.  */
            method_prototype
              = lookup_method (CLASS_NST_METHODS (implementation_context),
                               sel_name);
@@ -4423,7 +4929,8 @@ build_message_expr (mess)
              tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
              if (protocol_list)
                method_prototype
-                 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
+                 = lookup_method_in_protocol_list (protocol_list,
+                                                   sel_name, 0);
            }
        }
 
@@ -4442,7 +4949,8 @@ build_message_expr (mess)
 
          if (!method_prototype
              && implementation_template != implementation_context)
-           /* the method is not published in the interface...check locally */
+           /* The method is not published in the interface. Check
+               locally.  */
            method_prototype
              = lookup_method (CLASS_CLS_METHODS (implementation_context),
                               sel_name);
@@ -4478,7 +4986,7 @@ build_message_expr (mess)
          warning ("method `%s' not implemented by protocol.",
                   IDENTIFIER_POINTER (sel_name));
 
-          /* try and find the method signiture in the global pools! */
+          /* Try and find the method signature in the global pools.  */
 
           if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
            hsh = hash_lookup (cls_method_hash_list, sel_name);
@@ -4491,11 +4999,11 @@ build_message_expr (mess)
     {
       hash hsh;
 
-      /* we think we have an instance...loophole: extern id Object; */
+      /* We think we have an instance...loophole: extern id Object; */
       hsh = hash_lookup (nst_method_hash_list, sel_name);
       if (!hsh)
-       /* for various loopholes...like sending messages to self in a
-          factory context... */
+       /* For various loopholes, like sending messages to self in a
+          factory context.  */
        hsh = hash_lookup (cls_method_hash_list, sel_name);
 
       method_prototype = check_duplicates (hsh);
@@ -4510,6 +5018,14 @@ build_message_expr (mess)
   /* Save the selector name for printing error messages.  */
   building_objc_message_expr = sel_name;
 
+  /* Build the parameters list for looking up the method.
+     These are the object itself and the selector.  */
+
+  if (flag_typed_selectors)
+    selector = build_typed_selector_reference (sel_name, method_prototype);
+  else
+    selector = build_selector_reference (sel_name);
+
   retval = build_objc_method_call (super, method_prototype,
                                   receiver, self_object,
                                   selector, method_params);
@@ -4542,8 +5058,8 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
     {
       if (! method_prototype)
        {
-         method_params = tree_cons (NULLT, lookup_object,
-                                    tree_cons (NULLT, selector,
+         method_params = tree_cons (NULL_TREE, lookup_object,
+                                    tree_cons (NULL_TREE, selector,
                                                method_params));
          assemble_external (sender);
          return build_function_call (sender, method_params);
@@ -4554,7 +5070,7 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
             Clobber the data type of SENDER temporarily to accept
             all the arguments for this operation, and to return
             whatever this operation returns.  */
-         tree arglist = NULLT;
+         tree arglist = NULL_TREE;
          tree retval;
 
          /* Save the proper contents of SENDER's data type.  */
@@ -4572,8 +5088,8 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
 
          /* Call SENDER with all the parameters.  This will do type
             checking using the arg types for this method.  */
-         method_params = tree_cons (NULLT, lookup_object,
-                                    tree_cons (NULLT, selector,
+         method_params = tree_cons (NULL_TREE, lookup_object,
+                                    tree_cons (NULL_TREE, selector,
                                                method_params));
          assemble_external (sender);
          retval = build_function_call (sender, method_params);
@@ -4595,13 +5111,14 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
       object = save_expr (object);
       selector = save_expr (selector);
 
-      lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
+      lookup_object = build_c_cast (rcv_p, lookup_object);
 
       assemble_external (sender);
       method
        = build_function_call (sender,
-                              tree_cons (NULLT, lookup_object,
-                                         tree_cons (NULLT, selector, NULLT)));
+                              tree_cons (NULL_TREE, lookup_object,
+                                         tree_cons (NULL_TREE, selector,
+                                                    NULL_TREE)));
 
       /* If we have a method prototype, construct the data type this
         method needs, and cast what we got from SENDER into a pointer
@@ -4616,13 +5133,13 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
        }
       else
        TREE_TYPE (method)
-         = build_pointer_type (build_function_type (ptr_type_node, NULLT));
+         = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
 
       /* Pass the object to the method.  */
       assemble_external (method);
       return build_function_call (method,
-                                 tree_cons (NULLT, object,
-                                            tree_cons (NULLT, selector,
+                                 tree_cons (NULL_TREE, object,
+                                            tree_cons (NULL_TREE, selector,
                                                        method_params)));
     }
 }
@@ -4632,18 +5149,17 @@ build_protocol_reference (p)
      tree p;
 {
   tree decl, ident, ptype;
-  struct obstack *save_current_obstack = current_obstack;
-  struct obstack *save_rtl_obstack = rtl_obstack;
 
-  rtl_obstack = current_obstack = &permanent_obstack;
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
 
   /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
 
   ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
   ptype
-    = groktypename (build_tree_list (build_tree_list (NULLT,
+    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
                                                      objc_protocol_template),
-                                    NULLT));
+                                    NULL_TREE));
 
   if (IDENTIFIER_GLOBAL_VALUE (ident))
     decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl.  */
@@ -4653,16 +5169,14 @@ build_protocol_reference (p)
       DECL_EXTERNAL (decl) = 1;
       TREE_PUBLIC (decl) = 1;
       TREE_USED (decl) = 1;
+      DECL_ARTIFICIAL (decl) = 1;
 
-      /* usually called from `rest_of_decl_compilation' */
       make_decl_rtl (decl, 0, 1);
-      /* our `extended/custom' pushdecl in c-decl.c */
       pushdecl_top_level (decl);
    }
-  current_obstack = save_current_obstack;
-  rtl_obstack = save_rtl_obstack;
 
   PROTOCOL_FORWARD_DECL (p) = decl;
+  pop_obstacks ();
 }
 
 tree
@@ -4703,14 +5217,17 @@ build_selector_expr (selnamelist)
   if (!doing_objc_thang)
     objc_fatal ();
 
-  /* obtain the full selector name */
+  /* Obtain the full selector name.  */
   if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
-    /* a unary selector */
+    /* A unary selector.  */
     selname = selnamelist;
   else if (TREE_CODE (selnamelist) == TREE_LIST)
     selname = build_keyword_selector (selnamelist);
 
-  return build_selector_reference (selname);
+  if (flag_typed_selectors)
+    return build_typed_selector_reference (selname, 0);
+  else
+    return build_selector_reference (selname);
 }
 
 tree
@@ -4728,7 +5245,7 @@ build_encode_expr (type)
   obstack_1grow (&util_obstack, 0);    /* null terminate string */
   string = obstack_finish (&util_obstack);
 
-  /* synthesize a string that represents the encoded struct/union */
+  /* Synthesize a string that represents the encoded struct/union.  */
   result = my_build_string (strlen (string) + 1, string);
   obstack_free (&util_obstack, util_firstobj);
   return result;
@@ -4739,7 +5256,20 @@ build_ivar_reference (id)
      tree id;
 {
   if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
-    TREE_TYPE (self_decl) = instance_type; /* cast */
+    {
+      /* Historically, a class method that produced objects (factory
+        method) would assign `self' to the instance that it
+        allocated.  This would effectively turn the class method into
+        an instance method.  Following this assignment, the instance
+        variables could be accessed.  That practice, while safe,
+        violates the simple rule that a class method should not refer
+        to an instance variable.  It's better to catch the cases
+        where this is done unknowingly than to support the above
+        paradigm.  */
+      warning ("instance variable `%s' accessed in class method",
+              IDENTIFIER_POINTER (id));
+      TREE_TYPE (self_decl) = instance_type; /* cast */
+    }
 
   return build_component_ref (build_indirect_ref (self_decl, "->"), id);
 }
@@ -4747,7 +5277,9 @@ build_ivar_reference (id)
 #define HASH_ALLOC_LIST_SIZE   170
 #define ATTR_ALLOC_LIST_SIZE   170
 #define SIZEHASHTABLE          257
-#define HASHFUNCTION(key)      ((int)key & 0x7fffffff) /* make positive */
+
+/* make positive */
+#define HASHFUNCTION(key)      ((HOST_WIDE_INT) key & 0x7fffffff)
 
 static void
 hash_init ()
@@ -4856,7 +5388,7 @@ lookup_method (mchain, method)
        return mchain;
       mchain = TREE_CHAIN (mchain);
     }
-  return NULLT;
+  return NULL_TREE;
 }
 
 static tree
@@ -4866,7 +5398,7 @@ lookup_instance_method_static (interface, ident)
 {
   tree inter = interface;
   tree chain = CLASS_NST_METHODS (inter);
-  tree meth = NULLT;
+  tree meth = NULL_TREE;
 
   do
     {
@@ -4883,7 +5415,6 @@ lookup_instance_method_static (interface, ident)
              if ((meth = lookup_method (chain, ident)))
                return meth;
 
-             /* NEW!!! */
              /* Check for instance methods in protocols in categories.  */
              if (CLASS_PROTOCOL_LIST (category))
                {
@@ -4920,8 +5451,8 @@ lookup_class_method_static (interface, ident)
 {
   tree inter = interface;
   tree chain = CLASS_CLS_METHODS (inter);
-  tree meth = NULLT;
-  tree root_inter = NULLT;
+  tree meth = NULL_TREE;
+  tree root_inter = NULL_TREE;
 
   do
     {
@@ -4938,7 +5469,6 @@ lookup_class_method_static (interface, ident)
              if ((meth = lookup_method (chain, ident)))
                return meth;
 
-             /* NEW!!! */
              /* Check for class methods in protocols in categories.  */
              if (CLASS_PROTOCOL_LIST (category))
                {
@@ -4953,7 +5483,6 @@ lookup_class_method_static (interface, ident)
          while (category);
        }
 
-      /* NEW!!! */
       /* Check for class methods in protocols.  */
       if (CLASS_PROTOCOL_LIST (inter))
        {
@@ -4968,7 +5497,6 @@ lookup_class_method_static (interface, ident)
     }
   while (inter);
 
-/* NEW!!! */
   /* Simulate wrap around.  */
   return lookup_instance_method_static (root_inter, ident);
 }
@@ -4998,7 +5526,7 @@ add_class_method (class, method)
               IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
       else
         {
-         /* check types, if different complain */
+         /* Check types; if different, complain.  */
          if (!comp_proto_with_proto (method, mth))
            error ("duplicate declaration of class method `%s'.",
                   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
@@ -5007,12 +5535,12 @@ add_class_method (class, method)
 
   if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
     {
-      /* install on a global chain */
+      /* Install on a global chain.  */
       hash_enter (cls_method_hash_list, method);
     }
   else
     {
-      /* check types, if different add to a list */
+      /* Check types; if different, add to a list.  */
       if (!comp_proto_with_proto (method, hsh->key))
         hash_add_attr (hsh, method);
     }
@@ -5033,7 +5561,7 @@ add_instance_method (class, method)
 
   if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
     {
-      /* put method on list in reverse order */
+      /* Put method on list in reverse order.  */
       TREE_CHAIN (method) = CLASS_NST_METHODS (class);
       CLASS_NST_METHODS (class) = method;
     }
@@ -5044,7 +5572,7 @@ add_instance_method (class, method)
               IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
       else
         {
-         /* check types, if different complain */
+         /* Check types; if different, complain.  */
          if (!comp_proto_with_proto (method, mth))
            error ("duplicate declaration of instance method `%s'.",
                   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
@@ -5053,12 +5581,12 @@ add_instance_method (class, method)
 
   if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
     {
-      /* install on a global chain */
+      /* Install on a global chain.  */
       hash_enter (nst_method_hash_list, method);
     }
   else
     {
-      /* check types, if different add to a list */
+      /* Check types; if different, add to a list.  */
       if (!comp_proto_with_proto (method, hsh->key))
         hash_add_attr (hsh, method);
     }
@@ -5069,7 +5597,7 @@ static tree
 add_class (class)
      tree class;
 {
-  /* put interfaces on list in reverse order */
+  /* Put interfaces on list in reverse order.  */
   TREE_CHAIN (class) = interface_chain;
   interface_chain = class;
   return interface_chain;
@@ -5080,9 +5608,9 @@ add_category (class, category)
       tree class;
       tree category;
 {
-  /* put categories on list in reverse order */
-
+  /* Put categories on list in reverse order.  */
   tree cat = CLASS_CATEGORY_LIST (class);
+
   while (cat)
     {
       if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
@@ -5111,7 +5639,7 @@ add_instance_variable (class, public, declarator, declspecs, width)
 {
   tree field_decl, raw_decl;
 
-  raw_decl = build_tree_list (declspecs        /*purpose*/, declarator/*value*/);
+  raw_decl = build_tree_list (declspecs, declarator);
 
   if (CLASS_RAW_IVARS (class))
     chainon (CLASS_RAW_IVARS (class), raw_decl);
@@ -5121,7 +5649,7 @@ add_instance_variable (class, public, declarator, declspecs, width)
   field_decl = grokfield (input_filename, lineno,
                          declarator, declspecs, width);
 
-  /* overload the public attribute, it is not used for FIELD_DECL's */
+  /* Overload the public attribute, it is not used for FIELD_DECLs.  */
   switch (public)
     {
     case 0:
@@ -5180,7 +5708,7 @@ is_private (decl)
     return 0;
 }
 
-/* we have an instance variable reference, check to see if it is public...*/
+/* We have an instance variable reference;, check to see if it is public.  */
 
 int
 is_public (expr, identifier)
@@ -5207,7 +5735,7 @@ is_public (expr, identifier)
              if (TREE_PUBLIC (decl))
                return 1;
 
-             /* important difference between the Stepstone translator:
+             /* Important difference between the Stepstone translator:
                 all instance variables should be public within the context
                 of the implementation.  */
              if (implementation_context
@@ -5225,16 +5753,18 @@ is_public (expr, identifier)
              return 0;
            }
        }
+
       else if (implementation_context && (basetype == objc_object_reference))
        {
          TREE_TYPE (expr) = uprivate_record;
          warning ("static access to object of type `id'");
        }
     }
+
   return 1;
 }
 
-/* implement @defs (<classname>) within struct bodies. */
+/* Implement @defs (<classname>) within struct bodies.  */
 
 tree
 get_class_ivars (interface)
@@ -5246,7 +5776,7 @@ get_class_ivars (interface)
   return build_ivar_chain (interface, 1);
 }
 \f
-/* make sure all entries in "chain" are also in "list" */
+/* Make sure all entries in CHAIN are also in LIST.  */
 
 static int
 check_methods (chain, list, mtype)
@@ -5262,32 +5792,39 @@ check_methods (chain, list, mtype)
        {
          if (first)
            {
-             if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+             if (TREE_CODE (implementation_context)
+                 == CLASS_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of class `%s'",
                         IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
-             else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
+             else if (TREE_CODE (implementation_context)
+                      == CATEGORY_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of category `%s'",
                         IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
              first = 0;
            }
+
          warning ("method definition for `%c%s' not found",
                   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
        }
+
       chain = TREE_CHAIN (chain);
     }
+
     return first;
 }
 
 static int
 conforms_to_protocol (class, protocol)
-tree class;
-tree protocol;
+     tree class;
+     tree protocol;
 {
    while (protocol)
      {
        tree p = CLASS_PROTOCOL_LIST (class);
+
        while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
         p = TREE_CHAIN (p);
+
        if (!p)
         {
           tree super = (CLASS_SUPER_NAME (class)
@@ -5297,26 +5834,29 @@ tree protocol;
           if (!tmp)
             return 0;
         }
+
        protocol = TREE_CHAIN (protocol);
      }
+
    return 1;
 }
 
 /* Make sure all methods in CHAIN are accessible as MTYPE methods in 
-   CONTEXT.  This is one of two mechanisms to check protocol integrity
-*/
+   CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
 
 static int
 check_methods_accessible (chain, context, mtype)
      tree chain;
-     tree context; /* implementation_context */
+     tree context;
      int mtype;
 {
   int first = 1;
   tree list;
+  tree base_context = context;
 
   while (chain)
     {
+      context = base_context;
       while (context)
        {
          if (mtype == '+')
@@ -5327,12 +5867,14 @@ check_methods_accessible (chain, context, mtype)
          if (lookup_method (list, chain))
              break; 
 
-         else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE) 
+         else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
+                  || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
            context = (CLASS_SUPER_NAME (context) 
                       ? lookup_interface (CLASS_SUPER_NAME (context))
                       : NULL_TREE);
 
-         else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE)
+         else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
+                  || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
            context = (CLASS_NAME (context) 
                       ? lookup_interface (CLASS_NAME (context))
                       : NULL_TREE);
@@ -5360,7 +5902,7 @@ check_methods_accessible (chain, context, mtype)
                   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
        }
 
-      chain = TREE_CHAIN (chain); /* next method... */
+      chain = TREE_CHAIN (chain); /* next method...  */
     }
     return first;
 }
@@ -5379,7 +5921,7 @@ check_protocols (proto_list, type, name)
        {
          int f1, f2;
          
-         /* Ensure that all protocols have bodies! */
+         /* Ensure that all protocols have bodies */
          if (flag_warn_protocol) {
            f1 = check_methods (PROTOCOL_CLS_METHODS (p),
                                CLASS_CLS_METHODS (implementation_context),
@@ -5402,9 +5944,9 @@ check_protocols (proto_list, type, name)
 
        }
       else
-       ; /* an identifier...if we could not find a protocol.  */
+       ; /* An identifier if we could not find a protocol.  */
 
-      /* Check protocols recursively. */
+      /* Check protocols recursively.  */
       if (PROTOCOL_LIST (p))
        {
          tree super_class
@@ -5467,24 +6009,27 @@ start_class (code, class_name, super_name, protocol_list)
                      IDENTIFIER_POINTER (class_name));
               return error_mark_node;
             }
-        implemented_classes = perm_tree_cons (NULLT, class_name,
+        implemented_classes = perm_tree_cons (NULL_TREE, class_name,
                                              implemented_classes);
       }
 
-      /* pre-build the following entities - for speed/convenience. */
+      /* Pre-build the following entities - for speed/convenience.  */
       if (!self_id)
-        self_id = get_identifier ("self");
+         self_id = get_identifier ("self");
       if (!ucmd_id)
         ucmd_id = get_identifier ("_cmd");
-
+      if (!unused_list)
+       unused_list
+         = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
       if (!objc_super_template)
        objc_super_template = build_super_template ();
 
-      method_slot = 0;         /* reset for multiple classes per file */
+      /* Reset for multiple classes per file.  */
+      method_slot = 0;
 
       implementation_context = class;
 
-      /* lookup the interface for this implementation. */
+      /* Lookup the interface for this implementation.  */
 
       if (!(implementation_template = lookup_interface (class_name)))
         {
@@ -5493,8 +6038,8 @@ start_class (code, class_name, super_name, protocol_list)
          add_class (implementation_template = implementation_context);
         }
 
-      /* if a super class has been specified in the implementation,
-        insure it conforms to the one specified in the interface */
+      /* If a super class has been specified in the implementation,
+        insure it conforms to the one specified in the interface */
 
       if (super_name
          && (super_name != CLASS_SUPER_NAME (implementation_template)))
@@ -5505,12 +6050,14 @@ start_class (code, class_name, super_name, protocol_list)
                 IDENTIFIER_POINTER (super_name));
          error ("previous declaration of `%s'", name);
         }
+
       else if (! super_name)
        {
          CLASS_SUPER_NAME (implementation_context) 
            = CLASS_SUPER_NAME (implementation_template);
        }
     }
+
   else if (code == CLASS_INTERFACE_TYPE)
     {
       if (lookup_interface (class_name))
@@ -5523,19 +6070,20 @@ start_class (code, class_name, super_name, protocol_list)
        CLASS_PROTOCOL_LIST (class)
          = lookup_and_install_protocols (protocol_list);
     }
+
   else if (code == CATEGORY_INTERFACE_TYPE)
     {
       tree class_category_is_assoc_with;
 
-      /* for a category, class_name is really the name of the class that
-        the following set of methods will be associated with...we must
-        find the interface so that can derive the objects template */
+      /* For a category, class_name is really the name of the class that
+        the following set of methods will be associated with. We must
+        find the interface so that can derive the objects template */
 
       if (!(class_category_is_assoc_with = lookup_interface (class_name)))
        {
          error ("Cannot find interface declaration for `%s'",
                 IDENTIFIER_POINTER (class_name));
-         exit (1);
+         exit (FATAL_EXIT_CODE);
        }
       else
         add_category (class_category_is_assoc_with, class);
@@ -5544,30 +6092,34 @@ start_class (code, class_name, super_name, protocol_list)
        CLASS_PROTOCOL_LIST (class)
          = lookup_and_install_protocols (protocol_list);
     }
+
   else if (code == CATEGORY_IMPLEMENTATION_TYPE)
     {
-      /* pre-build the following entities - for speed/convenience. */
+      /* Pre-build the following entities for speed/convenience.  */
       if (!self_id)
         self_id = get_identifier ("self");
       if (!ucmd_id)
         ucmd_id = get_identifier ("_cmd");
-
+      if (!unused_list)
+       unused_list
+         = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
       if (!objc_super_template)
        objc_super_template = build_super_template ();
 
-      method_slot = 0;         /* reset for multiple classes per file */
+      /* Reset for multiple classes per file.  */
+      method_slot = 0;
 
       implementation_context = class;
 
-      /* for a category, class_name is really the name of the class that
-        the following set of methods will be associated with...we must
-        find the interface so that can derive the objects template */
+      /* For a category, class_name is really the name of the class that
+        the following set of methods will be associated with.  We must
+        find the interface so that can derive the objects template */
 
       if (!(implementation_template = lookup_interface (class_name)))
         {
          error ("Cannot find interface declaration for `%s'",
                 IDENTIFIER_POINTER (class_name));
-         exit (1);
+         exit (FATAL_EXIT_CODE);
         }
     }
   return class;
@@ -5583,7 +6135,7 @@ continue_class (class)
       struct imp_entry *imp_entry;
       tree ivar_context;
 
-      /* check consistency of the instance variables. */
+      /* Check consistency of the instance variables.  */
 
       if (CLASS_IVARS (class))
        check_ivars (implementation_template, class);
@@ -5595,7 +6147,8 @@ continue_class (class)
       if (!objc_class_template)
        build_class_template ();
 
-      if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
+      if (!(imp_entry
+           = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
        perror ("unable to allocate in objc-tree.c");
 
       imp_entry->next = imp_list;
@@ -5606,7 +6159,7 @@ continue_class (class)
       imp_entry->class_decl = UOBJC_CLASS_decl;
       imp_entry->meta_decl = UOBJC_METACLASS_decl;
 
-      /* append to front and increment count */
+      /* Append to front and increment count.  */
       imp_list = imp_entry;
       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
        imp_count++;
@@ -5615,20 +6168,23 @@ continue_class (class)
 
       return ivar_context;
     }
+
   else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
     {
       tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
 
       if (!TYPE_FIELDS (record))
        {
-         finish_struct (record, build_ivar_chain (class, 0));
+         finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
          CLASS_STATIC_TEMPLATE (class) = record;
 
-         /* mark this record as a class template - for static typing */
+         /* Mark this record as a class template for static typing.  */
          TREE_STATIC_TEMPLATE (record) = 1;
        }
-      return NULLT;
+
+      return NULL_TREE;
     }
+
   else
     return error_mark_node;
 }
@@ -5641,11 +6197,11 @@ finish_class (class)
 {
   if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
     {
-      /* all code generation is done in finish_objc */
+      /* All code generation is done in finish_objc.  */
 
       if (implementation_template != implementation_context)
        {
-         /* ensure that all method listed in the interface contain bodies! */
+         /* Ensure that all method listed in the interface contain bodies.  */
          check_methods (CLASS_CLS_METHODS (implementation_template),
                         CLASS_CLS_METHODS (implementation_context), '+');
          check_methods (CLASS_NST_METHODS (implementation_template),
@@ -5657,11 +6213,12 @@ finish_class (class)
                             IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
        }
     }
+
   else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
     {
       tree category = CLASS_CATEGORY_LIST (implementation_template);
 
-      /* find the category interface from the class it is associated with */
+      /* Find the category interface from the class it is associated with.  */
       while (category)
        {
          if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
@@ -5671,7 +6228,7 @@ finish_class (class)
 
       if (category)
        {
-         /* ensure that all method listed in the interface contain bodies! */
+         /* Ensure all method listed in the interface contain bodies.  */
          check_methods (CLASS_CLS_METHODS (category),
                         CLASS_CLS_METHODS (implementation_context), '+');
          check_methods (CLASS_NST_METHODS (category),
@@ -5683,6 +6240,7 @@ finish_class (class)
                             IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
        }
     }
+
   else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
     {
       tree decl_specs;
@@ -5693,9 +6251,9 @@ finish_class (class)
 
       sprintf (string, "_%s", class_name);
 
-      decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
-      decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
-      define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
+      decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
+      decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
+      define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
                   decl_specs);
     }
 }
@@ -5704,7 +6262,7 @@ static tree
 add_protocol (protocol)
      tree protocol;
 {
-  /* put protocol on list in reverse order */
+  /* Put protocol on list in reverse order.  */
   TREE_CHAIN (protocol) = protocol_chain;
   protocol_chain = protocol;
   return protocol_chain;
@@ -5721,7 +6279,8 @@ lookup_protocol (ident)
       if (ident == PROTOCOL_NAME (chain))
        return chain;
     }
-  return NULLT;
+
+  return NULL_TREE;
 }
 
 tree
@@ -5776,17 +6335,17 @@ encode_type_qualifiers (declspecs)
 
   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
     {
-      if (ridpointers[RID_CONST] == TREE_VALUE (spec))
+      if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'r');
-      else if (ridpointers[RID_IN] == TREE_VALUE (spec))
+      else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'n');
-      else if (ridpointers[RID_INOUT] == TREE_VALUE (spec))
+      else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'N');
-      else if (ridpointers[RID_OUT] == TREE_VALUE (spec))
+      else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'o');
-      else if (ridpointers[RID_BYCOPY] == TREE_VALUE (spec))
+      else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'O');
-      else if (ridpointers[RID_ONEWAY] == TREE_VALUE (spec))
+      else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'V');
     }
 }
@@ -5850,7 +6409,7 @@ encode_pointer (type, curtype, format)
       return;
     }
 
-  /* we have a type that does not get special treatment... */
+  /* We have a type that does not get special treatment.  */
 
   /* NeXT extension */
   obstack_1grow (&util_obstack, '^');
@@ -5870,7 +6429,6 @@ encode_array (type, curtype, format)
   /* An incomplete array is treated like a pointer.  */
   if (an_int_cst == NULL)
     {
-      /* split for obvious reasons.  North-Keys 30 Mar 1991 */
       encode_pointer (type, curtype, format);
       return;
     }
@@ -5878,6 +6436,7 @@ encode_array (type, curtype, format)
   sprintf (buffer, "[%d",
           (TREE_INT_CST_LOW (an_int_cst)
            / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+
   obstack_grow (&util_obstack, buffer, strlen (buffer));
   encode_type (array_of, curtype, format);
   obstack_1grow (&util_obstack, ']');
@@ -5885,135 +6444,139 @@ encode_array (type, curtype, format)
 }
 \f
 static void
-encode_aggregate (type, curtype, format)
+encode_aggregate_within (type, curtype, format, left, right)
      tree type;
      int curtype;
      int format;
+     char left;
+     char right;
 {
-  enum tree_code code = TREE_CODE (type);
+  if (obstack_object_size (&util_obstack) > 0
+      && *(obstack_next_free (&util_obstack) - 1) == '^')
+    {
+      tree name = TYPE_NAME (type);
 
-  switch (code)
+      /* we have a reference; this is a NeXT extension. */
+
+      if (obstack_object_size (&util_obstack) - curtype == 1
+         && format == OBJC_ENCODE_INLINE_DEFS)
+       {
+         /* Output format of struct for first level only. */
+         tree fields = TYPE_FIELDS (type);
+
+         if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+           {
+             obstack_1grow (&util_obstack, left);
+             obstack_grow (&util_obstack,
+                           IDENTIFIER_POINTER (name),
+                           strlen (IDENTIFIER_POINTER (name)));
+             obstack_1grow (&util_obstack, '=');
+           }
+         else
+           {
+             obstack_1grow (&util_obstack, left);
+             obstack_grow (&util_obstack, "?=", 2);
+           }
+
+         for ( ; fields; fields = TREE_CHAIN (fields))
+             encode_field_decl (fields, curtype, format);
+
+         obstack_1grow (&util_obstack, right);
+       }
+
+      else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+       {
+         obstack_1grow (&util_obstack, left);
+         obstack_grow (&util_obstack,
+                       IDENTIFIER_POINTER (name),
+                       strlen (IDENTIFIER_POINTER (name)));
+         obstack_1grow (&util_obstack, right);
+       }
+
+      else
+       {
+         /* We have an untagged structure or a typedef. */
+         obstack_1grow (&util_obstack, left);
+         obstack_1grow (&util_obstack, '?');
+         obstack_1grow (&util_obstack, right);
+       }
+    }
+
+  else
     {
-    case RECORD_TYPE:
-      {
-       if (obstack_object_size (&util_obstack) > 0
-           && *(obstack_next_free (&util_obstack) - 1) == '^')
-         {
-           tree name = TYPE_NAME (type);
+      tree name = TYPE_NAME (type);
+      tree fields = TYPE_FIELDS (type);
 
-           /* we have a reference - this is a NeXT extension */
+      if (format == OBJC_ENCODE_INLINE_DEFS
+         || generating_instance_variables)
+       {
+         obstack_1grow (&util_obstack, left);
+         if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+             obstack_grow (&util_obstack,
+                         IDENTIFIER_POINTER (name),
+                         strlen (IDENTIFIER_POINTER (name)));
+         else
+             obstack_1grow (&util_obstack, '?');
 
-           if (obstack_object_size (&util_obstack) - curtype == 1
-               && format == OBJC_ENCODE_INLINE_DEFS)
-             {
-               /* output format of struct for first level only! */
+         obstack_1grow (&util_obstack, '=');
 
-               tree fields = TYPE_FIELDS (type);
+         for (; fields; fields = TREE_CHAIN (fields))
+           {
+             if (generating_instance_variables)
+               {
+                 tree fname = DECL_NAME (fields);
 
-               if (name && TREE_CODE (name) == IDENTIFIER_NODE)
-                 {
-                   obstack_1grow (&util_obstack, '{');
-                   obstack_grow (&util_obstack,
-                                 IDENTIFIER_POINTER (name),
-                                 strlen (IDENTIFIER_POINTER (name)));
-                   obstack_1grow (&util_obstack, '=');
-                 }
-               else
-                 obstack_grow (&util_obstack, "{?=", 3);
+                 obstack_1grow (&util_obstack, '"');
+                 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
+                   {
+                     obstack_grow (&util_obstack,
+                                   IDENTIFIER_POINTER (fname),
+                                   strlen (IDENTIFIER_POINTER (fname)));
+                   }
 
-               for ( ; fields; fields = TREE_CHAIN (fields))
-                 encode_field_decl (fields, curtype, format);
-               obstack_1grow (&util_obstack, '}');
-             }
-            else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
-             {
-               obstack_1grow (&util_obstack, '{');
-               obstack_grow (&util_obstack,
-                             IDENTIFIER_POINTER (name),
-                             strlen (IDENTIFIER_POINTER (name)));
-               obstack_1grow (&util_obstack, '}');
-             }
-           else /* we have an untagged structure or a typedef */
-             obstack_grow (&util_obstack, "{?}", 3);
-         }
-       else
-         {
-           tree name = TYPE_NAME (type);
-           tree fields = TYPE_FIELDS (type);
+                 obstack_1grow (&util_obstack, '"');
+               }
 
-           if (format == OBJC_ENCODE_INLINE_DEFS
-               || generating_instance_variables)
-             {
-               obstack_1grow (&util_obstack, '{');
-               if (name && TREE_CODE (name) == IDENTIFIER_NODE)
-                 obstack_grow (&util_obstack,
-                               IDENTIFIER_POINTER (name),
-                               strlen (IDENTIFIER_POINTER (name)));
-               else
-                 obstack_1grow (&util_obstack, '?');
+             encode_field_decl (fields, curtype, format);
+           }
 
-               obstack_1grow (&util_obstack, '=');
+         obstack_1grow (&util_obstack, right);
+       }
 
-               for (; fields; fields = TREE_CHAIN (fields))
-                 {
-                  if (generating_instance_variables)
-                    {
-                      tree fname = DECL_NAME (fields);
-
-                     obstack_1grow (&util_obstack, '"');
-                     if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
-                       {
-                       obstack_grow (&util_obstack,
-                                     IDENTIFIER_POINTER (fname),
-                                     strlen (IDENTIFIER_POINTER (fname)));
-                       }
-                     obstack_1grow (&util_obstack, '"');
-                    }
-                 encode_field_decl (fields, curtype, format);
-                 }
-               obstack_1grow (&util_obstack, '}');
-             }
-           else
-             {
-               obstack_1grow (&util_obstack, '{');
-               if (name && TREE_CODE (name) == IDENTIFIER_NODE)
-                 obstack_grow (&util_obstack,
-                               IDENTIFIER_POINTER (name),
-                               strlen (IDENTIFIER_POINTER (name)));
-               else    /* we have an untagged structure or a typedef */
-                 obstack_1grow (&util_obstack, '?');
-               obstack_1grow (&util_obstack, '}');
-             }
-         }
+      else
+       {
+         obstack_1grow (&util_obstack, left);
+         if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+             obstack_grow (&util_obstack,
+                           IDENTIFIER_POINTER (name),
+                           strlen (IDENTIFIER_POINTER (name)));
+         else
+             /* We have an untagged structure or a typedef. */
+             obstack_1grow (&util_obstack, '?');
+
+         obstack_1grow (&util_obstack, right);
+       }
+    }
+}
+
+static void
+encode_aggregate (type, curtype, format)
+     tree type;
+     int curtype;
+     int format;
+{
+  enum tree_code code = TREE_CODE (type);
+
+  switch (code)
+    {
+    case RECORD_TYPE:
+      {
+       encode_aggregate_within(type, curtype, format, '{', '}');
        break;
       }
     case UNION_TYPE:
       {
-       if (*obstack_next_free (&util_obstack) == '^'
-           || format != OBJC_ENCODE_INLINE_DEFS)
-         {
-           /* we have a reference - this is a NeXT extension--
-              or we don't want the details.  */
-            if (TYPE_NAME (type)
-               && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
-             {
-               obstack_1grow (&util_obstack, '(');
-               obstack_grow (&util_obstack,
-                             IDENTIFIER_POINTER (TYPE_NAME (type)),
-                             strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
-               obstack_1grow (&util_obstack, ')');
-             }
-           else /* we have an untagged structure or a typedef */
-             obstack_grow (&util_obstack, "(?)", 3);
-         }
-       else
-         {
-           tree fields = TYPE_FIELDS (type);
-           obstack_1grow (&util_obstack, '(');
-           for ( ; fields; fields = TREE_CHAIN (fields))
-             encode_field_decl (fields, curtype, format);
-           obstack_1grow (&util_obstack, ')');
-         }
+       encode_aggregate_within(type, curtype, format, '(', ')');
        break;
       }
 
@@ -6023,11 +6586,11 @@ encode_aggregate (type, curtype, format)
     }
 }
 
-/* Support bitfields, the current version of Objective-C does not support
-   them. the string will consist of one or more "b:n"'s where n is an
+/* Support bitfields.  The current version of Objective-C does not support
+   them.  The string will consist of one or more "b:n"'s where n is an
    integer describing the width of the bitfield. Currently, classes in
    the kit implement a method "-(char *)describeBitfieldStruct:" that
-   simulates this...if they do not implement this method, the archiver
+   simulates this. If they do not implement this method, the archiver
    assumes the bitfield is 16 bits wide (padded if necessary) and packed
    according to the GNU compiler. After looking at the "kit", it appears
    that all classes currently rely on this default behavior, rather than
@@ -6055,49 +6618,58 @@ encode_type (type, curtype, format)
 
   if (code == INTEGER_TYPE)
     {
-      if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
+      if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
+         && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
        {
-         /* unsigned integer types */
+         /* Unsigned integer types.  */
 
-         if (TYPE_MODE (type) == QImode) /* 'C' */
+         if (TYPE_MODE (type) == QImode)
            obstack_1grow (&util_obstack, 'C');
-         else if (TYPE_MODE (type) == HImode) /* 'S' */
+         else if (TYPE_MODE (type) == HImode)
            obstack_1grow (&util_obstack, 'S');
          else if (TYPE_MODE (type) == SImode)
            {
              if (type == long_unsigned_type_node)
-               obstack_1grow (&util_obstack, 'L'); /* 'L' */
+               obstack_1grow (&util_obstack, 'L');
              else
-               obstack_1grow (&util_obstack, 'I'); /* 'I' */
+               obstack_1grow (&util_obstack, 'I');
            }
+         else if (TYPE_MODE (type) == DImode)
+           obstack_1grow (&util_obstack, 'Q');
        }
-      else                     /* signed integer types */
+
+      else
+       /* Signed integer types.  */
        {
-         if (TYPE_MODE (type) == QImode) /* 'c' */
+         if (TYPE_MODE (type) == QImode)
            obstack_1grow (&util_obstack, 'c');
-         else if (TYPE_MODE (type) == HImode) /* 's' */
+         else if (TYPE_MODE (type) == HImode)
            obstack_1grow (&util_obstack, 's');
-         else if (TYPE_MODE (type) == SImode) /* 'i' */
+         else if (TYPE_MODE (type) == SImode)
            {
              if (type == long_integer_type_node)
-               obstack_1grow (&util_obstack, 'l'); /* 'l' */
+               obstack_1grow (&util_obstack, 'l');
              else
-               obstack_1grow (&util_obstack, 'i'); /* 'i' */
+               obstack_1grow (&util_obstack, 'i');
            }
+
+         else if (TYPE_MODE (type) == DImode)
+           obstack_1grow (&util_obstack, 'q');
        }
     }
+
   else if (code == REAL_TYPE)
     {
-      /* floating point types */
+      /* Floating point types.  */
 
-      if (TYPE_MODE (type) == SFmode) /* 'f' */
+      if (TYPE_MODE (type) == SFmode)
        obstack_1grow (&util_obstack, 'f');
       else if (TYPE_MODE (type) == DFmode
-              || TYPE_MODE (type) == TFmode) /* 'd' */
+              || TYPE_MODE (type) == TFmode)
        obstack_1grow (&util_obstack, 'd');
     }
 
-  else if (code == VOID_TYPE)  /* 'v' */
+  else if (code == VOID_TYPE)
     obstack_1grow (&util_obstack, 'v');
 
   else if (code == ARRAY_TYPE)
@@ -6123,7 +6695,7 @@ encode_field_decl (field_decl, curtype, format)
 
  /* If this field is obviously a bitfield, or is a bitfield that has been
      clobbered to look like a ordinary integer mode, go ahead and generate
-     the bitfield typing information. */
+     the bitfield typing information.  */
   type = TREE_TYPE (field_decl);
   if (DECL_BIT_FIELD (field_decl))
     encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
@@ -6144,6 +6716,7 @@ expr_last (complex_expr)
   if (complex_expr)
     while ((next = TREE_OPERAND (complex_expr, 0)))
       complex_expr = next;
+
   return complex_expr;
 }
 \f
@@ -6171,35 +6744,41 @@ start_method_def (method)
 
   /* Required to implement _msgSuper.  */
   method_context = method;
-  UOBJC_SUPER_decl = NULLT;
+  UOBJC_SUPER_decl = NULL_TREE;
 
-  pushlevel (0);               /* Must be called BEFORE start_function.  */
+  /* Must be called BEFORE start_function.  */
+  pushlevel (0);
 
   /* Generate prototype declarations for arguments..."new-style".  */
 
   if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
-    decl_specs = build_tree_list (NULLT, uprivate_record);
+    decl_specs = build_tree_list (NULL_TREE, uprivate_record);
   else
-    /* really a `struct objc_class *'...however we allow people to
-       assign to self...which changes its type midstream.  */
-    decl_specs = build_tree_list (NULLT, objc_object_reference);
+    /* Really a `struct objc_class *'. However, we allow people to
+       assign to selfwhich changes its type midstream.  */
+    decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
 
-  push_parm_decl (build_tree_list (decl_specs,
-                                  build1 (INDIRECT_REF, NULLT, self_id)));
+  push_parm_decl (build_tree_list
+                 (build_tree_list (decl_specs,
+                                   build1 (INDIRECT_REF, NULL_TREE, self_id)),
+                  build_tree_list (unused_list, NULL_TREE)));
 
 #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);
-  push_parm_decl (build_tree_list (decl_specs, ucmd_id));
+  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
+  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
+  push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
+                                  build_tree_list (unused_list, NULL_TREE)));
 #else /* not OBJC_INT_SELECTORS */
-  decl_specs = build_tree_list (NULLT,
+  decl_specs = build_tree_list (NULL_TREE,
                                xref_tag (RECORD_TYPE,
                                          get_identifier (TAG_SELECTOR)));
-  push_parm_decl (build_tree_list (decl_specs,
-                                  build1 (INDIRECT_REF, NULLT, ucmd_id)));
+  push_parm_decl (build_tree_list
+                 (build_tree_list (decl_specs,
+                                   build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
+                  build_tree_list (unused_list, NULL_TREE)));
 #endif /* not OBJC_INT_SELECTORS */
 
-  /* generate argument declarations if a keyword_decl */
+  /* Generate argument declarations if a keyword_decl.  */
   if (METHOD_SEL_ARGS (method))
     {
       tree arglist = METHOD_SEL_ARGS (method);
@@ -6212,15 +6791,21 @@ start_method_def (method)
            {
              tree last_expr = expr_last (arg_decl);
 
-             /* unite the abstract decl with its name */
+             /* Unite the abstract decl with its name.  */
              TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
-             push_parm_decl (build_tree_list (arg_spec, arg_decl));
-             /* unhook...restore the abstract declarator */
-             TREE_OPERAND (last_expr, 0) = NULLT;
+             push_parm_decl (build_tree_list
+                             (build_tree_list (arg_spec, arg_decl),
+                              build_tree_list (NULL_TREE, NULL_TREE)));
+
+             /* Unhook: restore the abstract declarator.  */
+             TREE_OPERAND (last_expr, 0) = NULL_TREE;
            }
+
          else
-           push_parm_decl (build_tree_list (arg_spec,
-                                            KEYWORD_ARG_NAME (arglist)));
+           push_parm_decl (build_tree_list
+                           (build_tree_list (arg_spec,
+                                             KEYWORD_ARG_NAME (arglist)),
+                            build_tree_list (NULL_TREE, NULL_TREE)));
 
          arglist = TREE_CHAIN (arglist);
        }
@@ -6229,7 +6814,7 @@ start_method_def (method)
 
   if (METHOD_ADD_ARGS (method) > (tree)1)
     {
-      /* we have a variable length selector - in "prototype" format */
+      /* We have a variable length selector - in "prototype" format.  */
       tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
       while (akey)
        {
@@ -6245,7 +6830,7 @@ start_method_def (method)
 static void
 warn_with_method (message, mtype, method)
      char *message;
-     char mtype;
+     int mtype;
      tree method;
 {
   if (count_error (1) == 0)
@@ -6260,7 +6845,7 @@ warn_with_method (message, mtype, method)
           message, mtype, gen_method_decl (method, errbuf));
 }
 
-/* return 1 if `method' is consistent with `proto' */
+/* Return 1 if METHOD is consistent with PROTO.  */
 
 static int
 comp_method_with_proto (method, proto)
@@ -6268,14 +6853,13 @@ comp_method_with_proto (method, proto)
 {
   static tree function_type = 0;
 
-  /* create a function_type node once */
+  /* Create a function_type node once.  */
   if (!function_type)
     {
-      struct obstack *ambient_obstack = current_obstack;
-
-      current_obstack = &permanent_obstack;
+      push_obstacks_nochange ();
+      end_temporary_allocation ();
       function_type = make_node (FUNCTION_TYPE);
-      current_obstack = ambient_obstack;
+      pop_obstacks ();
     }
 
   /* Install argument types - normally set by build_function_type.  */
@@ -6287,7 +6871,7 @@ comp_method_with_proto (method, proto)
   return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
 }
 
-/* return 1 if `proto1' is consistent with `proto2' */
+/* Return 1 if PROTO1 is consistent with PROTO2.  */
 
 static int
 comp_proto_with_proto (proto1, proto2)
@@ -6295,33 +6879,32 @@ comp_proto_with_proto (proto1, proto2)
 {
   static tree function_type1 = 0, function_type2 = 0;
 
-  /* create a couple function_type node's once */
+  /* Create a couple function_type node's once.  */
   if (!function_type1)
     {
-      struct obstack *ambient_obstack = current_obstack;
-
-      current_obstack = &permanent_obstack;
+      push_obstacks_nochange ();
+      end_temporary_allocation ();
       function_type1 = make_node (FUNCTION_TYPE);
       function_type2 = make_node (FUNCTION_TYPE);
-      current_obstack = ambient_obstack;
+      pop_obstacks ();
     }
 
-  /* Install argument types - normally set by build_function_type.  */
+  /* Install argument types; normally set by build_function_type.  */
   TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
   TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
 
-  /* install return type */
+  /* Install return type.  */
   TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
   TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
 
   return comptypes (function_type1, function_type2);
 }
 
-/* - generate an identifier for the function. the format is "_n_cls",
+/* - Generate an identifier for the function. the format is "_n_cls",
      where 1 <= n <= nMethods, and cls is the name the implementation we
      are processing.
-   - install the return type from the method declaration.
-   - if we have a prototype, check for type consistency.  */
+   - Install the return type from the method declaration.
+   - If we have a prototype, check for type consistency.  */
 
 static void
 really_start_method (method, parmlist)
@@ -6331,8 +6914,8 @@ really_start_method (method, parmlist)
   tree method_decl, method_id;
   char *buf, *sel_name, *class_name, *cat_name;
 
-  /* synth the storage class & assemble the return type */
-  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
+  /* Synth the storage class & assemble the return type.  */
+  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
   ret_spec = TREE_PURPOSE (TREE_TYPE (method));
   decl_specs = chainon (sc_spec, ret_spec);
 
@@ -6343,6 +6926,7 @@ really_start_method (method, parmlist)
              ? NULL
              : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
   method_slot++;
+
   /* Make sure this is big enough for any plausible method label.  */
   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
                         + (cat_name ? strlen (cat_name) : 0));
@@ -6352,35 +6936,38 @@ really_start_method (method, parmlist)
 
   method_id = get_identifier (buf);
 
-  method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
+  method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
 
-  /* check the declarator portion of the return type for the method */
+  /* Check the declarator portion of the return type for the method.  */
   if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
     {
-      /* unite the complex decl (specified in the abstract decl) with the
+      /* Unite the complex decl (specified in the abstract decl) with the
         function decl just synthesized..(int *), (int (*)()), (int (*)[]).  */
       tree save_expr = expr_last (ret_decl);
 
       TREE_OPERAND (save_expr, 0) = method_decl;
       method_decl = ret_decl;
-      /* fool the parser into thinking it is starting a function */
-      start_function (decl_specs, method_decl, 0);
-      /* unhook...this has the effect of restoring the abstract declarator */
-      TREE_OPERAND (save_expr, 0) = NULLT;
+
+      /* Fool the parser into thinking it is starting a function.  */
+      start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+
+      /* Unhook: this has the effect of restoring the abstract declarator.  */
+      TREE_OPERAND (save_expr, 0) = NULL_TREE;
     }
+
   else
     {
       TREE_VALUE (TREE_TYPE (method)) = method_decl;
-      /* fool the parser into thinking it is starting a function */
-      start_function (decl_specs, method_decl, 0);
-      /* unhook...this has the effect of restoring the abstract declarator */
-      TREE_VALUE (TREE_TYPE (method)) = NULLT;
+
+      /* Fool the parser into thinking it is starting a function.  */
+      start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+
+      /* Unhook: this has the effect of restoring the abstract declarator.  */
+      TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
     }
 
   METHOD_DEFINITION (method) = current_function_decl;
 
-  /* Check consistency...start_function, pushdecl, duplicate_decls.  */
-
   if (implementation_template != implementation_context)
     {
       tree proto;
@@ -6422,11 +7009,9 @@ continue_method_def ()
      build_ivar_reference calling build_indirect_ref.  */
   self_decl = TREE_PURPOSE (parmlist);
 
-  poplevel (0, 0, 0);          /* must be called BEFORE start_function.  */
-
+  poplevel (0, 0, 0);
   really_start_method (method_context, parmlist);
-
-  store_parm_decls ();         /* must be called AFTER start_function.  */
+  store_parm_decls ();
 }
 
 /* Called by the parser, from the `pushlevel' production.  */
@@ -6437,14 +7022,15 @@ add_objc_decls ()
   if (!UOBJC_SUPER_decl)
     {
       UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
-                                    build_tree_list (NULLT,
+                                    build_tree_list (NULL_TREE,
                                                      objc_super_template),
-                                    0);
+                                    0, NULL_TREE, NULL_TREE);
 
-      finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
+      finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
 
-      /* this prevents `unused variable' warnings when compiling with -Wall.  */
-      DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
+      /* This prevents `unused variable' warnings when compiling with -Wall.  */
+      TREE_USED (UOBJC_SUPER_decl) = 1;
+      DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
     }
 }
 
@@ -6461,12 +7047,12 @@ get_super_receiver ()
     {
       tree super_expr, super_expr_list;
 
-      /* set receiver to self */
+      /* Set receiver to self.  */
       super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
       super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
-      super_expr_list = build_tree_list (NULLT, super_expr);
+      super_expr_list = build_tree_list (NULL_TREE, super_expr);
 
-      /* set class to begin searching */
+      /* Set class to begin searching.  */
       super_expr = build_component_ref (UOBJC_SUPER_decl,
                                        get_identifier ("class"));
 
@@ -6481,12 +7067,14 @@ get_super_receiver ()
                                           ? ucls_super_ref
                                           : uucls_super_ref));
        }
-      else                     /* we have a category... */
+
+      else
+       /* We have a category.  */
        {
          tree super_name = CLASS_SUPER_NAME (implementation_template);
          tree super_class;
 
-         if (!super_name)  /* Barf if super used in a category of Object. */
+         if (!super_name)
            {
              error ("no super class declared in interface for `%s'",
                    IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
@@ -6510,15 +7098,16 @@ get_super_receiver ()
              super_class
                = build_function_call
                  (super_class,
-                  build_tree_list (NULLT,
-                                   my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
-                                                    IDENTIFIER_POINTER (super_name))));
+                  build_tree_list
+                  (NULL_TREE,
+                   my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
+                                    IDENTIFIER_POINTER (super_name))));
            }
 
-         /* cast! */
          TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
          super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
        }
+
       chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
 
       super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
@@ -6543,11 +7132,12 @@ encode_method_def (func_decl)
   char buffer[40];
   tree result;
 
-  /* return type */
+  /* Return type.  */
   encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
               obstack_object_size (&util_obstack),
               OBJC_ENCODE_INLINE_DEFS);
-  /* stack size */
+
+  /* Stack size.  */
   for (parms = DECL_ARGUMENTS (func_decl); parms;
        parms = TREE_CHAIN (parms))
     {
@@ -6555,7 +7145,7 @@ encode_method_def (func_decl)
                      + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
                         / BITS_PER_UNIT));
 
-      if (parm_end > max_parm_end)
+      if (!offset_is_register && parm_end > max_parm_end)
        max_parm_end = parm_end;
     }
 
@@ -6564,21 +7154,26 @@ encode_method_def (func_decl)
   sprintf (buffer, "%d", stack_size);
   obstack_grow (&util_obstack, buffer, strlen (buffer));
 
-  /* argument types */
+  /* Argument types.  */
   for (parms = DECL_ARGUMENTS (func_decl); parms;
        parms = TREE_CHAIN (parms))
     {
-      /* type */
+      /* Type.  */
       encode_type (TREE_TYPE (parms),
                   obstack_object_size (&util_obstack),
                   OBJC_ENCODE_INLINE_DEFS);
 
-      /* compute offset */
+      /* Compute offset.  */
       sprintf (buffer, "%d", forwarding_offset (parms));
+
+      /* Indicate register.  */
+      if (offset_is_register)
+       obstack_1grow (&util_obstack, '+');
+
       obstack_grow (&util_obstack, buffer, strlen (buffer));
     }
 
-  obstack_1grow (&util_obstack, 0);    /* null terminate string */
+  obstack_1grow (&util_obstack, 0);
   result = get_identifier (obstack_finish (&util_obstack));
   obstack_free (&util_obstack, util_firstobj);
   return result;
@@ -6591,9 +7186,9 @@ finish_method_def ()
 
   finish_function (0);
 
-  /* this must be done AFTER finish_function, since the optimizer may
-     find "may be used before set" errors.  */
-  method_context = NULLT;      /* required to implement _msgSuper.  */
+  /* Required to implement _msgSuper. This must be done AFTER finish_function,
+     since the optimizer may find "may be used before set" errors.  */
+  method_context = NULL_TREE;
 }
 
 int
@@ -6606,6 +7201,7 @@ lang_report_error_function (decl)
               IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
       return 1;
     }
+
   else
     return 0;
 }
@@ -6640,6 +7236,7 @@ adorn_decl (decl, str)
       else
        strcat (str, "[]");
     }
+
   else if (code == ARRAY_TYPE)
     {
       tree an_int_cst = TYPE_SIZE (decl);
@@ -6652,6 +7249,7 @@ adorn_decl (decl, str)
       else
        strcat (str, "[]");
     }
+
   else if (code == CALL_EXPR)
     {
       tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
@@ -6666,9 +7264,10 @@ adorn_decl (decl, str)
        }
       strcat (str, ")");
     }
+
   else if (code == FUNCTION_TYPE)
     {
-      tree chain  = TYPE_ARG_TYPES (decl); /* a list of types */
+      tree chain  = TYPE_ARG_TYPES (decl);
 
       strcat (str, "(");
       while (chain && TREE_VALUE (chain) != void_type_node)
@@ -6680,6 +7279,7 @@ adorn_decl (decl, str)
        }
       strcat (str, ")");
     }
+
   else if (code == INDIRECT_REF)
     {
       strcpy (tmpbuf, "*");
@@ -6703,6 +7303,7 @@ adorn_decl (decl, str)
       strcat (tmpbuf, str);
       strcpy (str, tmpbuf);
     }
+
   else if (code == POINTER_TYPE)
     {
       strcpy (tmpbuf, "*");
@@ -6740,7 +7341,7 @@ gen_declarator (decl, buf, name)
        case CALL_EXPR:
          op = TREE_OPERAND (decl, 0);
 
-         /* we have a pointer to a function or array...(*)(), (*)[] */
+         /* We have a pointer to a function or array...(*)(), (*)[] */
          if ((code == ARRAY_REF || code == CALL_EXPR)
              && op && TREE_CODE (op) == INDIRECT_REF)
            wrap = 1;
@@ -6764,15 +7365,15 @@ gen_declarator (decl, buf, name)
          strcpy (buf, name);
          str = buf;
 
-         /* this clause is done iteratively...rather than recursively */
+         /* This clause is done iteratively rather than recursively.  */
          do
            {
              op = (is_complex_decl (TREE_TYPE (decl))
-                   ? TREE_TYPE (decl) : NULLT);
+                   ? TREE_TYPE (decl) : NULL_TREE);
 
              adorn_decl (decl, str);
 
-             /* we have a pointer to a function or array...(*)(), (*)[] */
+             /* We have a pointer to a function or array...(*)(), (*)[] */
              if (code == POINTER_TYPE
                  && op && (TREE_CODE (op) == FUNCTION_TYPE
                            || TREE_CODE (op) == ARRAY_TYPE))
@@ -6784,21 +7385,25 @@ gen_declarator (decl, buf, name)
                }
 
              decl = (is_complex_decl (TREE_TYPE (decl))
-                     ? TREE_TYPE (decl) : NULLT);
+                     ? TREE_TYPE (decl) : NULL_TREE);
            }
-         while (decl && (code = TREE_CODE (decl)));
+
+         while (decl && (code = TREE_CODE (decl)))
+           ;
 
          break;
 
        case IDENTIFIER_NODE:
-         /* will only happen if we are processing a "raw" expr-decl. */
+         /* Will only happen if we are processing a "raw" expr-decl.  */
          strcpy (buf, IDENTIFIER_POINTER (decl));
          return buf;
        }
 
       return str;
     }
-  else                 /* we have an abstract declarator or a _DECL node */
+
+  else
+    /* We have an abstract declarator or a _DECL node.  */
     {
       strcpy (buf, name);
       return buf;
@@ -6840,7 +7445,9 @@ gen_declspecs (declspecs, buf, raw)
                      strcat (buf, " <");
                      while (chain)
                        {
-                         strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
+                         strcat (buf,
+                                 IDENTIFIER_POINTER
+                                 (PROTOCOL_NAME (TREE_VALUE (chain))));
                          chain = TREE_CHAIN (chain);
                          if (chain)
                            strcat (buf, ", ");
@@ -6848,9 +7455,11 @@ gen_declspecs (declspecs, buf, raw)
                      strcat (buf, ">");
                    }
                }
+
              else
                strcat (buf, "untagged struct");
            }
+
          else if (TREE_CODE (aspec) == UNION_TYPE)
            {
              if (TYPE_NAME (aspec))
@@ -6862,6 +7471,7 @@ gen_declspecs (declspecs, buf, raw)
              else
                strcat (buf, "untagged union");
            }
+
          else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
            {
              if (TYPE_NAME (aspec))
@@ -6873,11 +7483,10 @@ gen_declspecs (declspecs, buf, raw)
              else
                strcat (buf, "untagged enum");
            }
+
          else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
-           {
-             strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
-           }
-         /* NEW!!! */
+           strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
+
          else if (IS_ID (aspec))
            {
              tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
@@ -6890,7 +7499,9 @@ gen_declspecs (declspecs, buf, raw)
                  strcat (buf, " <");
                  while (chain)
                    {
-                     strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
+                     strcat (buf,
+                             IDENTIFIER_POINTER
+                             (PROTOCOL_NAME (TREE_VALUE (chain))));
                      chain = TREE_CHAIN (chain);
                      if (chain)
                        strcat (buf, ", ");
@@ -6904,67 +7515,127 @@ gen_declspecs (declspecs, buf, raw)
     }
   else
     {
-    /* type qualifiers */
-
-    if (TREE_READONLY (declspecs))
-      strcat (buf, "const ");
-    if (TYPE_VOLATILE (declspecs))
-      strcat (buf, "volatile ");
+      /* Type qualifiers.  */
+      if (TREE_READONLY (declspecs))
+       strcat (buf, "const ");
+      if (TYPE_VOLATILE (declspecs))
+       strcat (buf, "volatile ");
 
-    switch (TREE_CODE (declspecs))
-      {
-       /* type specifiers */
-
-      case INTEGER_TYPE:       /* signed integer types */
-       declspecs = TYPE_MAIN_VARIANT (declspecs);
-
-        if (declspecs == short_integer_type_node) /* 's' */
-          strcat (buf, "short int ");
-        else if (declspecs == integer_type_node) /* 'i' */
-          strcat (buf, "int ");
-        else if (declspecs == long_integer_type_node) /* 'l' */
-          strcat (buf, "long int ");
-       else if (declspecs == long_long_integer_type_node) /* 'l' */
-         strcat (buf, "long long int ");
-        else if (declspecs == signed_char_type_node /* 'c' */
-                || declspecs == char_type_node)
-          strcat (buf, "char ");
-
-        /* unsigned integer types */
-
-        else if (declspecs == short_unsigned_type_node)        /* 'S' */
-          strcat (buf, "unsigned short ");
-        else if (declspecs == unsigned_type_node) /* 'I' */
-          strcat (buf, "unsigned int ");
-        else if (declspecs == long_unsigned_type_node) /* 'L' */
-          strcat (buf, "unsigned long ");
-       else if (declspecs == long_long_unsigned_type_node) /* 'L' */
-         strcat (buf, "unsigned long long ");
-        else if (declspecs == unsigned_char_type_node) /* 'C' */
-          strcat (buf, "unsigned char ");
-       break;
+      switch (TREE_CODE (declspecs))
+       {
+         /* Type specifiers.  */
+
+       case INTEGER_TYPE:
+         declspecs = TYPE_MAIN_VARIANT (declspecs);
+
+         /* Signed integer types.  */
+
+         if (declspecs == short_integer_type_node)
+           strcat (buf, "short int ");
+         else if (declspecs == integer_type_node)
+           strcat (buf, "int ");
+         else if (declspecs == long_integer_type_node)
+           strcat (buf, "long int ");
+         else if (declspecs == long_long_integer_type_node)
+           strcat (buf, "long long int ");
+         else if (declspecs == signed_char_type_node
+                  || declspecs == char_type_node)
+           strcat (buf, "char ");
+
+         /* Unsigned integer types.  */
+
+         else if (declspecs == short_unsigned_type_node)
+           strcat (buf, "unsigned short ");
+         else if (declspecs == unsigned_type_node)
+           strcat (buf, "unsigned int ");
+         else if (declspecs == long_unsigned_type_node)
+           strcat (buf, "unsigned long ");
+         else if (declspecs == long_long_unsigned_type_node)
+           strcat (buf, "unsigned long long ");
+         else if (declspecs == unsigned_char_type_node)
+           strcat (buf, "unsigned char ");
+         break;
 
-      case REAL_TYPE:          /* floating point types */
-        declspecs = TYPE_MAIN_VARIANT (declspecs);
+       case REAL_TYPE:
+         declspecs = TYPE_MAIN_VARIANT (declspecs);
 
-        if (declspecs == float_type_node) /* 'f' */
-          strcat (buf, "float ");
-        else if (declspecs == double_type_node)        /* 'd' */
-          strcat (buf, "double ");
-       else if (declspecs == long_double_type_node) /* 'd' */
-          strcat (buf, "long double ");
-       break;
+         if (declspecs == float_type_node)
+           strcat (buf, "float ");
+         else if (declspecs == double_type_node)
+           strcat (buf, "double ");
+         else if (declspecs == long_double_type_node)
+           strcat (buf, "long double ");
+         break;
 
       case RECORD_TYPE:
-       if (TYPE_NAME (declspecs)
-           && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+         if (TYPE_NAME (declspecs)
+             && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+           {
+             tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
+
+             if (! TREE_STATIC_TEMPLATE (declspecs))
+               strcat (buf, "struct ");
+             strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+
+             if (protocol_list)
+               {
+                 tree chain = protocol_list;
+
+                 strcat (buf, " <");
+                 while (chain)
+                   {
+                     strcat (buf,
+                             IDENTIFIER_POINTER
+                             (PROTOCOL_NAME (TREE_VALUE (chain))));
+                     chain = TREE_CHAIN (chain);
+                     if (chain)
+                       strcat (buf, ", ");
+                   }
+                 strcat (buf, ">");
+               }
+           }
+
+         else
+           strcat (buf, "untagged struct");
+
+         strcat (buf, " ");
+         break;
+
+       case UNION_TYPE:
+         if (TYPE_NAME (declspecs)
+             && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+           {
+             strcat (buf, "union ");
+             strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+             strcat (buf, " ");
+           }
+
+         else
+           strcat (buf, "untagged union ");
+         break;
+
+       case ENUMERAL_TYPE:
+         if (TYPE_NAME (declspecs)
+             && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+           {
+             strcat (buf, "enum ");
+             strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+             strcat (buf, " ");
+           }
+
+         else
+           strcat (buf, "untagged enum ");
+         break;
+
+       case VOID_TYPE:
+         strcat (buf, "void ");
+         break;
+
+       case POINTER_TYPE:
          {
            tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
 
-           if (! TREE_STATIC_TEMPLATE (declspecs))
-             strcat (buf, "struct ");
-           strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
-           /* NEW!!! */
+           strcat (buf, "id");
            if (protocol_list)
              {
                tree chain = protocol_list;
@@ -6972,70 +7643,18 @@ gen_declspecs (declspecs, buf, raw)
                strcat (buf, " <");
                while (chain)
                  {
-                   strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
+                   strcat (buf,
+                           IDENTIFIER_POINTER
+                           (PROTOCOL_NAME (TREE_VALUE (chain))));
                    chain = TREE_CHAIN (chain);
                    if (chain)
                      strcat (buf, ", ");
                  }
+
                strcat (buf, ">");
              }
          }
-       else
-         strcat (buf, "untagged struct");
-
-       strcat (buf, " ");
-       break;
-
-      case UNION_TYPE:
-       if (TYPE_NAME (declspecs)
-           && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
-         {
-           strcat (buf, "union ");
-           strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
-           strcat (buf, " ");
-         }
-       else
-         strcat (buf, "untagged union ");
-       break;
-
-      case ENUMERAL_TYPE:
-       if (TYPE_NAME (declspecs)
-           && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
-         {
-           strcat (buf, "enum ");
-           strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
-           strcat (buf, " ");
-         }
-       else
-         strcat (buf, "untagged enum ");
-       break;
-
-      case VOID_TYPE:
-       strcat (buf, "void ");
-        break;
-
-       /* NEW!!! */
-      case POINTER_TYPE:
-       {
-         tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
-
-         strcat (buf, "id");
-         if (protocol_list)
-           {
-             tree chain = protocol_list;
-
-             strcat (buf, " <");
-             while (chain)
-               {
-                 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
-                 chain = TREE_CHAIN (chain);
-                 if (chain)
-                   strcat (buf, ", ");
-               }
-             strcat (buf, ">");
-           }
        }
-      }
     }
 }
 
@@ -7049,9 +7668,9 @@ gen_declaration (atype_or_adecl, buf)
   if (TREE_CODE (atype_or_adecl) == TREE_LIST)
     {
       tree declspecs;  /* "identifier_node", "record_type" */
-      tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
+      tree declarator; /* "array_ref", "indirect_ref", "call_expr"...  */
 
-      /* we have a "raw", abstract declarator (typename) */
+      /* We have a "raw", abstract declarator (typename).  */
       declarator = TREE_VALUE (atype_or_adecl);
       declspecs  = TREE_PURPOSE (atype_or_adecl);
 
@@ -7062,34 +7681,37 @@ gen_declaration (atype_or_adecl, buf)
          strcat (buf, gen_declarator (declarator, declbuf, ""));
        }
     }
+
   else
     {
       tree atype;
-      tree declspecs;  /* "integer_type", "real_type", "record_type"... */
-      tree declarator; /* "array_type", "function_type", "pointer_type". */
+      tree declspecs;  /* "integer_type", "real_type", "record_type"...  */
+      tree declarator; /* "array_type", "function_type", "pointer_type".  */
 
       if (TREE_CODE (atype_or_adecl) == FIELD_DECL
          || TREE_CODE (atype_or_adecl) == PARM_DECL
          || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
        atype = TREE_TYPE (atype_or_adecl);
       else
-       atype = atype_or_adecl; /* assume we have a *_type node */
+       /* Assume we have a *_type node.  */
+       atype = atype_or_adecl;
 
       if (is_complex_decl (atype))
        {
          tree chain;
 
-         /* get the declaration specifier...it is at the end of the list */
+         /* Get the declaration specifier; it is at the end of the list.  */
          declarator = chain = atype;
          do
            chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
          while (is_complex_decl (chain));
          declspecs = chain;
        }
+
       else
        {
          declspecs = atype;
-         declarator = NULLT;
+         declarator = NULL_TREE;
        }
 
       gen_declspecs (declspecs, buf, 0);
@@ -7107,6 +7729,7 @@ gen_declaration (atype_or_adecl, buf)
              strcat (buf, " ");
              strcat (buf, gen_declarator (declarator, declbuf, decl_name));
            }
+
          else if (decl_name[0])
            {
              strcat (buf, " ");
@@ -7119,6 +7742,7 @@ gen_declaration (atype_or_adecl, buf)
          strcat (buf, gen_declarator (declarator, declbuf, ""));
        }
     }
+
   return buf;
 }
 
@@ -7140,7 +7764,8 @@ gen_method_decl (method, buf)
 
   chain = METHOD_SEL_ARGS (method);
   if (chain)
-    {                          /* we have a chain of keyword_decls */
+    {
+      /* We have a chain of keyword_decls.  */
       do
         {
          if (KEYWORD_KEY_NAME (chain))
@@ -7153,6 +7778,7 @@ gen_method_decl (method, buf)
              gen_declaration (TREE_TYPE (chain), buf);
              strcat (buf, ")");
            }
+
          strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
          if ((chain = TREE_CHAIN (chain)))
            strcat (buf, " ");
@@ -7163,9 +7789,10 @@ gen_method_decl (method, buf)
         strcat (buf, ", ...");
       else if (METHOD_ADD_ARGS (method))
         {
-         /* we have a tree list node as generate by get_parm_info.  */
+         /* We have a tree list node as generate by get_parm_info.  */
          chain  = TREE_PURPOSE (METHOD_ADD_ARGS (method));
-          /* know we have a chain of parm_decls */
+
+          /* Know we have a chain of parm_decls.  */
           while (chain)
             {
              strcat (buf, ", ");
@@ -7174,13 +7801,15 @@ gen_method_decl (method, buf)
             }
        }
     }
-  else                         /* we have a unary selector */
+
+  else
+    /* We have a unary selector.  */
     strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
 
   return buf;
 }
-
-/* debug info...  */
+\f
+/* Debug info.  */
 
 static void
 dump_interface (fp, chain)
@@ -7251,16 +7880,16 @@ init_objc ()
   tree_code_name
     = (char **) xrealloc (tree_code_name,
                          sizeof (char *) * LAST_OBJC_TREE_CODE);
-  bcopy (objc_tree_code_type,
-        tree_code_type + (int) LAST_CODE,
+  bcopy ((char *) objc_tree_code_type,
+        (char *) (tree_code_type + (int) LAST_CODE),
         (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
          * sizeof (char *)));
-  bcopy (objc_tree_code_length,
-        tree_code_length + (int) LAST_CODE,
+  bcopy ((char *) objc_tree_code_length,
+        (char *) (tree_code_length + (int) LAST_CODE),
         (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
          * sizeof (int)));
-  bcopy (objc_tree_code_name,
-        tree_code_name + (int) LAST_CODE,
+  bcopy ((char *) objc_tree_code_name,
+        (char *) (tree_code_name + (int) LAST_CODE),
         (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
          * sizeof (char *)));
 
@@ -7285,6 +7914,11 @@ finish_objc ()
   OBJC_PROLOGUE;
 #endif
 
+  /* Process the static instances here because initialization of objc_symtab
+     dependens on them. */
+  if (objc_static_instances)
+    generate_static_references ();
+
   if (implementation_context || class_names_chain
       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
     generate_objc_symtab_decl ();
@@ -7319,7 +7953,7 @@ finish_objc ()
   if (protocol_chain)
     generate_protocols ();
 
-  if (implementation_context || class_names_chain
+  if (implementation_context || class_names_chain || objc_static_instances
       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
     {
       /* Arrange for Objc data structures to be initialized at run time.  */
@@ -7328,10 +7962,11 @@ finish_objc ()
        assemble_constructor (init_name);
     }
 
-  /* dump the class references...this forces the appropriate classes
+  /* Dump the class references.  This forces the appropriate classes
      to be linked into the executable image, preserving unix archive
-     semantics...this can be removed when we move to a more dynamically
+     semantics.  This can be removed when we move to a more dynamically
      linked environment.  */
+
   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
     {
       handle_class_ref (chain);
@@ -7342,7 +7977,7 @@ finish_objc ()
   for (impent = imp_list; impent; impent = impent->next)
     handle_impent (impent);
 
-  /* dump the string table last */
+  /* Dump the string table last.  */
 
   generate_strings ();
 
@@ -7358,7 +7993,7 @@ finish_objc ()
       hash hsh;
 
       /* Run through the selector hash tables and print a warning for any
-         selector which has multiple methods. */
+         selector which has multiple methods.  */
 
       for (slot = 0; slot < SIZEHASHTABLE; slot++)
        for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
@@ -7412,16 +8047,15 @@ generate_classref_translation_entry (chain)
 
   name = DECL_NAME (TREE_PURPOSE (chain));
 
-  sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
+  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
 
   /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
-  decl_specs = tree_cons (NULLT, type, sc_spec);
+  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
 
-  /* the `decl' that is returned from start_decl is the one that we
-     forward declared in `build_class_reference'.  */
-  decl = start_decl (name, decl_specs, 1);
-  end_temporary_allocation ();
-  finish_decl (decl, expr, NULLT);
+  /* The decl that is returned from start_decl is the one that we
+     forward declared in build_class_reference.  */
+  decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
+  finish_decl (decl, expr, NULL_TREE);
   return;
 }
 
@@ -7434,6 +8068,7 @@ handle_class_ref (chain)
     {
       tree decl;
       char *string = (char *) alloca (strlen (name) + 30);
+      tree exp;
 
       sprintf (string, "%sobjc_class_name_%s",
               (flag_next_runtime ? "." : "__"), name);
@@ -7449,12 +8084,16 @@ handle_class_ref (chain)
       /* Make following constant read-only (why not)?  */
       readonly_data_section ();
 
+      exp = build1 (ADDR_EXPR, string_type_node, decl);
+
+      /* Align the section properly.  */
+      assemble_constant_align (exp);
+
       /* Inform the assembler about this new external thing.  */
       assemble_external (decl);
 
       /* Output a constant to reference this address.  */
-      output_constant (build1 (ADDR_EXPR, string_type_node, decl),
-                      int_size_in_bytes (string_type_node));
+      output_constant (exp, int_size_in_bytes (string_type_node));
     }
   else
     {
@@ -7490,6 +8129,7 @@ handle_impent (impent)
          sprintf (string, ".globl .objc_class_name_%s", class_name);
          assemble_asm (my_build_string (strlen (string) + 1, string));
        }
+
       else
        {
          sprintf (string, "%sobjc_class_name_%s",
@@ -7498,6 +8138,7 @@ handle_impent (impent)
          assemble_label (string);
        }
     }
+
   else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
     {
       char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
@@ -7508,7 +8149,7 @@ handle_impent (impent)
 
       /* Do the same for categories.  Even though no references to these
         symbols are generated automatically by the compiler, it gives
-        you a handle to pull them into an archive by hand. */
+        you a handle to pull them into an archive by hand.  */
       if (flag_next_runtime)
        {
          /* Grossly unportable.  */
@@ -7520,6 +8161,7 @@ handle_impent (impent)
                   class_name, class_super_name);
          assemble_asm (my_build_string (strlen (string) + 1, string));
        }
+
       else
        {
          sprintf (string, "%sobjc_category_name_%s_%s",
@@ -7547,7 +8189,7 @@ objc_debug (fp)
       {
        if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
          {
-           /* we have a function definition - generate prototype */
+           /* We have a function definition: generate prototype.  */
             bzero (errbuf, BUFSIZE);
            gen_declaration (loop, errbuf);
            fprintf (fp, "%s;\n", errbuf);
@@ -7555,7 +8197,8 @@ objc_debug (fp)
        loop = TREE_CHAIN (loop);
       }
   }
-  {                            /* dump global chains */
+  {
+    /* Dump global chains.  */
     tree loop;
     int i, index = 0, offset = 0;
     hash hashlist;
@@ -7574,6 +8217,7 @@ objc_debug (fp)
            while (hashlist);
          }
       }
+
     for (i = 0; i < SIZEHASHTABLE; i++)
       {
        if (hashlist = cls_method_hash_list[i])
@@ -7588,6 +8232,7 @@ objc_debug (fp)
            while (hashlist);
          }
       }
+
     fprintf (fp, "\nsel_refdef_chain:\n");
     for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
       {
@@ -7597,6 +8242,7 @@ objc_debug (fp)
        /* add one for the '\0' character */
        offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
       }
+
     fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
   }
 }