]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/objc/objc-act.c
Fixed compilation of bitfields of enumerations in args and ivars
[gcc.git] / gcc / objc / objc-act.c
index 3bafafe56a104b88922b663b8b2faebe5828c775..31eb05fc83e54c7175ceb9d366ab9aba3765903d 100644 (file)
@@ -1,5 +1,6 @@
 /* Implement classes and message passing for Objective C.
-   Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Contributed by Steve Naroff.
 
 This file is part of GNU CC.
@@ -36,13 +37,16 @@ Boston, MA 02111-1307, USA.  */
 
    code generation `options':
 
-   - OBJC_INT_SELECTORS  */
+   */
 
 #include "config.h"
 #include "system.h"
 #include "tree.h"
+#include "rtl.h"
+#include "expr.h"
 #include "c-tree.h"
 #include "c-lex.h"
+#include "c-common.h"
 #include "flags.h"
 #include "objc-act.h"
 #include "input.h"
@@ -50,12 +54,11 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "output.h"
 #include "toplev.h"
-
-#if USE_CPPLIB
+#include "ggc.h"
 #include "cpplib.h"
-extern cpp_reader  parse_in;
-extern cpp_options parse_options;
-#endif
+#include "debug.h"
+#include "target.h"
+#include "varray.h"
 
 /* This is the default way of generating a method name.  */
 /* I am not sure it is really correct.
@@ -87,12 +90,11 @@ extern cpp_options parse_options;
 /* Define the special tree codes that we use.  */
 
 /* Table indexed by tree code giving a string containing a character
-   classifying the tree code.  Possibilities are
-   t, d, s, c, r, <, 1 and 2.  See objc-tree.def for details.  */
+   classifying the tree code.  */
 
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
 
-char objc_tree_code_type[] = {
+static const char objc_tree_code_type[] = {
   'x',
 #include "objc-tree.def"
 };
@@ -104,7 +106,7 @@ char objc_tree_code_type[] = {
 
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
 
-int objc_tree_code_length[] = {
+static const int objc_tree_code_length[] = {
   0,
 #include "objc-tree.def"
 };
@@ -114,7 +116,7 @@ int objc_tree_code_length[] = {
    Used for printing out the tree and error messages.  */
 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
 
-char *objc_tree_code_name[] = {
+static const char * const objc_tree_code_name[] = {
   "@@dummy",
 #include "objc-tree.def"
 };
@@ -133,19 +135,17 @@ 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"
+
+/* The version identifies which language generation and runtime
+   the module (file) was compiled for, and is recorded in the
+   module descriptor.  */
 
 #define OBJC_VERSION   (flag_next_runtime ? 5 : 8)
 #define PROTOCOL_VERSION 2
 
+/* (Decide if these can ever be validly changed.) */
 #define OBJC_ENCODE_INLINE_DEFS        0
 #define OBJC_ENCODE_DONT_INLINE_DEFS   1
 
@@ -153,85 +153,71 @@ static tree static_instances_decl = NULL_TREE;
 
 /* Used by compile_file.  */
 
-static void init_objc                          PROTO((void));
-static void finish_objc                                PROTO((void));
+static void init_objc                          PARAMS ((void));
+static void finish_objc                                PARAMS ((void));
 
 /* 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((tree));
-static tree build_objc_method_call             PROTO((int, tree, tree,
+static void synth_module_prologue              PARAMS ((void));
+static tree build_constructor                  PARAMS ((tree, tree));
+static rtx build_module_descriptor             PARAMS ((void));
+static tree init_module_descriptor             PARAMS ((tree));
+static tree build_objc_method_call             PARAMS ((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,
+static void generate_strings                   PARAMS ((void));
+static tree get_proto_encoding                         PARAMS ((tree));
+static void build_selector_translation_table   PARAMS ((void));
+static tree build_ivar_chain                   PARAMS ((tree, int));
+
+static tree objc_add_static_instance           PARAMS ((tree, tree));
+
+static tree build_ivar_template                        PARAMS ((void));
+static tree build_method_template              PARAMS ((void));
+static tree build_private_template             PARAMS ((tree));
+static void build_class_template               PARAMS ((void));
+static void build_selector_template            PARAMS ((void));
+static void build_category_template            PARAMS ((void));
+static tree build_super_template               PARAMS ((void));
+static tree build_category_initializer         PARAMS ((tree, tree, tree,
                                                       tree, tree, tree));
-static tree build_protocol_initializer         PROTO((tree, tree, tree,
+static tree build_protocol_initializer         PARAMS ((tree, tree, tree,
                                                       tree, tree));
 
-static void synth_forward_declarations         PROTO((void));
-static void generate_ivar_lists                        PROTO((void));
-static void generate_dispatch_tables           PROTO((void));
-static void generate_shared_structures         PROTO((void));
-static tree generate_protocol_list             PROTO((tree));
-static void generate_forward_declaration_to_string_table PROTO((void));
-static void build_protocol_reference           PROTO((tree));
+static void synth_forward_declarations         PARAMS ((void));
+static void generate_ivar_lists                        PARAMS ((void));
+static void generate_dispatch_tables           PARAMS ((void));
+static void generate_shared_structures         PARAMS ((void));
+static tree generate_protocol_list             PARAMS ((tree));
+static void generate_forward_declaration_to_string_table PARAMS ((void));
+static void build_protocol_reference           PARAMS ((tree));
 
-#if 0
-static tree init_selector                      PROTO((int));
-#endif
-static tree build_keyword_selector             PROTO((tree));
-static tree synth_id_with_class_suffix         PROTO((char *, tree));
+static tree build_keyword_selector             PARAMS ((tree));
+static tree synth_id_with_class_suffix         PARAMS ((const char *, tree));
 
-static void generate_static_references         PROTO((void));
-static int check_methods_accessible            PROTO((tree, tree,
+static void generate_static_references         PARAMS ((void));
+static int check_methods_accessible            PARAMS ((tree, tree,
                                                       int));
-static void encode_aggregate_within            PROTO((tree, int, int,
+static void encode_aggregate_within            PARAMS ((tree, int, int,
                                                       int, int));
+static const char *objc_demangle               PARAMS ((const char *));
+static const char *objc_printable_name         PARAMS ((tree, int));
+static void objc_expand_function_end            PARAMS ((void));
 
-/* We handle printing method names ourselves for ObjC */
-extern char *(*decl_printable_name) ();
-
-/* Misc. bookkeeping */
-
-typedef struct hashed_entry    *hash;
-typedef struct hashed_attribute  *attr;
+/* Hash tables to manage the global pool of method prototypes.  */
 
-struct hashed_attribute
-{
-  attr next;
-  tree value;
-};
-struct hashed_entry
-{
-  attr list;
-  hash next;
-  tree key;
-};
+hash *nst_method_hash_list = 0;
+hash *cls_method_hash_list = 0;
 
-static void hash_init                          PROTO((void));
-static void hash_enter                         PROTO((hash *, tree));
-static hash hash_lookup                                PROTO((hash *, tree));
-static void hash_add_attr                      PROTO((hash, tree));
-static tree lookup_method                      PROTO((tree, tree));
-static tree lookup_instance_method_static      PROTO((tree, tree));
-static tree lookup_class_method_static         PROTO((tree, tree));
-static tree add_class                          PROTO((tree));
-static void add_category                       PROTO((tree, tree));
+static size_t hash_func                                PARAMS ((tree));
+static void hash_init                          PARAMS ((void));
+static void hash_enter                         PARAMS ((hash *, tree));
+static hash hash_lookup                                PARAMS ((hash *, tree));
+static void hash_add_attr                      PARAMS ((hash, tree));
+static tree lookup_method                      PARAMS ((tree, tree));
+static tree lookup_instance_method_static      PARAMS ((tree, tree));
+static tree lookup_class_method_static         PARAMS ((tree, tree));
+static tree add_class                          PARAMS ((tree));
+static void add_category                       PARAMS ((tree, tree));
 
 enum string_section
 {
@@ -240,107 +226,116 @@ enum string_section
   meth_var_types       /* method and variable type descriptors */
 };
 
-static tree add_objc_string                    PROTO((tree,
-                                                      enum string_section));
-static tree get_objc_string_decl               PROTO((tree,
+static tree add_objc_string                    PARAMS ((tree,
                                                       enum string_section));
-static tree build_objc_string_decl             PROTO((tree,
+static tree get_objc_string_decl               PARAMS ((tree,
                                                       enum string_section));
-static tree build_selector_reference_decl      PROTO((tree));
+static tree build_objc_string_decl             PARAMS ((enum string_section));
+static tree build_selector_reference_decl      PARAMS ((void));
 
 /* Protocol additions.  */
 
-static tree add_protocol                       PROTO((tree));
-static tree lookup_protocol                    PROTO((tree));
-static tree lookup_and_install_protocols       PROTO((tree));
+static tree add_protocol                       PARAMS ((tree));
+static tree lookup_protocol                    PARAMS ((tree));
+static void check_protocol_recursively         PARAMS ((tree, tree));
+static tree lookup_and_install_protocols       PARAMS ((tree));
 
 /* Type encoding.  */
 
-static void encode_type_qualifiers             PROTO((tree));
-static void encode_pointer                     PROTO((tree, int, int));
-static void encode_array                       PROTO((tree, int, int));
-static void encode_aggregate                   PROTO((tree, int, int));
-static void encode_bitfield                    PROTO((int, int));
-static void encode_type                                PROTO((tree, int, int));
-static void encode_field_decl                  PROTO((tree, int, int));
+static void encode_type_qualifiers             PARAMS ((tree));
+static void encode_pointer                     PARAMS ((tree, int, int));
+static void encode_array                       PARAMS ((tree, int, int));
+static void encode_aggregate                   PARAMS ((tree, int, int));
+static void encode_bitfield                    PARAMS ((int));
+static void encode_type                                PARAMS ((tree, int, int));
+static void encode_field_decl                  PARAMS ((tree, int, int));
 
-static void really_start_method                        PROTO((tree, tree));
-static int comp_method_with_proto              PROTO((tree, tree));
-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));
+static void really_start_method                        PARAMS ((tree, tree));
+static int comp_method_with_proto              PARAMS ((tree, tree));
+static int comp_proto_with_proto               PARAMS ((tree, tree));
+static tree get_arg_type_list                  PARAMS ((tree, int, int));
+static tree expr_last                          PARAMS ((tree));
 
 /* Utilities for debugging and error diagnostics.  */
 
-static void warn_with_method                   PROTO((char *, int, tree));
-static void error_with_ivar                    PROTO((char *, tree, tree));
-static char *gen_method_decl                   PROTO((tree, char *));
-static char *gen_declaration                   PROTO((tree, char *));
-static char *gen_declarator                    PROTO((tree, char *, char *));
-static int is_complex_decl                     PROTO((tree));
-static void adorn_decl                         PROTO((tree, char *));
-static void dump_interface                     PROTO((FILE *, tree));
+static void warn_with_method                   PARAMS ((const char *, int, tree));
+static void error_with_ivar                    PARAMS ((const char *, tree, tree));
+static char *gen_method_decl                   PARAMS ((tree, char *));
+static char *gen_declaration                   PARAMS ((tree, char *));
+static void gen_declaration_1                  PARAMS ((tree, char *));
+static char *gen_declarator                    PARAMS ((tree, char *,
+                                                      const char *));
+static int is_complex_decl                     PARAMS ((tree));
+static void adorn_decl                         PARAMS ((tree, char *));
+static void dump_interface                     PARAMS ((FILE *, tree));
 
 /* Everything else.  */
 
-static void objc_fatal                         PROTO((void))
-  ATTRIBUTE_NORETURN;
-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 my_build_string                    PROTO((int, char *));
-static void build_objc_symtab_template         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));
-#if 0
-static tree build_msg_pool_reference           PROTO((int));
-#endif
-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, 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));
-static tree encode_method_prototype            PROTO((tree, tree));
-static tree generate_descriptor_table          PROTO((tree, char *, int, tree, tree));
-static void generate_method_descriptors                PROTO((tree));
-static tree build_tmp_function_decl            PROTO((void));
-static void hack_method_prototype              PROTO((tree, tree));
-static void generate_protocol_references       PROTO((tree));
-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, tree));
-static tree generate_ivars_list                        PROTO((tree, char *,
+static void add_objc_tree_codes                        PARAMS ((void));
+static tree define_decl                                PARAMS ((tree, tree));
+static tree lookup_method_in_protocol_list     PARAMS ((tree, tree, int));
+static tree lookup_protocol_in_reflist         PARAMS ((tree, tree));
+static tree create_builtin_decl                        PARAMS ((enum tree_code,
+                                                      tree, const char *));
+static void setup_string_decl                  PARAMS ((void));
+static void build_string_class_template                PARAMS ((void));
+static tree my_build_string                    PARAMS ((int, const char *));
+static void build_objc_symtab_template         PARAMS ((void));
+static tree init_def_list                      PARAMS ((tree));
+static tree init_objc_symtab                   PARAMS ((tree));
+static void forward_declare_categories         PARAMS ((void));
+static void generate_objc_symtab_decl          PARAMS ((void));
+static tree build_selector                     PARAMS ((tree));
+static tree build_typed_selector_reference             PARAMS ((tree, tree));
+static tree build_selector_reference           PARAMS ((tree));
+static tree build_class_reference_decl         PARAMS ((void));
+static void add_class_reference                        PARAMS ((tree));
+static tree objc_copy_list                     PARAMS ((tree, tree *));
+static tree build_protocol_template            PARAMS ((void));
+static tree build_descriptor_table_initializer PARAMS ((tree, tree));
+static tree build_method_prototype_list_template PARAMS ((tree, int));
+static tree build_method_prototype_template    PARAMS ((void));
+static int forwarding_offset                   PARAMS ((tree));
+static tree encode_method_prototype            PARAMS ((tree, tree));
+static tree generate_descriptor_table          PARAMS ((tree, const char *,
+                                                      int, tree, tree));
+static void generate_method_descriptors                PARAMS ((tree));
+static tree build_tmp_function_decl            PARAMS ((void));
+static void hack_method_prototype              PARAMS ((tree, tree));
+static void generate_protocol_references       PARAMS ((tree));
+static void generate_protocols                 PARAMS ((void));
+static void check_ivars                                PARAMS ((tree, tree));
+static tree build_ivar_list_template           PARAMS ((tree, int));
+static tree build_method_list_template         PARAMS ((tree, int));
+static tree build_ivar_list_initializer                PARAMS ((tree, tree));
+static tree generate_ivars_list                        PARAMS ((tree, const char *,
                                                       int, tree));
-static tree build_dispatch_table_initializer   PROTO((tree, tree));
-static tree generate_dispatch_table            PROTO((tree, char *,
+static tree build_dispatch_table_initializer   PARAMS ((tree, tree));
+static tree generate_dispatch_table            PARAMS ((tree, const char *,
                                                       int, tree));
-static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
+static tree build_shared_structure_initializer PARAMS ((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));
-static tree check_duplicates                   PROTO((hash));
-static tree receiver_is_class_object           PROTO((tree));
-static int check_methods                       PROTO((tree, tree, int));
-static int conforms_to_protocol                        PROTO((tree, tree));
-static void check_protocols                    PROTO((tree, char *, char *));
-static tree encode_method_def                  PROTO((tree));
-static void gen_declspecs                      PROTO((tree, char *, int));
-static void generate_classref_translation_entry        PROTO((tree));
-static void handle_class_ref                   PROTO((tree));
+static void generate_category                  PARAMS ((tree));
+static int is_objc_type_qualifier              PARAMS ((tree));
+static tree adjust_type_for_id_default         PARAMS ((tree));
+static tree check_duplicates                   PARAMS ((hash));
+static tree receiver_is_class_object           PARAMS ((tree));
+static int check_methods                       PARAMS ((tree, tree, int));
+static int conforms_to_protocol                        PARAMS ((tree, tree));
+static void check_protocol                     PARAMS ((tree, const char *,
+                                                      const char *));
+static void check_protocols                    PARAMS ((tree, const char *,
+                                                      const char *));
+static tree encode_method_def                  PARAMS ((tree));
+static void gen_declspecs                      PARAMS ((tree, char *, int));
+static void generate_classref_translation_entry        PARAMS ((tree));
+static void handle_class_ref                   PARAMS ((tree));
+static void generate_struct_by_value_array     PARAMS ((void))
+     ATTRIBUTE_NORETURN;
+static void objc_act_parse_init                        PARAMS ((void));
+static void ggc_mark_imp_list                  PARAMS ((void *));
+static void ggc_mark_hash_table                        PARAMS ((void *));
 
 /*** Private Interface (data) ***/
 
@@ -369,110 +364,36 @@ static void handle_class_ref                     PROTO((tree));
 #define UTAG_METHOD_PROTOTYPE  "_objc_method_prototype"
 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
 
+#ifdef NEXT_OBJC_RUNTIME
+#define STRING_OBJECT_CLASS_NAME "NSConstantString"
+#else
 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
-#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
-
-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'.  */
-
-#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
-#define TYPED_OBJECT(type) \
-       (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
-
-/* 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;
-
-static tree super_type, selector_type, id_type, objc_class_type;
-static tree instance_type, protocol_type;
-
-/* Type checking macros.  */
-
-#define IS_ID(TYPE) \
-  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
-#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
-  (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
-#define IS_SUPER(TYPE) \
-  (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
-
-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.  */
-
-static tree cls_ref_chain = NULL_TREE; /* Classes referenced.  */
-static tree sel_ref_chain = NULL_TREE; /* Selectors referenced.  */
-
-/* Chains to manage uniquing of strings.  */
-
-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.  */
-
-static hash *nst_method_hash_list = 0;
-static hash *cls_method_hash_list = 0;
-
-/* Backend data declarations.  */
-
-static tree UOBJC_SYMBOLS_decl;
-static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
-static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
-static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
-static tree UOBJC_SELECTOR_TABLE_decl;
-static tree UOBJC_MODULES_decl;
-static tree UOBJC_STRINGS_decl;
-
-/* The following are used when compiling a class implementation.
-   implementation_template will normally be an interface, however if
-   none exists this will be equal to implementation_context...it is
-   set in start_class.  */
+#endif
+/* Note that the string object global name is only needed for the
+   NeXT runtime.  */
+#define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
 
-static tree implementation_context = NULL_TREE;
-static tree implementation_template = NULL_TREE;
+#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
 
-struct imp_entry
-{
-  struct imp_entry *next;
-  tree imp_context;
-  tree imp_template;
-  tree class_decl;             /* _OBJC_CLASS_<my_name>; */
-  tree meta_decl;              /* _OBJC_METACLASS_<my_name>; */
-};
+static const char *constant_string_class_name = NULL;
 
-static void handle_impent                      PROTO((struct imp_entry *));
+static const char *TAG_GETCLASS;
+static const char *TAG_GETMETACLASS;
+static const char *TAG_MSGSEND;
+static const char *TAG_MSGSENDSUPER;
+static const char *TAG_EXECCLASS;
 
-static struct imp_entry *imp_list = 0;
-static int imp_count = 0;      /* `@implementation' */
-static int cat_count = 0;      /* `@category' */
+/* The OCTI_... enumeration itself in in objc/objc-act.h.  */
+tree objc_global_trees[OCTI_MAX];
 
-static tree objc_class_template, objc_category_template, uprivate_record;
-static tree objc_protocol_template, objc_selector_template;
-static tree ucls_super_ref, uucls_super_ref;
+int objc_receiver_context;
 
-static tree objc_method_template, objc_ivar_template;
-static tree objc_symtab_template, objc_module_template;
-static tree objc_super_template, objc_object_reference;
+static void handle_impent                      PARAMS ((struct imp_entry *));
 
-static tree objc_object_id, objc_class_id, objc_id_id;
-static tree constant_string_id;
-static tree constant_string_type;
-static tree UOBJC_SUPER_decl;
+struct imp_entry *imp_list = 0;
+int imp_count = 0;     /* `@implementation' */
+int cat_count = 0;     /* `@category' */
 
-static tree method_context = NULL_TREE;
 static int  method_slot = 0;   /* Used by start_method_def, */
 
 #define BUFSIZE                1024
@@ -485,7 +406,7 @@ extern enum debug_info_type write_symbols;
 
 /* Data imported from toplev.c.  */
 
-extern char *dump_base_name;
+extern const char *dump_base_name;
 \f
 /* Generate code for GNU or NeXT runtime environment.  */
 
@@ -528,11 +449,13 @@ static int generating_instance_variables = 0;
 
 static int print_struct_values = 0;
 
+static varray_type deferred_fns;
+
 /* Some platforms pass small structures through registers versus through
    an invisible pointer.  Determine at what size structure is the 
    transition point between the two possibilities. */
 
-void
+static void
 generate_struct_by_value_array ()
 {
   tree type;
@@ -541,7 +464,7 @@ generate_struct_by_value_array ()
   int aggregate_in_mem[32];
   int found = 0;
 
-  /* Presumbaly no platform passes 32 byte structures in a register. */
+  /* Presumably no platform passes 32 byte structures in a register. */
   for (i = 1; i < 32; i++)
     {
       char buffer[5];
@@ -591,49 +514,28 @@ generate_struct_by_value_array ()
   exit (0);
 }
 
-#if USE_CPPLIB
-extern char *yy_cur;
-#endif
-
-void
-lang_init_options ()
+const char *
+objc_init (filename)
+     const char *filename;
 {
-#if USE_CPPLIB
-  cpp_reader_init (&parse_in);
-  parse_in.opts = &parse_options;
-  cpp_options_init (&parse_options);
-#endif
-}
+  filename = c_objc_common_init (filename);
+  add_objc_tree_codes ();
 
-void
-lang_init ()
-{
-#if !USE_CPPLIB
-  /* 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);
-#else
-  check_newline ();
-  yy_cur--;
-#endif 
+  decl_printable_name = objc_printable_name;
 
-  /* 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;
+  /* Force the line number back to 0; check_newline will have
+     raised it to 1, which will make the builtin functions appear
+     not to be built in.  */
+  lineno = 0;
 
   /* If gen_declaration desired, open the output file.  */
   if (flag_gen_declaration)
     {
-      int dump_base_name_length = strlen (dump_base_name);
-      register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
-      strcpy (dumpname, dump_base_name);
-      strcat (dumpname, ".decl");
+      register char * const dumpname = concat (dump_base_name, ".decl", NULL);
       gen_declaration_file = fopen (dumpname, "w");
       if (gen_declaration_file == 0)
-       pfatal_with_name (dumpname);
+       fatal_io_error ("can't open %s", dumpname);
+      free (dumpname);
     }
 
   if (flag_next_runtime)
@@ -654,49 +556,60 @@ lang_init ()
       flag_typed_selectors = 1;
     }
 
-  if (doing_objc_thang)
-    init_objc ();
+  objc_ellipsis_node = make_node (ERROR_MARK);
+
+  init_objc ();
 
   if (print_struct_values)
     generate_struct_by_value_array ();
+
+  objc_act_parse_init ();
+
+  VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
+  ggc_add_tree_varray_root (&deferred_fns, 1);
+
+  return filename;
 }
 
-static void
-objc_fatal ()
+/* Register a function tree, so that its optimization and conversion
+   to RTL is only done at the end of the compilation.  */
+
+int
+defer_fn (fn)
+     tree fn;
 {
-  fatal ("Objective-C text in C source file");
+  VARRAY_PUSH_TREE (deferred_fns, fn);
+
+  return 1;
 }
 
 void
 finish_file ()
 {
-  if (doing_objc_thang)
-    finish_objc ();            /* Objective-C finalization */
+  size_t i;
 
-  if (gen_declaration_file)
-    fclose (gen_declaration_file);
-}
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
+    /* Don't output the same function twice.  We may run into such
+       situations when an extern inline function is later given a
+       non-extern-inline definition.  */
+    if (! TREE_ASM_WRITTEN (VARRAY_TREE (deferred_fns, i)))
+      c_expand_deferred_function (VARRAY_TREE (deferred_fns, i));
+  VARRAY_FREE (deferred_fns);
 
-void
-lang_finish ()
-{
-}
+  finish_objc ();              /* Objective-C finalization */
 
-const char *
-lang_identify ()
-{
-  return "objc";
+  if (gen_declaration_file)
+    fclose (gen_declaration_file);
 }
 
 int
-lang_decode_option (argc, argv)
+objc_decode_option (argc, argv)
      int argc;
      char **argv;
 {
-  char *p = argv[0];
-  if (!strcmp (p, "-lang-objc"))
-    doing_objc_thang = 1;
-  else if (!strcmp (p, "-gen-decls"))
+  const char *p = argv[0];
+
+  if (!strcmp (p, "-gen-decls"))
     flag_gen_declaration = 1;
   else if (!strcmp (p, "-Wselector"))
     warn_selector = 1;
@@ -716,29 +629,26 @@ lang_decode_option (argc, argv)
     flag_next_runtime = 1;
   else if (!strcmp (p, "-print-objc-runtime-info"))
     print_struct_values = 1;
+#define CSTSTRCLASS "-fconstant-string-class="
+  else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
+    if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
+      error ("no class name specified as argument to -fconstant-string-class");
+    constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
+  }
+#undef CSTSTRCLASS
   else
     return c_decode_option (argc, argv);
 
   return 1;
 }
 
-/* used by print-tree.c */
-
-void
-lang_print_xnode (file, node, indent)
-     FILE *file ATTRIBUTE_UNUSED;
-     tree node ATTRIBUTE_UNUSED;
-     int indent ATTRIBUTE_UNUSED;
-{
-}
-
 \f
 static tree
 define_decl (declarator, declspecs)
      tree declarator;
      tree declspecs;
 {
-  tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
+  tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
   finish_decl (decl, NULL_TREE, NULL_TREE);
   return decl;
 }
@@ -760,9 +670,7 @@ maybe_objc_comptypes (lhs, rhs, reflexive)
      tree lhs, rhs;
      int reflexive;
 {
-  if (doing_objc_thang)
-    return objc_comptypes (lhs, rhs, reflexive);
-  return -1;
+  return objc_comptypes (lhs, rhs, reflexive);
 }
 
 static tree
@@ -807,7 +715,7 @@ 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 supported by the object on the rhs.  */
    if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
      {
        tree fnd = 0;
@@ -897,6 +805,12 @@ objc_comptypes (lhs, rhs, reflexive)
                      tree cat;
 
                      rproto_list = CLASS_PROTOCOL_LIST (rinter);
+                     /* If the underlying ObjC class does not have
+                        protocols attached to it, perhaps there are
+                        "one-off" protocols attached to the rhs?
+                        E.g., 'id<MyProt> foo;'.  */
+                     if (!rproto_list)
+                       rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
                      rproto = lookup_protocol_in_reflist (rproto_list, p);
 
                      /* Check for protocols adopted by categories.  */
@@ -927,7 +841,7 @@ objc_comptypes (lhs, rhs, reflexive)
        return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
 
       else
-       /* Defer to comptypes .*/
+       /* Defer to comptypes.  */
        return -1;
     }
 
@@ -994,18 +908,14 @@ objc_check_decl (decl)
   if (TREE_CODE (type) == RECORD_TYPE
       && TREE_STATIC_TEMPLATE (type)
       && type != constant_string_type)
-    {
-      error_with_decl (decl, "`%s' cannot be statically allocated");
-      fatal ("statically allocated objects not supported");
-    }
+    error_with_decl (decl, "`%s' cannot be statically allocated");
 }
 
 void
 maybe_objc_check_decl (decl)
      tree decl;
 {
-  if (doing_objc_thang)
-    objc_check_decl (decl);
+  objc_check_decl (decl);
 }
 
 /* Implement static typing.  At this point, we know we have an interface.  */
@@ -1021,24 +931,22 @@ get_static_reference (interface, protocols)
     {
       tree t, m = TYPE_MAIN_VARIANT (type);
 
-      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;
 
-      /* Look up protocols and install in lang specific list.  */
+      /* Look up protocols and install in lang specific list.  Note
+        that the protocol list can have a different lifetime than T!  */
       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
 
       /* This forces a new pointer type to be created later
         (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) = 0;
+       TYPE_POINTER_TO (t) = NULL_TREE;
 
       type = t;
     }
@@ -1057,11 +965,14 @@ get_object_reference (protocols)
     {
       type = TREE_TYPE (type_decl);
       if (TYPE_MAIN_VARIANT (type) != id_type)
-       warning ("Unexpected type for `id' (%s)",
-               gen_declaration (type, errbuf));
+       warning ("unexpected type for `id' (%s)",
+                gen_declaration (type, errbuf));
     }
   else
-    fatal ("Undefined type `id', please import <objc/objc.h>");
+    {
+      error ("undefined type `id', please import <objc/objc.h>");
+      return error_mark_node;
+    }
 
   /* This clause creates a new pointer type that is qualified with
      the protocol specification...this info is used later to do more
@@ -1071,11 +982,8 @@ get_object_reference (protocols)
     {
       tree t, m = TYPE_MAIN_VARIANT (type);
 
-      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);
@@ -1088,13 +996,39 @@ get_object_reference (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) = NULL_TREE;
 
       type = t;
     }
   return type;
 }
 
+/* Check for circular dependencies in protocols.  The arguments are
+   PROTO, the protocol to check, and LIST, a list of protocol it
+   conforms to.  */
+
+static void 
+check_protocol_recursively (proto, list)
+     tree proto;
+     tree list;
+{
+  tree p;
+
+  for (p = list; p; p = TREE_CHAIN (p))
+    {
+      tree pp = TREE_VALUE (p);
+
+      if (TREE_CODE (pp) == IDENTIFIER_NODE)
+       pp = lookup_protocol (pp);
+
+      if (pp == proto)
+       fatal_error ("protocol `%s' has circular dependency",
+                    IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));      
+      if (pp)
+       check_protocol_recursively (proto, PROTOCOL_LIST (pp));
+    }
+}
+
 static tree
 lookup_and_install_protocols (protocols)
      tree protocols;
@@ -1110,7 +1044,7 @@ lookup_and_install_protocols (protocols)
 
       if (!p)
        {
-         error ("Cannot find protocol declaration for `%s'",
+         error ("cannot find protocol declaration for `%s'",
                 IDENTIFIER_POINTER (ident));
          if (prev)
            TREE_CHAIN (prev) = TREE_CHAIN (proto);
@@ -1136,14 +1070,14 @@ static tree
 create_builtin_decl (code, type, name)
      enum tree_code code;
      tree type;
-     char *name;
+     const 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);
+      make_decl_rtl (decl, 0);
       pushdecl (decl);
     }
 
@@ -1151,6 +1085,19 @@ create_builtin_decl (code, type, name)
   return decl;
 }
 
+/* Find the decl for the constant string class.  */
+
+static void
+setup_string_decl ()
+{
+  if (!string_class_decl)
+    {
+      if (!constant_string_global_id)
+       constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
+      string_class_decl = lookup_name (constant_string_global_id);
+    }
+}
+
 /* Purpose: "play" parser, creating/installing representations
    of the declarations that are required by Objective-C.
 
@@ -1184,15 +1131,10 @@ synth_module_prologue ()
 
   /* Declare type of selector-objects that represent an operation name.  */
 
-#ifdef OBJC_INT_SELECTORS
-  /* `unsigned int' */
-  selector_type = unsigned_type_node;
-#else
   /* `struct objc_selector *' */
   selector_type
     = build_pointer_type (xref_tag (RECORD_TYPE,
                                    get_identifier (TAG_SELECTOR)));
-#endif /* not OBJC_INT_SELECTORS */
 
   /* Forward declare type, or else the prototype for msgSendSuper will
      complain.  */
@@ -1221,11 +1163,11 @@ synth_module_prologue ()
       if (flag_traditional && TAG_MSGSEND[0] != '_')
        DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
 
-      make_decl_rtl (umsg_decl, NULL_PTR, 1);
+      make_decl_rtl (umsg_decl, NULL);
       pushdecl (umsg_decl);
     }
   else
-    umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
+    umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
 
   /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
 
@@ -1236,7 +1178,7 @@ synth_module_prologue ()
                                                 NULL_TREE)));
 
   umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
-                                    temp_type, NOT_BUILT_IN, 0);
+                                    temp_type, 0, NOT_BUILT_IN, 0);
 
   /* id objc_getClass (const char *); */
 
@@ -1247,12 +1189,12 @@ synth_module_prologue ()
                                              NULL_TREE)));
 
   objc_get_class_decl
-    = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
+    = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
 
   /* id objc_getMetaClass (const char *); */
 
   objc_get_meta_class_decl
-    = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
+    = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
 
   /* static SEL _OBJC_SELECTOR_TABLE[]; */
 
@@ -1263,12 +1205,15 @@ synth_module_prologue ()
          /* Suppress outputting debug symbols, because
             dbxout_init hasn'r been called yet.  */
          enum debug_info_type save_write_symbols = write_symbols;
+         struct gcc_debug_hooks *save_hooks = debug_hooks;
          write_symbols = NO_DEBUG;
+         debug_hooks = &do_nothing_debug_hooks;
 
          build_selector_template ();
          temp_type = build_array_type (objc_selector_template, NULL_TREE);
 
          write_symbols = save_write_symbols;
+         debug_hooks = save_hooks;
        }
       else
        temp_type = build_array_type (selector_type, NULL_TREE);
@@ -1285,16 +1230,47 @@ synth_module_prologue ()
   generate_forward_declaration_to_string_table ();
 
   /* Forward declare constant_string_id and constant_string_type.  */
-  constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
+  if (!constant_string_class_name)
+    constant_string_class_name = STRING_OBJECT_CLASS_NAME;
+
+  constant_string_id = get_identifier (constant_string_class_name);
   constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
 }
 
+/* Predefine the following data type:
+
+   struct STRING_OBJECT_CLASS_NAME 
+   {
+     Object isa;
+     char *cString;
+     unsigned int length;
+   }; */
+
+static void
+build_string_class_template ()
+{
+  tree field_decl, field_decl_chain;
+
+  field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
+  field_decl_chain = field_decl;
+
+  field_decl = create_builtin_decl (FIELD_DECL,
+                                   build_pointer_type (char_type_node),
+                                   "cString");
+  chainon (field_decl_chain, field_decl);
+
+  field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
+  chainon (field_decl_chain, field_decl);
+
+  finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
+}
+
 /* Custom build_string which sets TREE_TYPE!  */
 
 static tree
 my_build_string (len, str)
      int len;
-     char *str;
+     const char *str;
 {
   int wide_flag = 0;
   tree a_string = build_string (len, str);
@@ -1313,27 +1289,12 @@ my_build_string (len, str)
   return a_string;
 }
 
-/* Return a newly constructed OBJC_STRING_CST node whose value is
-   the LEN characters at STR.
-   The TREE_TYPE is not initialized.  */
-
-tree
-build_objc_string (len, str)
-     int len;
-     const char *str;
-{
-  tree s = build_string (len, str);
-
-  TREE_SET_CODE (s, OBJC_STRING_CST);
-  return s;
-}
-
-/* Given a chain of OBJC_STRING_CST's, build a static instance of
-   NXConstanString which points at the concatenation of those strings.
+/* Given a chain of STRING_CST's, build a static instance of
+   NXConstantString 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 NXConstandString class
-   object.  */
+   pointers of the string objects to point at the NXConstantString
+   class object.  */
 
 tree
 build_objc_string_object (strings)
@@ -1342,35 +1303,46 @@ build_objc_string_object (strings)
   tree string, initlist, constructor;
   int length;
 
-  if (!doing_objc_thang)
-    objc_fatal ();
-
   if (lookup_interface (constant_string_id) == NULL_TREE)
     {
-      error ("Cannot find interface declaration for `%s'",
+      error ("cannot find interface declaration for `%s'",
             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.  */
   string = combine_strings (strings);
   TREE_SET_CODE (string, STRING_CST);
   length = TREE_STRING_LENGTH (string) - 1;
 
-  if (! flag_next_runtime)
+  /* We could not properly create NXConstantString in synth_module_prologue,
+     because that's called before debugging is initialized.  Do it now.  */
+  if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
+    build_string_class_template ();
+
+  /* & ((NXConstantString) { NULL, string, length })  */
+
+  if (flag_next_runtime)
+    {
+      /* For the NeXT runtime, we can generate a literal reference
+        to the string class, don't need to run a constructor.  */
+      setup_string_decl ();
+      if (string_class_decl == NULL_TREE)
+       {
+         error ("cannot find reference tag for class `%s'",
+                IDENTIFIER_POINTER (constant_string_id));
+         return error_mark_node;
+       }
+      initlist = build_tree_list
+       (NULL_TREE,
+        copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
+    }
+  else
     {
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
-      if (! TREE_PERMANENT (strings))
-       string = my_build_string (length + 1,
-                                 TREE_STRING_POINTER (string));
+      initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
     }
 
-  /* & ((NXConstantString) {0, string, length})  */
-
-  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);
@@ -1381,7 +1353,6 @@ build_objc_string_object (strings)
     {
       constructor
        = objc_add_static_instance (constructor, constant_string_type);
-      pop_obstacks ();
     }
 
   return (build_unary_op (ADDR_EXPR, constructor, 1));
@@ -1397,9 +1368,6 @@ objc_add_static_instance (constructor, class_decl)
   tree *chain, decl;
   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;
@@ -1416,17 +1384,17 @@ objc_add_static_instance (constructor, class_decl)
   DECL_COMMON (decl) = 1;
   TREE_STATIC (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
+  DECL_INITIAL (decl) = constructor;
+
+  /* We may be writing something else just now.
+     Postpone till end of input.  */
+  DECL_DEFER_OUTPUT (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;
 }
 
@@ -1437,8 +1405,27 @@ static tree
 build_constructor (type, elts)
      tree type, elts;
 {
-  tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
+  tree constructor, f, e;
+
+  /* ??? Most of the places that we build constructors, we don't fill in
+     the type of integers properly.  Convert them all en masse.  */
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      f = TREE_TYPE (type);
+      if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
+       for (e = elts; e ; e = TREE_CHAIN (e))
+         TREE_VALUE (e) = convert (f, TREE_VALUE (e));
+    }
+  else
+    {
+      f = TYPE_FIELDS (type);
+      for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
+       if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
+           || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
+         TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
+    }
 
+  constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
   TREE_CONSTANT (constructor) = 1;
   TREE_STATIC (constructor) = 1;
   TREE_READONLY (constructor) = 1;
@@ -1609,20 +1596,20 @@ static void
 forward_declare_categories ()
 {
   struct imp_entry *impent;
-  tree sav = implementation_context;
+  tree sav = objc_implementation_context;
 
   for (impent = imp_list; impent; impent = impent->next)
     {
       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
        {
          /* Set an invisible arg to synth_id_with_class_suffix.  */
-         implementation_context = impent->imp_context;
+         objc_implementation_context = impent->imp_context;
          impent->class_decl
            = create_builtin_decl (VAR_DECL, objc_category_template,
-                                  IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
+                                  IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
        }
     }
-  implementation_context = sav;
+  objc_implementation_context = sav;
 }
 
 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
@@ -1649,7 +1636,7 @@ generate_objc_symtab_decl ()
                                   tree_cons (NULL_TREE,
                                              objc_symtab_template, sc_spec),
                                   1,
-                                  NULL_TREE, NULL_TREE);
+                                  NULL_TREE);
 
   TREE_USED (UOBJC_SYMBOLS_decl) = 1;
   DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
@@ -1693,13 +1680,12 @@ init_module_descriptor (type)
 
 /* Write out the data structures to describe Objective C classes defined.
    If appropriate, compile and output a setup function to initialize them.
-   Return a string which is the name of a function to call to initialize
-   the Objective C data structures for this file (and perhaps for other files
-   also).
+   Return a symbol_ref to the function to call to initialize the Objective C
+   data structures for this file (and perhaps for other files also).
 
    struct objc_module { ... } _OBJC_MODULE = { ... };   */
 
-static char *
+static rtx
 build_module_descriptor ()
 {
   tree decl_specs, field_decl, field_decl_chain;
@@ -1749,10 +1735,12 @@ build_module_descriptor ()
                                           ridpointers[(int) RID_STATIC]));
 
   UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
-                                  decl_specs, 1, NULL_TREE, NULL_TREE);
+                                  decl_specs, 1, NULL_TREE);
 
   DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
   DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
+  DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
+
   finish_decl (UOBJC_MODULES_decl,
               init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
               NULL_TREE);
@@ -1766,64 +1754,54 @@ build_module_descriptor ()
      way of generating the requisite code.  */
 
   if (flag_next_runtime)
-    return 0;
+    return NULL_RTX;
 
   {
-    tree parms, function_decl, decelerator, void_list_node_1;
-    tree function_type;
-    tree init_function_name = get_file_function_name ('I');
+    tree parms, execclass_decl, decelerator, void_list_node_1;
+    tree init_function_name, init_function_decl;
 
     /* Declare void __objc_execClass (void *); */
 
     void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
-    function_type
-      = build_function_type (void_type_node,
-                            tree_cons (NULL_TREE, ptr_type_node,
-                                       void_list_node_1));
-    function_decl = build_decl (FUNCTION_DECL,
-                               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 (NULL_TREE,
-                        build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
-    decelerator = build_function_call (function_decl, parms);
+    execclass_decl = build_decl (FUNCTION_DECL,
+                                get_identifier (TAG_EXECCLASS),
+                                build_function_type (void_type_node,
+                                       tree_cons (NULL_TREE, ptr_type_node,
+                                                  void_list_node_1)));
+    DECL_EXTERNAL (execclass_decl) = 1;
+    DECL_ARTIFICIAL (execclass_decl) = 1;
+    TREE_PUBLIC (execclass_decl) = 1;
+    pushdecl (execclass_decl);
+    rest_of_decl_compilation (execclass_decl, 0, 0, 0);
+    assemble_external (execclass_decl);
 
     /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);}  */
 
+    init_function_name = get_file_function_name ('I');
     start_function (void_list_node_1,
-                   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_1),
-                                     NULL_TREE),
-                   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
-       so each file can use the same name.  */
-    TREE_PUBLIC (current_function_decl) = 0;
-#endif
-    TREE_USED (current_function_decl) = 1;
+                   build_nt (CALL_EXPR, init_function_name,
+                             tree_cons (NULL_TREE, NULL_TREE,
+                                        void_list_node_1),
+                             NULL_TREE),
+                   NULL_TREE);
     store_parm_decls ();
 
-    assemble_external (function_decl);
-    c_expand_expr_stmt (decelerator);
+    init_function_decl = current_function_decl;
+    TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
+    TREE_USED (init_function_decl) = 1;
+    current_function_cannot_inline
+      = "static constructors and destructors cannot be inlined";
+
+    parms
+      = build_tree_list (NULL_TREE,
+                        build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
+    decelerator = build_function_call (execclass_decl, parms);
 
-    TREE_PUBLIC (current_function_decl) = 1;
+    c_expand_expr_stmt (decelerator);
 
-    function_decl = current_function_decl;
     finish_function (0);
 
-    /* Return the name of the constructor function.  */
-    return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
+    return XEXP (DECL_RTL (init_function_decl), 0);
   }
 }
 
@@ -1897,7 +1875,7 @@ generate_static_references ()
       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 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
       DECL_CONTEXT (decl) = 0;
       DECL_ARTIFICIAL (decl) = 1;
 
@@ -1924,8 +1902,8 @@ generate_static_references ()
 
       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;
+      TREE_STATIC (decl) = 1;
       decls
        = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
     }
@@ -1937,11 +1915,10 @@ generate_static_references ()
                         build_tree_list (NULL_TREE,
                                          ridpointers[(int) RID_STATIC]));
   static_instances_decl
-    = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+    = start_decl (expr_decl, decl_spec, 1, 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);
@@ -1964,8 +1941,8 @@ generate_strings ()
        = 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 ();
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
+      DECL_CONTEXT (decl) = NULL_TREE;
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
       finish_decl (decl, string_expr, NULL_TREE);
@@ -1979,7 +1956,8 @@ generate_strings ()
        = 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);
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
+      DECL_CONTEXT (decl) = NULL_TREE;
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
       finish_decl (decl, string_expr, NULL_TREE);
@@ -1993,7 +1971,8 @@ generate_strings ()
        = 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);
+      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
+      DECL_CONTEXT (decl) = NULL_TREE;
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                IDENTIFIER_POINTER (string));
       finish_decl (decl, string_expr, NULL_TREE);
@@ -2001,8 +1980,7 @@ generate_strings ()
 }
 
 static tree
-build_selector_reference_decl (name)
-      tree name;
+build_selector_reference_decl ()
 {
   tree decl, ident;
   char buf[256];
@@ -2010,9 +1988,6 @@ build_selector_reference_decl (name)
 
   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
 
-  push_obstacks_nochange ();
-  end_temporary_allocation ();
-
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, selector_type);
@@ -2023,11 +1998,9 @@ build_selector_reference_decl (name)
   DECL_ARTIFICIAL (decl) = 1;
   DECL_CONTEXT (decl) = 0;
 
-  make_decl_rtl (decl, 0, 1);
+  make_decl_rtl (decl, 0);
   pushdecl_top_level (decl);
 
-  pop_obstacks ();
-
   return decl;
 }
 
@@ -2044,39 +2017,6 @@ build_selector (ident)
     return build_c_cast (selector_type, expr); /* cast! */
 }
 
-/* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
-   The cast stops the compiler from issuing the following message:
-   grok.m: warning: initialization of non-const * pointer from const *
-   grok.m: warning: initialization between incompatible pointer types.  */
-
-#if 0
-static tree
-build_msg_pool_reference (offset)
-     int offset;
-{
-  tree expr = build_int_2 (offset, 0);
-  tree cast;
-
-  expr = build_array_ref (UOBJC_STRINGS_decl, expr);
-  expr = build_unary_op (ADDR_EXPR, expr, 0);
-
-  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;
-}
-
-static tree
-init_selector (offset)
-     int offset;
-{
-  tree expr = build_msg_pool_reference (offset);
-  TREE_TYPE (expr) = selector_type;
-  return expr;
-}
-#endif
-
 static void
 build_selector_translation_table ()
 {
@@ -2085,11 +2025,6 @@ build_selector_translation_table ()
   int offset = 0;
   tree decl = NULL_TREE, var_decl, name;
 
-  /* The corresponding pop_obstacks is in finish_decl,
-     called at the end of this function.  */
-  if (! flag_next_runtime)
-    push_obstacks_nochange ();
-
   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
     {
       tree expr;
@@ -2109,7 +2044,7 @@ build_selector_translation_table ()
 
          /* 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, NULL_TREE, NULL_TREE);
+         decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
        }
 
       /* add one for the '\0' character */
@@ -2140,7 +2075,7 @@ build_selector_translation_table ()
       TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
       /* 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;
+      DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
       initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
                                    nreverse (initlist));
       finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
@@ -2193,7 +2128,7 @@ build_typed_selector_reference (ident, proto)
       chain = &TREE_CHAIN (*chain);
     }
 
-  *chain = perm_tree_cons (proto, ident, NULL_TREE);
+  *chain = tree_cons (proto, ident, NULL_TREE);
 
  return_at_index:
   expr = build_unary_op (ADDR_EXPR,
@@ -2223,9 +2158,9 @@ build_selector_reference (ident)
       chain = &TREE_CHAIN (*chain);
     }
 
-  expr = build_selector_reference_decl (ident);
+  expr = build_selector_reference_decl ();
 
-  *chain = perm_tree_cons (expr, ident, NULL_TREE);
+  *chain = tree_cons (expr, ident, NULL_TREE);
 
   return (flag_next_runtime
          ? expr
@@ -2234,8 +2169,7 @@ build_selector_reference (ident)
 }
 
 static tree
-build_class_reference_decl (name)
-      tree name;
+build_class_reference_decl ()
 {
   tree decl, ident;
   char buf[256];
@@ -2243,9 +2177,6 @@ build_class_reference_decl (name)
 
   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
 
-  push_obstacks_nochange ();
-  end_temporary_allocation ();
-
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, objc_class_type);
@@ -2256,11 +2187,9 @@ build_class_reference_decl (name)
   DECL_CONTEXT (decl) = 0;
   DECL_ARTIFICIAL (decl) = 1;
 
-  make_decl_rtl (decl, 0, 1);
+  make_decl_rtl (decl, 0);
   pushdecl_top_level (decl);
 
-  pop_obstacks ();
-
   return decl;
 }
 
@@ -2287,10 +2216,10 @@ add_class_reference (ident)
       while (chain);
 
       /* Append to the end of the list */
-      TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
+      TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
     }
   else
-    cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
+    cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
 }
 
 /* Get a class reference, creating it if necessary.  Also create the
@@ -2309,13 +2238,13 @@ get_class_reference (ident)
        if (TREE_VALUE (*chain) == ident)
          {
            if (! TREE_PURPOSE (*chain))
-             TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
+             TREE_PURPOSE (*chain) = build_class_reference_decl ();
 
            return TREE_PURPOSE (*chain);
          }
 
-      decl = build_class_reference_decl (ident);
-      *chain = perm_tree_cons (decl, ident, NULL_TREE);
+      decl = build_class_reference_decl ();
+      *chain = tree_cons (decl, ident, NULL_TREE);
       return decl;
     }
   else
@@ -2333,13 +2262,7 @@ get_class_reference (ident)
     }
 }
 
-/* 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
+/* For each string section we have a chain which maps identifier nodes
    to decls for the strings.  */
 
 static tree
@@ -2366,16 +2289,15 @@ add_objc_string (ident, section)
       chain = &TREE_CHAIN (*chain);
     }
 
-  decl = build_objc_string_decl (ident, section);
+  decl = build_objc_string_decl (section);
 
-  *chain = perm_tree_cons (decl, ident, NULL_TREE);
+  *chain = tree_cons (decl, ident, NULL_TREE);
 
   return build_unary_op (ADDR_EXPR, decl, 1);
 }
 
 static tree
-build_objc_string_decl (name, section)
-     tree name;
+build_objc_string_decl (section)
      enum string_section section;
 {
   tree decl, ident;
@@ -2391,8 +2313,6 @@ build_objc_string_decl (name, section)
   else if (section == meth_var_types)
     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
 
-  push_obstacks_nochange ();
-  end_temporary_allocation ();
   ident = get_identifier (buf);
 
   decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
@@ -2404,11 +2324,9 @@ build_objc_string_decl (name, section)
   DECL_CONTEXT (decl) = 0;
   DECL_ARTIFICIAL (decl) = 1;
  
-  make_decl_rtl (decl, 0, 1);
+  make_decl_rtl (decl, 0);
   pushdecl_top_level (decl);
 
-  pop_obstacks ();
-
   return decl;
 }
 
@@ -2418,13 +2336,10 @@ objc_declare_alias (alias_ident, class_ident)
      tree alias_ident;
      tree class_ident;
 {
-  if (!doing_objc_thang)
-    objc_fatal ();
-
   if (is_class_name (class_ident) != class_ident)
-    warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
+    warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
   else if (is_class_name (alias_ident))
-    warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
+    warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
   else
     alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
 }
@@ -2435,9 +2350,6 @@ objc_declare_class (ident_list)
 {
   tree list;
 
-  if (!doing_objc_thang)
-    objc_fatal ();
-
   for (list = ident_list; list; list = TREE_CHAIN (list))
     {
       tree ident = TREE_VALUE (list);
@@ -2510,14 +2422,9 @@ objc_copy_list (list, head)
 
       /* The following statement fixes a bug when inheriting instance
         variables that are declared to be bitfields. finish_struct
-        expects to find the width of the bitfield in DECL_INITIAL,
-        which it nulls out after processing the decl of the super
-        class...rather than change the way finish_struct works (which
-        is risky), I create the situation it expects...s.naroff
-        (7/23/89).  */
-
+        expects to find the width of the bitfield in DECL_INITIAL.  */
       if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
-       DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
+       DECL_INITIAL (tail) = DECL_SIZE (tail);
 
       newlist = chainon (newlist, tail);
       list = TREE_CHAIN (list);
@@ -2556,17 +2463,15 @@ build_ivar_chain (interface, copy)
       if (!super_interface)
         {
          /* fatal did not work with 2 args...should fix */
-         error ("Cannot find interface declaration for `%s', superclass of `%s'",
+         error ("cannot find interface declaration for `%s', superclass of `%s'",
                 IDENTIFIER_POINTER (super_name),
                 IDENTIFIER_POINTER (my_name));
          exit (FATAL_EXIT_CODE);
         }
 
       if (super_interface == interface)
-        {
-          fatal ("Circular inheritance in interface declaration for `%s'",
-                 IDENTIFIER_POINTER (super_name));
-        }
+       fatal_error ("circular inheritance in interface declaration for `%s'",
+                    IDENTIFIER_POINTER (super_name));
 
       interface = super_interface;
       my_name = CLASS_NAME (interface);
@@ -2781,18 +2686,10 @@ build_method_prototype_template ()
   proto_record
     = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
 
-#ifdef OBJC_INT_SELECTORS
-  /* unsigned int _cmd; */
-  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 (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, NULL_TREE);
@@ -2866,7 +2763,7 @@ encode_method_prototype (method_decl, func_decl)
   tree parms;
   int stack_size, i;
   tree user_args;
-  int max_parm_end = 0;
+  HOST_WIDE_INT max_parm_end = 0;
   char buf[40];
   tree result;
 
@@ -2882,9 +2779,8 @@ encode_method_prototype (method_decl, func_decl)
   for (parms = DECL_ARGUMENTS (func_decl); parms;
        parms = TREE_CHAIN (parms))
     {
-      int parm_end = (forwarding_offset (parms)
-                     + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
-                        / BITS_PER_UNIT));
+      HOST_WIDE_INT parm_end = (forwarding_offset (parms)
+                               + int_size_in_bytes (TREE_TYPE (parms)));
 
       if (!offset_is_register && max_parm_end < parm_end)
        max_parm_end = parm_end;
@@ -2932,7 +2828,7 @@ encode_method_prototype (method_decl, func_decl)
 static tree
 generate_descriptor_table (type, name, size, list, proto)
      tree type;
-     char *name;
+     const char *name;
      int size;
      tree list;
      tree proto;
@@ -2943,7 +2839,8 @@ generate_descriptor_table (type, name, size, list, proto)
   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
 
   decl = start_decl (synth_id_with_class_suffix (name, proto),
-                               decl_specs, 1, NULL_TREE, NULL_TREE);
+                    decl_specs, 1, NULL_TREE);
+  DECL_CONTEXT (decl) = NULL_TREE;
 
   initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
   initlist = tree_cons (NULL_TREE, list, initlist);
@@ -2958,13 +2855,14 @@ static void
 generate_method_descriptors (protocol) /* generate_dispatch_tables */
   tree protocol;
 {
-  static tree objc_method_prototype_template;
   tree initlist, chain, method_list_template;
   tree cast, variable_length_type;
   int size;
 
   if (!objc_method_prototype_template)
-    objc_method_prototype_template = build_method_prototype_template ();
+    {
+      objc_method_prototype_template = build_method_prototype_template ();
+    }
 
   cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
                                get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
@@ -3015,6 +2913,9 @@ generate_method_descriptors (protocol)    /* generate_dispatch_tables */
     UOBJC_INSTANCE_METHODS_decl = 0;
 }
 
+/* Generate a temporary FUNCTION_DECL node to be used in
+   hack_method_prototype below.  */
+
 static tree
 build_tmp_function_decl ()
 {
@@ -3029,14 +2930,14 @@ build_tmp_function_decl ()
                  (build_tree_list (decl_specs,
                                    build1 (INDIRECT_REF, NULL_TREE,
                                            NULL_TREE)),
-                  build_tree_list (NULL_TREE, NULL_TREE)));
+                  NULL_TREE));
 
   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
                                          get_identifier (TAG_SELECTOR)));
   expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
 
   push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
-                                  build_tree_list (NULL_TREE, NULL_TREE)));
+                                  NULL_TREE));
   parms = get_parm_info (0);
   poplevel (0, 0, 0);
 
@@ -3048,6 +2949,13 @@ build_tmp_function_decl ()
   return define_decl (expr_decl, decl_specs);
 }
 
+/* Generate the prototypes for protocol methods.  This is used to
+   generate method encodings for these.
+
+   NST_METHODS is the method to generate a _DECL node for TMP_DECL is
+   a decl node to be used.  This is also where the return value is
+   given.  */
+
 static void
 hack_method_prototype (nst_methods, tmp_decl)
      tree nst_methods;
@@ -3061,7 +2969,7 @@ hack_method_prototype (nst_methods, tmp_decl)
   start_method_def (nst_methods);
   TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
 
-  if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
+  if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
     parms = get_parm_info (0); /* we have a `, ...' */
   else
     parms = get_parm_info (1); /* place a `void_at_end' */
@@ -3089,7 +2997,7 @@ hack_method_prototype (nst_methods, tmp_decl)
   init_function_start (tmp_decl, "objc-act", 0);
 
   /* Typically called from expand_function_start for function definitions.  */
-  assign_parms (tmp_decl, 0);
+  assign_parms (tmp_decl);
 
   /* install return type */
   TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
@@ -3125,7 +3033,7 @@ generate_protocols ()
   tree p, tmp_decl, encoding;
   tree sc_spec, decl_specs, decl;
   tree initlist, protocol_name_expr, refs_decl, refs_expr;
-  tree cast_type2 = 0;
+  tree cast_type2;
 
   tmp_decl = build_tmp_function_decl ();
 
@@ -3185,15 +3093,16 @@ generate_protocols ()
       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, NULL_TREE, NULL_TREE);
+                        decl_specs, 1, NULL_TREE);
+
+      DECL_CONTEXT (decl) = NULL_TREE;
 
       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
 
       if (refs_decl)
        {
-         if (!cast_type2)
-           cast_type2
-             = groktypename
+         cast_type2
+           = groktypename
                (build_tree_list (build_tree_list (NULL_TREE,
                                                   objc_protocol_template),
                                  build1 (INDIRECT_REF, NULL_TREE,
@@ -3229,16 +3138,14 @@ build_protocol_initializer (type, protocol_name, protocol_list,
      tree class_methods;
 {
   tree initlist = NULL_TREE, expr;
-  static tree cast_type = 0;
+  tree cast_type;
 
-  if (!cast_type)
-    cast_type
-      = groktypename
-       (build_tree_list
-        (build_tree_list (NULL_TREE,
-                          xref_tag (RECORD_TYPE,
-                                    get_identifier (UTAG_CLASS))),
-         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
+  cast_type = 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.  */
@@ -3551,7 +3458,7 @@ synth_forward_declarations ()
 
   /* extern struct objc_class _OBJC_CLASS_<my_name>; */
 
-  an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
+  an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
 
   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
   decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
@@ -3562,7 +3469,7 @@ synth_forward_declarations ()
   /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
 
   an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
-                                     implementation_context);
+                                     objc_implementation_context);
 
   UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
   TREE_USED (UOBJC_METACLASS_decl) = 1;
@@ -3577,7 +3484,7 @@ synth_forward_declarations ()
 
 static void
 error_with_ivar (message, decl, rawdecl)
-     char *message;
+     const char *message;
      tree decl;
      tree rawdecl;
 {
@@ -3585,10 +3492,11 @@ error_with_ivar (message, decl, rawdecl)
 
   report_error_function (DECL_SOURCE_FILE (decl));
 
-  fprintf (stderr, "%s:%d: ",
-          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
-  bzero (errbuf, BUFSIZE);
-  fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
+  error_with_file_and_line (DECL_SOURCE_FILE (decl),
+                           DECL_SOURCE_LINE (decl),
+                           "%s `%s'",
+                           message, gen_declaration (rawdecl, errbuf));
+
 }
 
 #define USERTYPE(t) \
@@ -3865,15 +3773,8 @@ build_ivar_list_initializer (type, field_decl)
           ivar);
       obstack_free (&util_obstack, util_firstobj);
 
-      /* set offset */
-      ivar
-       = tree_cons
-         (NULL_TREE,
-          build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
-                        / BITS_PER_UNIT),
-                       0),
-          ivar);
-
+      /* Set offset. */
+      ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
       initlist = tree_cons (NULL_TREE, 
                            build_constructor (type, nreverse (ivar)),
                            initlist);
@@ -3888,7 +3789,7 @@ build_ivar_list_initializer (type, field_decl)
 static tree
 generate_ivars_list (type, name, size, list)
      tree type;
-     char *name;
+     const char *name;
      int size;
      tree list;
 {
@@ -3897,8 +3798,8 @@ generate_ivars_list (type, name, size, list)
   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, NULL_TREE, NULL_TREE);
+  decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
+                    decl_specs, 1, NULL_TREE);
 
   initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
   initlist = tree_cons (NULL_TREE, list, initlist);
@@ -4018,20 +3919,12 @@ build_method_template ()
 
   _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
 
-#ifdef OBJC_INT_SELECTORS
-  /* unsigned int _cmd; */
-  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 (NULL_TREE,
                          xref_tag (RECORD_TYPE,
                                    get_identifier (TAG_SELECTOR)),
                          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, NULL_TREE);
@@ -4061,7 +3954,7 @@ build_method_template ()
 static tree
 generate_dispatch_table (type, name, size, list)
      tree type;
-     char *name;
+     const char *name;
      int size;
      tree list;
 {
@@ -4070,8 +3963,8 @@ generate_dispatch_table (type, name, size, list)
   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, NULL_TREE, NULL_TREE);
+  decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
+                    decl_specs, 1, NULL_TREE);
 
   initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
   initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
@@ -4103,7 +3996,7 @@ generate_dispatch_tables ()
 
   variable_length_type = groktypename (cast);
 
-  chain = CLASS_CLS_METHODS (implementation_context);
+  chain = CLASS_CLS_METHODS (objc_implementation_context);
   if (chain)
     {
       size = list_length (chain);
@@ -4115,7 +4008,7 @@ generate_dispatch_tables ()
 
       UOBJC_CLASS_METHODS_decl
        = generate_dispatch_table (method_list_template,
-                                  ((TREE_CODE (implementation_context)
+                                  ((TREE_CODE (objc_implementation_context)
                                     == CLASS_IMPLEMENTATION_TYPE)
                                    ? "_OBJC_CLASS_METHODS"
                                    : "_OBJC_CATEGORY_CLASS_METHODS"),
@@ -4125,7 +4018,7 @@ generate_dispatch_tables ()
   else
     UOBJC_CLASS_METHODS_decl = 0;
 
-  chain = CLASS_NST_METHODS (implementation_context);
+  chain = CLASS_NST_METHODS (objc_implementation_context);
   if (chain)
     {
       size = list_length (chain);
@@ -4135,7 +4028,7 @@ generate_dispatch_tables ()
       initlist
        = build_dispatch_table_initializer (objc_method_template, chain);
 
-      if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
        UOBJC_INSTANCE_METHODS_decl
          = generate_dispatch_table (method_list_template,
                                     "_OBJC_INSTANCE_METHODS",
@@ -4156,9 +4049,9 @@ static tree
 generate_protocol_list (i_or_p)
      tree i_or_p;
 {
-  static tree cast_type = 0;
   tree initlist, decl_specs, sc_spec;
   tree refs_decl, expr_decl, lproto, e, plist;
+  tree cast_type;
   int size = 0;
 
   if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
@@ -4169,14 +4062,12 @@ generate_protocol_list (i_or_p)
   else
     abort ();
 
-  if (!cast_type)
-    cast_type
-      = groktypename
-       (build_tree_list
-        (build_tree_list (NULL_TREE,
-                          xref_tag (RECORD_TYPE,
-                                    get_identifier (UTAG_PROTOCOL))),
-         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
+  cast_type = groktypename
+    (build_tree_list
+     (build_tree_list (NULL_TREE,
+                      xref_tag (RECORD_TYPE,
+                                get_identifier (UTAG_PROTOCOL))),
+      build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
 
   /* Compute size.  */
   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
@@ -4231,7 +4122,8 @@ generate_protocol_list (i_or_p)
 
   expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
 
-  refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+  refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
+  DECL_CONTEXT (refs_decl) = NULL_TREE;
 
   finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
                                             nreverse (initlist)),
@@ -4275,17 +4167,13 @@ build_category_initializer (type, cat_name, class_name,
      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
      {
-       static tree cast_type2;
-
-       if (!cast_type2)
-         cast_type2
-           = groktypename
-             (build_tree_list
-              (build_tree_list (NULL_TREE,
-                                xref_tag (RECORD_TYPE,
-                                          get_identifier (UTAG_PROTOCOL))),
-               build1 (INDIRECT_REF, NULL_TREE,
-                       build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
+       tree cast_type2 = groktypename
+        (build_tree_list
+         (build_tree_list (NULL_TREE,
+                           xref_tag (RECORD_TYPE,
+                                     get_identifier (UTAG_PROTOCOL))),
+          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;
@@ -4386,17 +4274,14 @@ build_shared_structure_initializer (type, isa, super, name, size, status,
     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
   else
      {
-     static tree cast_type2;
-
-     if (!cast_type2)
-        cast_type2
-         = groktypename
-           (build_tree_list
-            (build_tree_list (NULL_TREE,
-                              xref_tag (RECORD_TYPE,
-                                        get_identifier (UTAG_PROTOCOL))),
-             build1 (INDIRECT_REF, NULL_TREE,
-                     build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
+       tree cast_type2
+        = groktypename
+        (build_tree_list
+         (build_tree_list (NULL_TREE,
+                           xref_tag (RECORD_TYPE,
+                                     get_identifier (UTAG_PROTOCOL))),
+          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;
@@ -4446,8 +4331,8 @@ generate_category (cat)
   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, NULL_TREE, NULL_TREE);
+                                                objc_implementation_context),
+                    decl_specs, 1, NULL_TREE);
 
   initlist = build_category_initializer (TREE_TYPE (decl),
                                         cat_name_expr, class_name_expr,
@@ -4530,15 +4415,13 @@ generate_shared_structures ()
   decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
 
   decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
-                    NULL_TREE, NULL_TREE);
+                    NULL_TREE);
 
   initlist
     = build_shared_structure_initializer
       (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),
+       convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
        2 /*CLS_META*/,
        UOBJC_CLASS_METHODS_decl,
        UOBJC_CLASS_VARIABLES_decl,
@@ -4549,18 +4432,16 @@ generate_shared_structures ()
   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
 
   decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
-                    NULL_TREE, NULL_TREE);
+                    NULL_TREE);
 
   initlist
     = build_shared_structure_initializer
       (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),
+       convert (integer_type_node,
+               TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
+                               (implementation_template))),
        1 /*CLS_FACTORY*/,
        UOBJC_INSTANCE_METHODS_decl,
        UOBJC_INSTANCE_VARIABLES_decl,
@@ -4571,15 +4452,15 @@ generate_shared_structures ()
 
 static tree
 synth_id_with_class_suffix (preamble, ctxt)
-     char *preamble;
+     const char *preamble;
      tree ctxt;
 {
   char *string;
   if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
       || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
     {
-      char *class_name
-       = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
+      const char *const class_name
+       = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
       string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
       sprintf (string, "%s_%s", preamble,
               IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
@@ -4588,10 +4469,10 @@ synth_id_with_class_suffix (preamble, ctxt)
           || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
     {
       /* We have a category.  */
-      char *class_name
-       = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
-      char *class_super_name
-       = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
+      const char *const class_name
+       = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
+      const char *const class_super_name
+       = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
       string = (char *) alloca (strlen (preamble)
                                + strlen (class_name)
                                + strlen (class_super_name)
@@ -4600,7 +4481,7 @@ synth_id_with_class_suffix (preamble, ctxt)
     }
   else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
     {
-      char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
+      const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
       string
        = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
       sprintf (string, "%s_%s", preamble, protocol_name);
@@ -4703,6 +4584,7 @@ build_keyword_selector (selector)
   tree key_chain, key_name;
   char *buf;
 
+  /* Scan the selector to see how much space we'll need.  */
   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
     {
       if (TREE_CODE (selector) == KEYWORD_DECL)
@@ -4719,8 +4601,9 @@ build_keyword_selector (selector)
        len++;
     }
 
-  buf = (char *)alloca (len + 1);
-  bzero (buf, len + 1);
+  buf = (char *) alloca (len + 1);
+  /* Start the buffer out as an empty string.  */
+  buf[0] = '\0';
 
   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
     {
@@ -4777,8 +4660,8 @@ build_method_decl (code, ret_type, selector, add_args)
 #define METHOD_DEF 0
 #define METHOD_REF 1
 
-/* Used by `build_message_expr' and `comp_method_types'.  Return an
-   argument list for method METH.  CONTEXT is either METHOD_DEF or
+/* Used by `build_objc_method_call' and `comp_method_types'.  Return
+   an argument list for method METH.  CONTEXT is either METHOD_DEF or
    METHOD_REF, saying whether we are trying to define a method or call
    one.  SUPERFLAG says this is for a send to super; this makes a
    difference for the NeXT calling sequence in which the lookup and
@@ -4810,7 +4693,7 @@ get_arg_type_list (meth, context, superflag)
       chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
     }
 
-  if (METHOD_ADD_ARGS (meth) == (tree)1)
+  if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
     /* We have a `, ...' immediately following the selector,
        finalize the arglist...simulate get_parm_info (0).  */
     ;
@@ -4854,18 +4737,29 @@ check_duplicates (hsh)
   return meth;
 }
 
-/* If RECEIVER is a class reference, return the identifier node for the
-   referenced class.  RECEIVER is created by get_class_reference, so we
-   check the exact form created depending on which runtimes are used.  */
+/* If RECEIVER is a class reference, return the identifier node for
+   the referenced class.  RECEIVER is created by get_class_reference,
+   so we check the exact form created depending on which runtimes are
+   used.  */
 
 static tree
 receiver_is_class_object (receiver)
       tree receiver;
 {
   tree chain, exp, arg;
+
+  /* The receiver is 'self' in the context of a class method.  */
+  if (objc_method_context
+      && receiver == self_decl
+      && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
+    {
+      return CLASS_NAME (objc_implementation_context);
+    }
+  
   if (flag_next_runtime)
     {
-      /* The receiver is a variable created by build_class_reference_decl.  */
+      /* 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.  */
@@ -4877,12 +4771,13 @@ receiver_is_class_object (receiver)
     {
       /* The receiver is a function call that returns an id.  Check if
         it is a call to objc_getClass, if so, pick up the class name.  */
-      if ((exp = TREE_OPERAND (receiver, 0))
+      if (TREE_CODE (receiver) == CALL_EXPR 
+         && (exp = TREE_OPERAND (receiver, 0))
          && TREE_CODE (exp) == ADDR_EXPR
          && (exp = TREE_OPERAND (exp, 0))
          && TREE_CODE (exp) == FUNCTION_DECL
          && exp == objc_get_class_decl
-         /* we have a call to objc_getClass! */
+         /* We have a call to objc_getClass!  */
          && (arg = TREE_OPERAND (receiver, 1))
          && TREE_CODE (arg) == TREE_LIST
          && (arg = TREE_VALUE (arg)))
@@ -4922,73 +4817,24 @@ build_message_expr (mess)
      tree mess;
 {
   tree receiver = TREE_PURPOSE (mess);
-  tree selector, self_object;
-  tree rtype, sel_name;
+  tree sel_name;
   tree args = TREE_VALUE (mess);
   tree method_params = NULL_TREE;
-  tree method_prototype = NULL_TREE;
-  tree retval;
-  int statically_typed = 0, statically_allocated = 0;
-  tree class_ident = 0;
-
-  /* 1 if this is sending to the superclass.  */
-  int super;
-
-  if (!doing_objc_thang)
-    objc_fatal ();
 
   if (TREE_CODE (receiver) == ERROR_MARK)
     return error_mark_node;
 
-  /* Determine receiver type.  */
-  rtype = TREE_TYPE (receiver);
-  super = IS_SUPER (rtype);
+  /* Obtain the full selector name.  */
+  if (TREE_CODE (args) == IDENTIFIER_NODE)
+    /* A unary selector.  */
+    sel_name = args;
+  else if (TREE_CODE (args) == TREE_LIST)
+    sel_name = build_keyword_selector (args);
+  else
+    abort ();
 
-  if (! super)
-    {
-      if (TREE_STATIC_TEMPLATE (rtype))
-       statically_allocated = 1;
-      else if (TREE_CODE (rtype) == POINTER_TYPE
-              && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
-       statically_typed = 1;
-      else if ((flag_next_runtime
-               || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
-              && (class_ident = receiver_is_class_object (receiver)))
-       ;
-      else if (! IS_ID (rtype)
-              /* Allow any type that matches objc_class_type.  */
-              && ! comptypes (rtype, objc_class_type))
-       {
-         bzero (errbuf, BUFSIZE);
-         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.  */
-      receiver = save_expr (receiver);
-      self_object = receiver;
-    }
-  else
-    /* If sending to `super', use current self as the object.  */
-    self_object = self_decl;
-
-  /* Obtain the full selector name.  */
-
-  if (TREE_CODE (args) == IDENTIFIER_NODE)
-    /* A unary selector.  */
-    sel_name = args;
-  else if (TREE_CODE (args) == TREE_LIST)
-    sel_name = build_keyword_selector (args);
-  else
-    abort ();
-
-  /* Build the parameter list to give to the method.  */
-
-  method_params = NULL_TREE;
-  if (TREE_CODE (args) == TREE_LIST)
+  /* Build the parameter list to give to the method.  */
+  if (TREE_CODE (args) == TREE_LIST)
     {
       tree chain = args, prev = NULL_TREE;
 
@@ -5011,9 +4857,58 @@ build_message_expr (mess)
       method_params = args;
     }
 
+  return finish_message_expr (receiver, sel_name, method_params);
+}
+
+/* The 'finish_message_expr' routine is called from within
+   'build_message_expr' for non-template functions.  In the case of
+   C++ template functions, it is called from 'build_expr_from_tree'
+   (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.  */
+   
+tree
+finish_message_expr (receiver, sel_name, method_params)
+     tree receiver, sel_name, method_params; 
+{      
+  tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
+  tree selector, self_object, retval;
+  int statically_typed = 0, statically_allocated = 0;
+  
+  /* Determine receiver type. */
+  tree rtype = TREE_TYPE (receiver);
+  int super = IS_SUPER (rtype);
+
+  if (! super)
+    {
+      if (TREE_STATIC_TEMPLATE (rtype))
+       statically_allocated = 1;
+      else if (TREE_CODE (rtype) == POINTER_TYPE
+              && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
+       statically_typed = 1;
+      else if ((flag_next_runtime
+               || (IS_ID (rtype)))
+              && (class_ident = receiver_is_class_object (receiver)))
+       ;
+      else if (! IS_ID (rtype)
+              /* Allow any type that matches objc_class_type.  */
+              && ! comptypes (rtype, objc_class_type))
+       {
+         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. */
+      receiver = save_expr (receiver);
+      self_object = receiver;
+    }
+  else
+    /* If sending to `super', use current self as the object.  */
+    self_object = self_decl;
+
   /* Determine operation return type.  */
 
-  if (IS_SUPER (rtype))
+  if (super)
     {
       tree iface;
 
@@ -5022,7 +4917,7 @@ build_message_expr (mess)
          iface
            = lookup_interface (CLASS_SUPER_NAME (implementation_template));
 
-         if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
+         if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
            method_prototype = lookup_instance_method_static (iface, sel_name);
          else
            method_prototype = lookup_class_method_static (iface, sel_name);
@@ -5064,8 +4959,8 @@ build_message_expr (mess)
 
       /* `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))
+      if (objc_implementation_context
+         && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
        {
          method_prototype
            = lookup_instance_method_static (implementation_template,
@@ -5077,11 +4972,11 @@ build_message_expr (mess)
                                                sel_name, 0);
 
          if (! method_prototype
-             && implementation_template != implementation_context)
+             && implementation_template != objc_implementation_context)
            /* The method is not published in the interface.  Check
                locally.  */
            method_prototype
-             = lookup_method (CLASS_NST_METHODS (implementation_context),
+             = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
                               sel_name);
        }
       else
@@ -5108,18 +5003,18 @@ build_message_expr (mess)
     }
   else if (class_ident)
     {
-      if (implementation_context
-         && CLASS_NAME (implementation_context) == class_ident)
+      if (objc_implementation_context
+         && CLASS_NAME (objc_implementation_context) == class_ident)
        {
          method_prototype
            = lookup_class_method_static (implementation_template, sel_name);
 
          if (!method_prototype
-             && implementation_template != implementation_context)
+             && implementation_template != objc_implementation_context)
            /* The method is not published in the interface. Check
                locally.  */
            method_prototype
-             = lookup_method (CLASS_CLS_METHODS (implementation_context),
+             = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
                               sel_name);
        }
       else
@@ -5132,7 +5027,7 @@ build_message_expr (mess)
 
       if (!method_prototype)
        {
-         warning ("cannot find class (factory) method.");
+         warning ("cannot find class (factory) method");
          warning ("return type for `%s' defaults to id",
                   IDENTIFIER_POINTER (sel_name));
        }
@@ -5150,7 +5045,7 @@ build_message_expr (mess)
        {
           hash hsh;
 
-         warning ("method `%s' not implemented by protocol.",
+         warning ("method `%s' not implemented by protocol",
                   IDENTIFIER_POINTER (sel_name));
 
           /* Try and find the method signature in the global pools.  */
@@ -5168,15 +5063,15 @@ build_message_expr (mess)
 
       /* 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 */     
        hsh = hash_lookup (cls_method_hash_list, sel_name);
 
       method_prototype = check_duplicates (hsh);
       if (!method_prototype)
        {
-         warning ("cannot find method.");
+         warning ("cannot find method");
          warning ("return type for `%s' defaults to id",
                   IDENTIFIER_POINTER (sel_name));
        }
@@ -5237,12 +5132,12 @@ 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 = NULL_TREE;
-         tree retval;
+         tree arglist = NULL_TREE, retval, savarg, savret;
+         tree ret_type = groktypename (TREE_TYPE (method_prototype));
 
          /* Save the proper contents of SENDER's data type.  */
-         tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
-         tree savret = TREE_TYPE (TREE_TYPE (sender));
+         savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
+         savret = TREE_TYPE (TREE_TYPE (sender));
 
          /* Install this method's argument types.  */
          arglist = get_arg_type_list (method_prototype, METHOD_REF,
@@ -5250,8 +5145,7 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
          TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
 
          /* Install this method's return type.  */
-         TREE_TYPE (TREE_TYPE (sender))
-           = groktypename (TREE_TYPE (method_prototype));
+         TREE_TYPE (TREE_TYPE (sender)) = ret_type;
 
          /* Call SENDER with all the parameters.  This will do type
             checking using the arg types for this method.  */
@@ -5317,9 +5211,6 @@ build_protocol_reference (p)
 {
   tree decl, ident, ptype;
 
-  push_obstacks_nochange ();
-  end_temporary_allocation ();
-
   /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
 
   ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
@@ -5338,12 +5229,11 @@ build_protocol_reference (p)
       TREE_USED (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
 
-      make_decl_rtl (decl, 0, 1);
+      make_decl_rtl (decl, 0);
       pushdecl_top_level (decl);
    }
 
   PROTOCOL_FORWARD_DECL (p) = decl;
-  pop_obstacks ();
 }
 
 tree
@@ -5351,16 +5241,11 @@ build_protocol_expr (protoname)
      tree protoname;
 {
   tree expr;
-  tree p;
-
-  if (!doing_objc_thang)
-    objc_fatal ();
-
-  p = lookup_protocol (protoname);
+  tree p = lookup_protocol (protoname);
 
   if (!p)
     {
-      error ("Cannot find protocol declaration for `%s'",
+      error ("cannot find protocol declaration for `%s'",
             IDENTIFIER_POINTER (protoname));
       return error_mark_node;
     }
@@ -5381,9 +5266,6 @@ build_selector_expr (selnamelist)
 {
   tree selname;
 
-  if (!doing_objc_thang)
-    objc_fatal ();
-
   /* Obtain the full selector name.  */
   if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
     /* A unary selector.  */
@@ -5404,10 +5286,7 @@ build_encode_expr (type)
      tree type;
 {
   tree result;
-  char *string;
-
-  if (!doing_objc_thang)
-    objc_fatal ();
+  const char *string;
 
   encode_type (type, obstack_object_size (&util_obstack),
               OBJC_ENCODE_INLINE_DEFS);
@@ -5424,7 +5303,7 @@ tree
 build_ivar_reference (id)
      tree id;
 {
-  if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
+  if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
     {
       /* Historically, a class method that produced objects (factory
         method) would assign `self' to the instance that it
@@ -5443,33 +5322,33 @@ build_ivar_reference (id)
   return build_component_ref (build_indirect_ref (self_decl, "->"), id);
 }
 \f
-#define HASH_ALLOC_LIST_SIZE   170
-#define ATTR_ALLOC_LIST_SIZE   170
-#define SIZEHASHTABLE          257
-
-/* make positive */
-#define HASHFUNCTION(key)      ((HOST_WIDE_INT) key & 0x7fffffff)
+/* Compute a hash value for a given method SEL_NAME.  */
 
+static size_t
+hash_func (sel_name)
+     tree sel_name;
+{
+  const unsigned char *s 
+    = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
+  size_t h = 0;
+  
+  while (*s)
+    h = h * 67 + *s++ - 113;
+  return h;  
+}
+     
 static void
 hash_init ()
 {
-  nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
-  cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
-
-  if (!nst_method_hash_list || !cls_method_hash_list)
-    perror ("unable to allocate space in objc-tree.c");
-  else
-    {
-      int i;
-
-      for (i = 0; i < SIZEHASHTABLE; i++)
-       {
-         nst_method_hash_list[i] = 0;
-         cls_method_hash_list[i] = 0;
-       }
-    }
+  nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
+  cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
 }
 
+/* WARNING!!!!  hash_enter is called with a method, and will peek
+   inside to find its selector!  But hash_lookup is given a selector
+   directly, and looks for the selector that's inside the found
+   entry's key (method) for comparison.  */
+
 static void
 hash_enter (hashlist, method)
      hash *hashlist;
@@ -5478,15 +5357,13 @@ hash_enter (hashlist, method)
   static hash  hash_alloc_list = 0;
   static int   hash_alloc_index = 0;
   hash obj;
-  int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
+  int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
 
   if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
     {
       hash_alloc_index = 0;
       hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
                                        * HASH_ALLOC_LIST_SIZE);
-      if (! hash_alloc_list)
-       perror ("unable to allocate in objc-tree.c");
     }
   obj = &hash_alloc_list[hash_alloc_index++];
   obj->list = 0;
@@ -5503,7 +5380,7 @@ hash_lookup (hashlist, sel_name)
 {
   hash target;
 
-  target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
+  target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
 
   while (target)
     {
@@ -5529,8 +5406,6 @@ hash_add_attr (entry, value)
       attr_alloc_index = 0;
       attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
                                        * ATTR_ALLOC_LIST_SIZE);
-      if (! attr_alloc_list)
-       perror ("unable to allocate in objc-tree.c");
     }
   obj = &attr_alloc_list[attr_alloc_index++];
   obj->next = entry->list;
@@ -5666,7 +5541,9 @@ lookup_class_method_static (interface, ident)
     }
   while (inter);
 
-  /* Simulate wrap around.  */
+  /* If no class (factory) method was found, check if an _instance_
+     method of the same name exists in the root class.  This is what
+     the Objective-C runtime will do.  */
   return lookup_instance_method_static (root_inter, ident);
 }
 
@@ -5678,10 +5555,6 @@ add_class_method (class, method)
   tree mth;
   hash hsh;
 
-  /* We will have allocated the method parameter declarations on the
-     maybepermanent_obstack.  Need to make sure they stick around!  */
-  preserve_data ();
-
   if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
     {
       /* put method on list in reverse order */
@@ -5691,13 +5564,13 @@ add_class_method (class, method)
   else
     {
       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
-       error ("duplicate definition of class method `%s'.",
+       error ("duplicate definition of class method `%s'",
               IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
       else
         {
          /* Check types; if different, complain.  */
          if (!comp_proto_with_proto (method, mth))
-           error ("duplicate declaration of class method `%s'.",
+           error ("duplicate declaration of class method `%s'",
                   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
         }
     }
@@ -5724,10 +5597,6 @@ add_instance_method (class, method)
   tree mth;
   hash hsh;
 
-  /* We will have allocated the method parameter declarations on the
-     maybepermanent_obstack.  Need to make sure they stick around!  */
-  preserve_data ();
-
   if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
     {
       /* Put method on list in reverse order.  */
@@ -5737,13 +5606,13 @@ add_instance_method (class, method)
   else
     {
       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
-       error ("duplicate definition of instance method `%s'.",
+       error ("duplicate definition of instance method `%s'",
               IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
       else
         {
          /* Check types; if different, complain.  */
          if (!comp_proto_with_proto (method, mth))
-           error ("duplicate declaration of instance method `%s'.",
+           error ("duplicate declaration of instance method `%s'",
                   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
         }
     }
@@ -5894,7 +5763,7 @@ is_public (expr, identifier)
        {
          if (!lookup_interface (TYPE_NAME (basetype)))
            {
-             error ("Cannot find interface declaration for `%s'",
+             error ("cannot find interface declaration for `%s'",
                     IDENTIFIER_POINTER (TYPE_NAME (basetype)));
              return 0;
            }
@@ -5907,12 +5776,12 @@ is_public (expr, identifier)
              /* Important difference between the Stepstone translator:
                 all instance variables should be public within the context
                 of the implementation.  */
-             if (implementation_context
-                 && (((TREE_CODE (implementation_context)
+             if (objc_implementation_context
+                 && (((TREE_CODE (objc_implementation_context)
                        == CLASS_IMPLEMENTATION_TYPE)
-                      || (TREE_CODE (implementation_context)
+                      || (TREE_CODE (objc_implementation_context)
                           == CATEGORY_IMPLEMENTATION_TYPE))
-                     && (CLASS_NAME (implementation_context)
+                     && (CLASS_NAME (objc_implementation_context)
                          == TYPE_NAME (basetype))))
                return ! is_private (decl);
 
@@ -5923,7 +5792,7 @@ is_public (expr, identifier)
            }
        }
 
-      else if (implementation_context && (basetype == objc_object_reference))
+      else if (objc_implementation_context && (basetype == objc_object_reference))
        {
          TREE_TYPE (expr) = uprivate_record;
          warning ("static access to object of type `id'");
@@ -5939,9 +5808,9 @@ tree
 get_class_ivars (interface)
      tree interface;
 {
-  if (!doing_objc_thang)
-    objc_fatal ();
-
+  /* Make sure we copy the leaf ivars in case @defs is used in a local
+     context.  Otherwise finish_struct will overwrite the layout info
+     using temporary storage.  */
   return build_ivar_chain (interface, 1);
 }
 \f
@@ -5961,14 +5830,14 @@ check_methods (chain, list, mtype)
        {
          if (first)
            {
-             if (TREE_CODE (implementation_context)
+             if (TREE_CODE (objc_implementation_context)
                  == CLASS_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of class `%s'",
-                        IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
-             else if (TREE_CODE (implementation_context)
+                        IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
+             else if (TREE_CODE (objc_implementation_context)
                       == CATEGORY_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of category `%s'",
-                        IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+                        IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
              first = 0;
            }
 
@@ -5982,16 +5851,17 @@ check_methods (chain, list, mtype)
     return first;
 }
 
+/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
+
 static int
 conforms_to_protocol (class, protocol)
      tree class;
      tree protocol;
 {
-   while (protocol)
+   if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
      {
        tree p = CLASS_PROTOCOL_LIST (class);
-
-       while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
+       while (p && TREE_VALUE (p) != protocol)
         p = TREE_CHAIN (p);
 
        if (!p)
@@ -6003,8 +5873,6 @@ conforms_to_protocol (class, protocol)
           if (!tmp)
             return 0;
         }
-
-       protocol = TREE_CHAIN (protocol);
      }
 
    return 1;
@@ -6055,16 +5923,16 @@ check_methods_accessible (chain, context, mtype)
        {
          if (first)
            {
-             if (TREE_CODE (implementation_context)
+             if (TREE_CODE (objc_implementation_context)
                  == CLASS_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of class `%s'",
                         IDENTIFIER_POINTER
-                          (CLASS_NAME (implementation_context)));
-             else if (TREE_CODE (implementation_context)
+                          (CLASS_NAME (objc_implementation_context)));
+             else if (TREE_CODE (objc_implementation_context)
                       == CATEGORY_IMPLEMENTATION_TYPE)
                warning ("incomplete implementation of category `%s'",
                         IDENTIFIER_POINTER
-                          (CLASS_SUPER_NAME (implementation_context)));
+                          (CLASS_SUPER_NAME (objc_implementation_context)));
              first = 0;
            }
          warning ("method definition for `%c%s' not found",
@@ -6076,65 +5944,86 @@ check_methods_accessible (chain, context, mtype)
     return first;
 }
 
+/* Check whether the current interface (accessible via
+   'objc_implementation_context') actually implements protocol P, along
+   with any protocols that P inherits.  */
+   
 static void
-check_protocols (proto_list, type, name)
-     tree proto_list;
-     char *type;
-     char *name;
+check_protocol (p, type, name)
+     tree p;
+     const char *type;
+     const char *name;
 {
-  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
+  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
     {
-      tree p = TREE_VALUE (proto_list);
+      int f1, f2;
 
-      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+      /* Ensure that all protocols have bodies!  */
+      if (flag_warn_protocol)
        {
-         int f1, f2;
-         
-         /* Ensure that all protocols have bodies.  */
-         if (flag_warn_protocol) {
-           f1 = check_methods (PROTOCOL_CLS_METHODS (p),
-                               CLASS_CLS_METHODS (implementation_context),
-                               '+');
-           f2 = check_methods (PROTOCOL_NST_METHODS (p),
-                               CLASS_NST_METHODS (implementation_context),
-                               '-');
-         } else {
-           f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
-                                          implementation_context,
-                                          '+');
-           f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
-                                          implementation_context,
-                                          '-');
-         }
-
-         if (!f1 || !f2)
-           warning ("%s `%s' does not fully implement the `%s' protocol",
-                    type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
-
+         f1 = check_methods (PROTOCOL_CLS_METHODS (p),
+                             CLASS_CLS_METHODS (objc_implementation_context),
+                             '+');
+         f2 = check_methods (PROTOCOL_NST_METHODS (p),
+                             CLASS_NST_METHODS (objc_implementation_context),
+                             '-');
        }
       else
-        {
-         ; /* An identifier if we could not find a protocol.  */
-        }
+       {
+         f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
+                                        objc_implementation_context,
+                                        '+');
+         f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
+                                        objc_implementation_context,
+                                        '-');
+       }
 
-      /* Check protocols recursively.  */
-      if (PROTOCOL_LIST (p))
+      if (!f1 || !f2)
+       warning ("%s `%s' does not fully implement the `%s' protocol",
+                type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+    }
+    
+  /* Check protocols recursively.  */
+  if (PROTOCOL_LIST (p))
+    {
+      tree subs = PROTOCOL_LIST (p);
+      tree super_class =
+       lookup_interface (CLASS_SUPER_NAME (implementation_template));
+      while (subs) 
        {
-         tree super_class
-           = lookup_interface (CLASS_SUPER_NAME (implementation_template));
-         if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
-           check_protocols (PROTOCOL_LIST (p), type, name);
+         tree sub = TREE_VALUE (subs);
+
+         /* If the superclass does not conform to the protocols
+            inherited by P, then we must!  */
+         if (!super_class || !conforms_to_protocol (super_class, sub))
+           check_protocol (sub, type, name);
+         subs = TREE_CHAIN (subs);
        }
     }
 }
+       
+/* Check whether the current interface (accessible via
+   'objc_implementation_context') actually implements the protocols listed
+   in PROTO_LIST.  */
+   
+static void
+check_protocols (proto_list, type, name)
+     tree proto_list;
+     const char *type;
+     const char *name;
+{
+  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
+    {
+      tree p = TREE_VALUE (proto_list);
+
+      check_protocol (p, type, name);
+    }
+}
 \f
 /* Make sure that the class CLASS_NAME is defined
    CODE says which kind of thing CLASS_NAME ought to be.
    It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
-   CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
-
-   If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
-   whose matching pop is in continue_class.  */
+   CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */
 
 tree
 start_class (code, class_name, super_name, protocol_list)
@@ -6145,15 +6034,14 @@ start_class (code, class_name, super_name, protocol_list)
 {
   tree class, decl;
 
-  if (code == CLASS_INTERFACE_TYPE)
+  if (objc_implementation_context)
     {
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
+      warning ("`@end' missing in implementation context");
+      finish_class (objc_implementation_context);
+      objc_ivar_chain = NULL_TREE;
+      objc_implementation_context = NULL_TREE;
     }
 
-  if (!doing_objc_thang)
-    objc_fatal ();
-
   class = make_node (code);
   TYPE_BINFO (class) = make_tree_vec (5);
 
@@ -6171,8 +6059,8 @@ start_class (code, class_name, super_name, protocol_list)
   if (code == CLASS_IMPLEMENTATION_TYPE)
     {
       {
-        static tree implemented_classes = 0;
-        tree chain = implemented_classes;
+        tree chain;
+
         for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
            if (TREE_VALUE (chain) == class_name)
             {
@@ -6180,8 +6068,8 @@ start_class (code, class_name, super_name, protocol_list)
                      IDENTIFIER_POINTER (class_name));
               return error_mark_node;
             }
-        implemented_classes = perm_tree_cons (NULL_TREE, class_name,
-                                             implemented_classes);
+        implemented_classes = tree_cons (NULL_TREE, class_name,
+                                        implemented_classes);
       }
 
       /* Pre-build the following entities - for speed/convenience.  */
@@ -6198,15 +6086,15 @@ start_class (code, class_name, super_name, protocol_list)
       /* Reset for multiple classes per file.  */
       method_slot = 0;
 
-      implementation_context = class;
+      objc_implementation_context = class;
 
       /* Lookup the interface for this implementation.  */
 
       if (!(implementation_template = lookup_interface (class_name)))
         {
-         warning ("Cannot find interface declaration for `%s'",
+         warning ("cannot find interface declaration for `%s'",
                   IDENTIFIER_POINTER (class_name));
-         add_class (implementation_template = implementation_context);
+         add_class (implementation_template = objc_implementation_context);
         }
 
       /* If a super class has been specified in the implementation,
@@ -6216,7 +6104,8 @@ start_class (code, class_name, super_name, protocol_list)
          && (super_name != CLASS_SUPER_NAME (implementation_template)))
         {
          tree previous_name = CLASS_SUPER_NAME (implementation_template);
-          char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
+          const char *const name =
+           previous_name ? IDENTIFIER_POINTER (previous_name) : "";
          error ("conflicting super class name `%s'",
                 IDENTIFIER_POINTER (super_name));
          error ("previous declaration of `%s'", name);
@@ -6224,7 +6113,7 @@ start_class (code, class_name, super_name, protocol_list)
 
       else if (! super_name)
        {
-         CLASS_SUPER_NAME (implementation_context) 
+         CLASS_SUPER_NAME (objc_implementation_context) 
            = CLASS_SUPER_NAME (implementation_template);
        }
     }
@@ -6252,7 +6141,7 @@ start_class (code, class_name, super_name, protocol_list)
 
       if (!(class_category_is_assoc_with = lookup_interface (class_name)))
        {
-         error ("Cannot find interface declaration for `%s'",
+         error ("cannot find interface declaration for `%s'",
                 IDENTIFIER_POINTER (class_name));
          exit (FATAL_EXIT_CODE);
        }
@@ -6280,7 +6169,7 @@ start_class (code, class_name, super_name, protocol_list)
       /* Reset for multiple classes per file.  */
       method_slot = 0;
 
-      implementation_context = class;
+      objc_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
@@ -6288,7 +6177,7 @@ start_class (code, class_name, super_name, protocol_list)
 
       if (!(implementation_template = lookup_interface (class_name)))
         {
-         error ("Cannot find interface declaration for `%s'",
+         error ("cannot find interface declaration for `%s'",
                 IDENTIFIER_POINTER (class_name));
          exit (FATAL_EXIT_CODE);
         }
@@ -6318,9 +6207,7 @@ continue_class (class)
       if (!objc_class_template)
        build_class_template ();
 
-      if (!(imp_entry
-           = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
-       perror ("unable to allocate in objc-tree.c");
+      imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
 
       imp_entry->next = imp_list;
       imp_entry->imp_context = class;
@@ -6370,18 +6257,18 @@ finish_class (class)
     {
       /* All code generation is done in finish_objc.  */
 
-      if (implementation_template != implementation_context)
+      if (implementation_template != objc_implementation_context)
        {
          /* Ensure that all method listed in the interface contain bodies.  */
          check_methods (CLASS_CLS_METHODS (implementation_template),
-                        CLASS_CLS_METHODS (implementation_context), '+');
+                        CLASS_CLS_METHODS (objc_implementation_context), '+');
          check_methods (CLASS_NST_METHODS (implementation_template),
-                        CLASS_NST_METHODS (implementation_context), '-');
+                        CLASS_NST_METHODS (objc_implementation_context), '-');
 
          if (CLASS_PROTOCOL_LIST (implementation_template))
            check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
                             "class",
-                            IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
+                            IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
        }
     }
 
@@ -6401,21 +6288,21 @@ finish_class (class)
        {
          /* Ensure all method listed in the interface contain bodies.  */
          check_methods (CLASS_CLS_METHODS (category),
-                        CLASS_CLS_METHODS (implementation_context), '+');
+                        CLASS_CLS_METHODS (objc_implementation_context), '+');
          check_methods (CLASS_NST_METHODS (category),
-                        CLASS_NST_METHODS (implementation_context), '-');
+                        CLASS_NST_METHODS (objc_implementation_context), '-');
 
          if (CLASS_PROTOCOL_LIST (category))
            check_protocols (CLASS_PROTOCOL_LIST (category),
                             "category",
-                            IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+                            IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
        }
     }
 
   else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
     {
       tree decl_specs;
-      char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
+      const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
       char *string = (char *) alloca (strlen (class_name) + 3);
 
       /* extern struct objc_object *_<my_name>; */
@@ -6454,6 +6341,33 @@ lookup_protocol (ident)
   return NULL_TREE;
 }
 
+/* This function forward declares the protocols named by NAMES.  If
+   they are already declared or defined, the function has no effect.  */
+
+void
+objc_declare_protocols (names)
+     tree names;
+{
+  tree list;
+
+  for (list = names; list; list = TREE_CHAIN (list))
+    {
+      tree name = TREE_VALUE (list);
+
+      if (lookup_protocol (name) == NULL_TREE)
+       {
+         tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
+
+         TYPE_BINFO (protocol) = make_tree_vec (2);
+         PROTOCOL_NAME (protocol) = name;
+         PROTOCOL_LIST (protocol) = NULL_TREE;
+         add_protocol (protocol);
+         PROTOCOL_DEFINED (protocol) = 0;
+         PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
+       }
+    }
+}
+
 tree
 start_protocol (code, name, list)
      enum tree_code code;
@@ -6462,29 +6376,38 @@ start_protocol (code, name, list)
 {
   tree protocol;
 
-  if (!doing_objc_thang)
-    objc_fatal ();
-
-  /* This is as good a place as any.  Need to invoke push_tag_toplevel.  */
+  /* This is as good a place as any.  Need to invoke
+     push_tag_toplevel.  */
   if (!objc_protocol_template)
     objc_protocol_template = build_protocol_template ();
 
-  protocol = make_node (code);
-  TYPE_BINFO (protocol) = make_tree_vec (2);
+  protocol = lookup_protocol (name);
 
-  PROTOCOL_NAME (protocol) = name;
-  PROTOCOL_LIST (protocol) = list;
+  if (!protocol)
+    {
+      protocol = make_node (code);
+      TYPE_BINFO (protocol) = make_tree_vec (2);
 
-  lookup_and_install_protocols (list);
+      PROTOCOL_NAME (protocol) = name;
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
+      add_protocol (protocol);
+      PROTOCOL_DEFINED (protocol) = 1;
+      PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
 
-  if (lookup_protocol (name))
-    warning ("duplicate declaration for protocol `%s'",
-          IDENTIFIER_POINTER (name));
-  else
-    add_protocol (protocol);
-
-  PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
+      check_protocol_recursively (protocol, list);
+    }
+  else if (! PROTOCOL_DEFINED (protocol))
+    {
+      PROTOCOL_DEFINED (protocol) = 1;
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
 
+      check_protocol_recursively (protocol, list);
+    }
+  else
+    {
+      warning ("duplicate declaration for protocol `%s'",
+              IDENTIFIER_POINTER (name));
+    }
   return protocol;
 }
 
@@ -6538,7 +6461,7 @@ encode_pointer (type, curtype, format)
       if (TYPE_NAME (pointer_to)
          && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
        {
-         char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
+         const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
 
          if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
            {
@@ -6566,13 +6489,11 @@ encode_pointer (type, curtype, format)
              obstack_1grow (&util_obstack, '#');
              return;
            }
-#ifndef OBJC_INT_SELECTORS
          else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
            {
              obstack_1grow (&util_obstack, ':');
              return;
            }
-#endif /* OBJC_INT_SELECTORS */
        }
     }
   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
@@ -6624,6 +6545,11 @@ encode_aggregate_within (type, curtype, format, left, right)
      int left;
      int right;
 {
+  /* The RECORD_TYPE may in fact be a typedef!  For purposes
+     of encoding, we need the real underlying enchilada.  */
+  if (TYPE_MAIN_VARIANT (type))
+    type = TYPE_MAIN_VARIANT (type);
+
   if (obstack_object_size (&util_obstack) > 0
       && *(obstack_next_free (&util_obstack) - 1) == '^')
     {
@@ -6773,9 +6699,8 @@ encode_aggregate (type, curtype, format)
    hand generating this string (which is tedious).  */
 
 static void
-encode_bitfield (width, format)
+encode_bitfield (width)
      int width;
-     int format;
 {
   char buffer[40];
   sprintf (buffer, "b%d", width);
@@ -6794,8 +6719,7 @@ encode_type (type, curtype, format)
 
   if (code == INTEGER_TYPE)
     {
-      if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
-         && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
+      if (integer_zerop (TYPE_MIN_VALUE (type)))
        {
          /* Unsigned integer types.  */
 
@@ -6870,8 +6794,7 @@ encode_complete_bitfield (int position, tree type, int size)
 
   if (code == INTEGER_TYPE)
     {
-      if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
-         && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
+      if (integer_zerop (TYPE_MIN_VALUE (type)))
        {
          /* Unsigned integer types.  */
 
@@ -6909,7 +6832,8 @@ encode_complete_bitfield (int position, tree type, int size)
            charType = 'q';
        }
     }
-
+  else if (code == ENUMERAL_TYPE)
+    charType = 'i';
   else
     abort ();
 
@@ -6933,25 +6857,16 @@ encode_field_decl (field_decl, curtype, format)
   if (flag_next_runtime)
     {
       if (DECL_BIT_FIELD (field_decl))
-       encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
-      else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
-              && DECL_FIELD_SIZE (field_decl)
-              && TYPE_MODE (type) > DECL_MODE (field_decl))
-       encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
+       encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
       else
        encode_type (TREE_TYPE (field_decl), curtype, format);
     }
   else
     {
-      if (DECL_BIT_FIELD (field_decl)
-         || (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
-             && DECL_FIELD_SIZE (field_decl)
-             && TYPE_MODE (type) > DECL_MODE (field_decl)))
-       {
-         encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)),
-                                   DECL_BIT_FIELD_TYPE (field_decl),
-                                   DECL_FIELD_SIZE (field_decl));
-       }
+      if (DECL_BIT_FIELD (field_decl))
+       encode_complete_bitfield (int_bit_position (field_decl),
+                                 DECL_BIT_FIELD_TYPE (field_decl),
+                                 tree_low_cst (DECL_SIZE (field_decl), 1));
       else
        encode_type (TREE_TYPE (field_decl), curtype, format);
     }
@@ -6970,19 +6885,6 @@ expr_last (complex_expr)
   return complex_expr;
 }
 \f
-/* The selector of the current method,
-   or NULL if we aren't compiling a method.  */
-
-tree
-maybe_objc_method_name (decl)
-      tree decl;
-{
-  if (method_context)
-    return METHOD_SEL_NAME (method_context);
-  else
-    return 0;
-}
-
 /* Transform a method definition into a function definition as follows:
    - synthesize the first two arguments, "self" and "_cmd".  */
 
@@ -6993,7 +6895,7 @@ start_method_def (method)
   tree decl_specs;
 
   /* Required to implement _msgSuper.  */
-  method_context = method;
+  objc_method_context = method;
   UOBJC_SUPER_decl = NULL_TREE;
 
   /* Must be called BEFORE start_function.  */
@@ -7001,7 +6903,7 @@ start_method_def (method)
 
   /* Generate prototype declarations for arguments..."new-style".  */
 
-  if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
+  if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
     decl_specs = build_tree_list (NULL_TREE, uprivate_record);
   else
     /* Really a `struct objc_class *'. However, we allow people to
@@ -7011,22 +6913,15 @@ start_method_def (method)
   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 (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 */
+                  unused_list));
+
   decl_specs = build_tree_list (NULL_TREE,
                                xref_tag (RECORD_TYPE,
                                          get_identifier (TAG_SELECTOR)));
   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 */
+                  unused_list));
 
   /* Generate argument declarations if a keyword_decl.  */
   if (METHOD_SEL_ARGS (method))
@@ -7045,7 +6940,7 @@ start_method_def (method)
              TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
              push_parm_decl (build_tree_list
                              (build_tree_list (arg_spec, arg_decl),
-                              build_tree_list (NULL_TREE, NULL_TREE)));
+                              NULL_TREE));
 
              /* Unhook: restore the abstract declarator.  */
              TREE_OPERAND (last_expr, 0) = NULL_TREE;
@@ -7055,14 +6950,15 @@ start_method_def (method)
            push_parm_decl (build_tree_list
                            (build_tree_list (arg_spec,
                                              KEYWORD_ARG_NAME (arglist)),
-                            build_tree_list (NULL_TREE, NULL_TREE)));
+                            NULL_TREE));
 
          arglist = TREE_CHAIN (arglist);
        }
       while (arglist);
     }
 
-  if (METHOD_ADD_ARGS (method) > (tree)1)
+  if (METHOD_ADD_ARGS (method) != NULL_TREE
+      && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
     {
       /* We have a variable length selector - in "prototype" format.  */
       tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
@@ -7079,7 +6975,7 @@ start_method_def (method)
 
 static void
 warn_with_method (message, mtype, method)
-     char *message;
+     const char *message;
      int mtype;
      tree method;
 {
@@ -7088,11 +6984,12 @@ warn_with_method (message, mtype, method)
 
   report_error_function (DECL_SOURCE_FILE (method));
 
-  fprintf (stderr, "%s:%d: warning: ",
-          DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
-  bzero (errbuf, BUFSIZE);
-  fprintf (stderr, "%s `%c%s'\n",
-          message, mtype, gen_method_decl (method, errbuf));
+  /* Add a readable method name to the warning.  */
+  warning_with_file_and_line (DECL_SOURCE_FILE (method),
+                             DECL_SOURCE_LINE (method),
+                             "%s `%c%s'",
+                             message, mtype,
+                             gen_method_decl (method, errbuf));
 }
 
 /* Return 1 if METHOD is consistent with PROTO.  */
@@ -7101,53 +6998,40 @@ static int
 comp_method_with_proto (method, proto)
      tree method, proto;
 {
-  static tree function_type = 0;
-
-  /* Create a function_type node once.  */
-  if (!function_type)
-    {
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
-      function_type = make_node (FUNCTION_TYPE);
-      pop_obstacks ();
-    }
+  /* Create a function template node at most once.  */
+  if (!function1_template)
+    function1_template = make_node (FUNCTION_TYPE);
 
   /* Install argument types - normally set by build_function_type.  */
-  TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
+  TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
 
   /* install return type */
-  TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
+  TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
 
-  return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
+  return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
 }
 
 /* Return 1 if PROTO1 is consistent with PROTO2.  */
 
 static int
-comp_proto_with_proto (proto1, proto2)
-     tree proto1, proto2;
+comp_proto_with_proto (proto0, proto1)
+     tree proto0, proto1;
 {
-  static tree function_type1 = 0, function_type2 = 0;
-
-  /* Create a couple function_type node's once.  */
-  if (!function_type1)
-    {
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
-      function_type1 = make_node (FUNCTION_TYPE);
-      function_type2 = make_node (FUNCTION_TYPE);
-      pop_obstacks ();
-    }
+  /* Create a couple of function_template nodes at most once.  */
+  if (!function1_template)
+    function1_template = make_node (FUNCTION_TYPE);
+  if (!function2_template)
+    function2_template = make_node (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);
+  TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
+  TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
 
   /* Install return type.  */
-  TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
-  TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
+  TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
+  TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
 
-  return comptypes (function_type1, function_type2);
+  return comptypes (function1_template, function2_template);
 }
 
 /* - Generate an identifier for the function. the format is "_n_cls",
@@ -7162,7 +7046,8 @@ really_start_method (method, parmlist)
 {
   tree sc_spec, ret_spec, ret_decl, decl_specs;
   tree method_decl, method_id;
-  char *buf, *sel_name, *class_name, *cat_name;
+  const char *sel_name, *class_name, *cat_name;
+  char *buf;
 
   /* Synth the storage class & assemble the return type.  */
   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
@@ -7170,11 +7055,11 @@ really_start_method (method, parmlist)
   decl_specs = chainon (sc_spec, ret_spec);
 
   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
-  class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
-  cat_name = ((TREE_CODE (implementation_context)
+  class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
+  cat_name = ((TREE_CODE (objc_implementation_context)
               == CLASS_IMPLEMENTATION_TYPE)
              ? NULL
-             : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+             : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
   method_slot++;
 
   /* Make sure this is big enough for any plausible method label.  */
@@ -7199,7 +7084,7 @@ really_start_method (method, parmlist)
       method_decl = ret_decl;
 
       /* Fool the parser into thinking it is starting a function.  */
-      start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+      start_function (decl_specs, method_decl, NULL_TREE);
 
       /* Unhook: this has the effect of restoring the abstract declarator.  */
       TREE_OPERAND (save_expr, 0) = NULL_TREE;
@@ -7210,7 +7095,7 @@ really_start_method (method, parmlist)
       TREE_VALUE (TREE_TYPE (method)) = method_decl;
 
       /* Fool the parser into thinking it is starting a function.  */
-      start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+      start_function (decl_specs, method_decl, NULL_TREE);
 
       /* Unhook: this has the effect of restoring the abstract declarator.  */
       TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
@@ -7218,7 +7103,9 @@ really_start_method (method, parmlist)
 
   METHOD_DEFINITION (method) = current_function_decl;
 
-  if (implementation_template != implementation_context)
+  /* Check consistency...start_function, pushdecl, duplicate_decls.  */
+
+  if (implementation_template != objc_implementation_context)
     {
       tree proto;
 
@@ -7249,7 +7136,7 @@ continue_method_def ()
 {
   tree parmlist;
 
-  if (METHOD_ADD_ARGS (method_context) == (tree)1)
+  if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
     /* We have a `, ...' immediately following the selector.  */
     parmlist = get_parm_info (0);
   else
@@ -7260,7 +7147,7 @@ continue_method_def ()
   self_decl = TREE_PURPOSE (parmlist);
 
   poplevel (0, 0, 0);
-  really_start_method (method_context, parmlist);
+  really_start_method (objc_method_context, parmlist);
   store_parm_decls ();
 }
 
@@ -7274,7 +7161,7 @@ add_objc_decls ()
       UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
                                     build_tree_list (NULL_TREE,
                                                      objc_super_template),
-                                    0, NULL_TREE, NULL_TREE);
+                                    0, NULL_TREE);
 
       finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
 
@@ -7293,7 +7180,7 @@ add_objc_decls ()
 tree
 get_super_receiver ()
 {
-  if (method_context)
+  if (objc_method_context)
     {
       tree super_expr, super_expr_list;
 
@@ -7306,13 +7193,13 @@ get_super_receiver ()
       super_expr = build_component_ref (UOBJC_SUPER_decl,
                                        get_identifier ("class"));
 
-      if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
        {
          /* [_cls, __cls]Super are "pre-built" in
             synth_forward_declarations.  */
 
          super_expr = build_modify_expr (super_expr, NOP_EXPR,
-                                         ((TREE_CODE (method_context)
+                                         ((TREE_CODE (objc_method_context)
                                            == INSTANCE_METHOD_DECL)
                                           ? ucls_super_ref
                                           : uucls_super_ref));
@@ -7324,6 +7211,7 @@ get_super_receiver ()
          tree super_name = CLASS_SUPER_NAME (implementation_template);
          tree super_class;
 
+         /* Barf if super used in a category of Object. */
          if (!super_name)
            {
              error ("no super class declared in interface for `%s'",
@@ -7334,7 +7222,7 @@ get_super_receiver ()
          if (flag_next_runtime)
            {
              super_class = get_class_reference (super_name);
-             if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
+             if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
                super_class
                  = build_component_ref (build_indirect_ref (super_class, "->"),
                                         get_identifier ("isa"));
@@ -7342,7 +7230,7 @@ get_super_receiver ()
          else
            {
              add_class_reference (super_name);
-             super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
+             super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
                             ? objc_get_class_decl : objc_get_meta_class_decl);
              assemble_external (super_class);
              super_class
@@ -7378,7 +7266,7 @@ encode_method_def (func_decl)
 {
   tree parms;
   int stack_size;
-  int max_parm_end = 0;
+  HOST_WIDE_INT max_parm_end = 0;
   char buffer[40];
   tree result;
 
@@ -7391,11 +7279,10 @@ encode_method_def (func_decl)
   for (parms = DECL_ARGUMENTS (func_decl); parms;
        parms = TREE_CHAIN (parms))
     {
-      int parm_end = (forwarding_offset (parms)
-                     + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
-                        / BITS_PER_UNIT));
+      HOST_WIDE_INT parm_end = (forwarding_offset (parms)
+                               + int_size_in_bytes (TREE_TYPE (parms)));
 
-      if (!offset_is_register && parm_end > max_parm_end)
+      if (! offset_is_register && parm_end > max_parm_end)
        max_parm_end = parm_end;
     }
 
@@ -7423,22 +7310,29 @@ encode_method_def (func_decl)
       obstack_grow (&util_obstack, buffer, strlen (buffer));
     }
 
+  /* Null terminate string.  */
   obstack_1grow (&util_obstack, 0);
   result = get_identifier (obstack_finish (&util_obstack));
   obstack_free (&util_obstack, util_firstobj);
   return result;
 }
 
+static void
+objc_expand_function_end ()
+{
+  METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
+}
+
 void
 finish_method_def ()
 {
-  METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
-
+  lang_expand_function_end = objc_expand_function_end;
   finish_function (0);
+  lang_expand_function_end = NULL;
 
   /* 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;
+  objc_method_context = NULL_TREE;
 }
 
 #if 0
@@ -7446,10 +7340,10 @@ int
 lang_report_error_function (decl)
       tree decl;
 {
-  if (method_context)
+  if (objc_method_context)
     {
       fprintf (stderr, "In method `%s'\n",
-              IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
+              IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
       return 1;
     }
 
@@ -7510,7 +7404,7 @@ adorn_decl (decl, str)
       strcat (str, "(");
       while (chain)
        {
-         gen_declaration (chain, str);
+         gen_declaration_1 (chain, str);
          chain = TREE_CHAIN (chain);
          if (chain)
            strcat (str, ", ");
@@ -7525,7 +7419,7 @@ adorn_decl (decl, str)
       strcat (str, "(");
       while (chain && TREE_VALUE (chain) != void_type_node)
        {
-         gen_declaration (TREE_VALUE (chain), str);
+         gen_declaration_1 (TREE_VALUE (chain), str);
          chain = TREE_CHAIN (chain);
          if (chain && TREE_VALUE (chain) != void_type_node)
            strcat (str, ", ");
@@ -7578,7 +7472,7 @@ static char *
 gen_declarator (decl, buf, name)
      tree decl;
      char *buf;
-     char *name;
+     const char *name;
 {
   if (decl)
     {
@@ -7823,7 +7717,7 @@ gen_declspecs (declspecs, buf, raw)
            strcat (buf, "long double ");
          break;
 
-      case RECORD_TYPE:
+       case RECORD_TYPE:
          if (TYPE_NAME (declspecs)
              && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
            {
@@ -7918,10 +7812,26 @@ gen_declspecs (declspecs, buf, raw)
     }
 }
 
+/* Given a tree node, produce a printable description of it in the given
+   buffer, overwriting the buffer.  */
+
 static char *
 gen_declaration (atype_or_adecl, buf)
      tree atype_or_adecl;
      char *buf;
+{
+  buf[0] = '\0';
+  gen_declaration_1 (atype_or_adecl, buf);
+  return buf;
+}
+
+/* Given a tree node, append a printable description to the end of the
+   given buffer.  */
+
+static void
+gen_declaration_1 (atype_or_adecl, buf)
+     tree atype_or_adecl;
+     char *buf;
 {
   char declbuf[256];
 
@@ -7980,9 +7890,9 @@ gen_declaration (atype_or_adecl, buf)
          || TREE_CODE (atype_or_adecl) == PARM_DECL
          || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
        {
-         char *decl_name = (DECL_NAME (atype_or_adecl)
-                            ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
-                            : "");
+         const char *const decl_name =
+           (DECL_NAME (atype_or_adecl)
+            ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
 
          if (declarator)
            {
@@ -8002,12 +7912,13 @@ gen_declaration (atype_or_adecl, buf)
          strcat (buf, gen_declarator (declarator, declbuf, ""));
        }
     }
-
-  return buf;
 }
 
 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
 
+/* Given a method tree, put a printable description into the given
+   buffer (overwriting) and return a pointer to the buffer.  */
+
 static char *
 gen_method_decl (method, buf)
      tree method;
@@ -8015,10 +7926,11 @@ gen_method_decl (method, buf)
 {
   tree chain;
 
+  buf[0] = '\0';
   if (RAW_TYPESPEC (method) != objc_object_reference)
     {
-      strcpy (buf, "(");
-      gen_declaration (TREE_TYPE (method), buf);
+      strcat (buf, "(");
+      gen_declaration_1 (TREE_TYPE (method), buf);
       strcat (buf, ")");
     }
 
@@ -8035,7 +7947,7 @@ gen_method_decl (method, buf)
          if (RAW_TYPESPEC (chain) != objc_object_reference)
            {
              strcat (buf, "(");
-             gen_declaration (TREE_TYPE (chain), buf);
+             gen_declaration_1 (TREE_TYPE (chain), buf);
              strcat (buf, ")");
            }
 
@@ -8045,7 +7957,7 @@ gen_method_decl (method, buf)
         }
       while (chain);
 
-      if (METHOD_ADD_ARGS (method) == (tree)1)
+      if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
         strcat (buf, ", ...");
       else if (METHOD_ADD_ARGS (method))
         {
@@ -8056,7 +7968,7 @@ gen_method_decl (method, buf)
           while (chain)
             {
              strcat (buf, ", ");
-             gen_declaration (chain, buf);
+             gen_declaration_1 (chain, buf);
              chain = TREE_CHAIN (chain);
             }
        }
@@ -8077,7 +7989,7 @@ dump_interface (fp, chain)
      tree chain;
 {
   char *buf = (char *)xmalloc (256);
-  char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
+  const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
   tree ivar_decls = CLASS_RAW_IVARS (chain);
   tree nst_methods = CLASS_NST_METHODS (chain);
   tree cls_methods = CLASS_CLS_METHODS (chain);
@@ -8086,7 +7998,7 @@ dump_interface (fp, chain)
 
   if (CLASS_SUPER_NAME (chain))
     {
-      char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
+      const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
       fprintf (fp, " : %s\n", super_name);
     }
   else
@@ -8097,7 +8009,6 @@ dump_interface (fp, chain)
       fprintf (fp, "{\n");
       do
        {
-         bzero (buf, 256);
          fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
          ivar_decls = TREE_CHAIN (ivar_decls);
        }
@@ -8107,14 +8018,12 @@ dump_interface (fp, chain)
 
   while (nst_methods)
     {
-      bzero (buf, 256);
       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
       nst_methods = TREE_CHAIN (nst_methods);
     }
 
   while (cls_methods)
     {
-      bzero (buf, 256);
       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
       cls_methods = TREE_CHAIN (cls_methods);
     }
@@ -8181,39 +8090,36 @@ objc_demangle (mangled)
 static const char *
 objc_printable_name (decl, kind)
      tree decl;
-     char **kind;
+     int kind ATTRIBUTE_UNUSED;
 {
   return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
 }
 
+/* Adds the tree codes specific to the ObjC/ObjC++ front end to the
+   list of all tree codes.  */
+
 static void
-init_objc ()
+add_objc_tree_codes ()
 {
-  /* Add the special tree codes of Objective C to the tables.  */
+  int add = (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE;
 
-#define LAST_CODE LAST_AND_UNUSED_TREE_CODE
+  memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE,
+         objc_tree_code_type, add);
+  memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE,
+         objc_tree_code_length, add * sizeof (int));
+  memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE,
+         objc_tree_code_name, add * sizeof (char *));
+}
 
+static void
+init_objc ()
+{
   gcc_obstack_init (&util_obstack);
   util_firstobj = (char *) obstack_finish (&util_obstack);
 
-  bcopy (objc_tree_code_type,
-        tree_code_type + (int) LAST_CODE,
-        (int) LAST_OBJC_TREE_CODE - (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 ((char *) objc_tree_code_name,
-        (char *) (tree_code_name + (int) LAST_CODE),
-        (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
-         * sizeof (char *)));
-
   errbuf = (char *)xmalloc (BUFSIZE);
   hash_init ();
   synth_module_prologue ();
-
-  /* Change the default error function */
-  decl_printable_name = (char* (*)()) objc_printable_name;
 }
 \f
 static void
@@ -8226,6 +8132,15 @@ finish_objc ()
   int save_warn_missing_braces = warn_missing_braces;
   warn_missing_braces = 0;
 
+  /* A missing @end may not be detected by the parser.  */
+  if (objc_implementation_context)
+    {
+      warning ("`@end' missing in implementation context");
+      finish_class (objc_implementation_context);
+      objc_ivar_chain = NULL_TREE;
+      objc_implementation_context = NULL_TREE;
+    }
+
   generate_forward_declaration_to_string_table ();
 
 #ifdef OBJC_PROLOGUE
@@ -8237,19 +8152,19 @@ finish_objc ()
   if (objc_static_instances)
     generate_static_references ();
 
-  if (implementation_context || class_names_chain
+  if (imp_list || class_names_chain
       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
     generate_objc_symtab_decl ();
 
   for (impent = imp_list; impent; impent = impent->next)
     {
-      implementation_context = impent->imp_context;
+      objc_implementation_context = impent->imp_context;
       implementation_template = impent->imp_template;
 
       UOBJC_CLASS_decl = impent->class_decl;
       UOBJC_METACLASS_decl = impent->meta_decl;
 
-      if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
        {
          /* all of the following reference the string pool...  */
          generate_ivar_lists ();
@@ -8259,7 +8174,7 @@ finish_objc ()
       else
        {
          generate_dispatch_tables ();
-         generate_category (implementation_context);
+         generate_category (objc_implementation_context);
        }
     }
 
@@ -8271,13 +8186,13 @@ finish_objc ()
   if (protocol_chain)
     generate_protocols ();
 
-  if (implementation_context || class_names_chain || objc_static_instances
+  if (objc_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.  */
-      char *init_name = build_module_descriptor ();
-      if (init_name)
-       assemble_constructor (init_name);
+      rtx init_sym = build_module_descriptor ();
+      if (init_sym && targetm.have_ctors_dtors)
+       (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
     }
 
   /* Dump the class references.  This forces the appropriate classes
@@ -8301,8 +8216,8 @@ finish_objc ()
 
   if (flag_gen_declaration)
     {
-      add_class (implementation_context);
-      dump_interface (gen_declaration_file, implementation_context);
+      add_class (objc_implementation_context);
+      dump_interface (gen_declaration_file, objc_implementation_context);
     }
 
   if (warn_selector)
@@ -8372,7 +8287,8 @@ generate_classref_translation_entry (chain)
 
   /* 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);
+  decl = start_decl (name, decl_specs, 1, NULL_TREE);
+  DECL_CONTEXT (decl) = NULL_TREE;
   finish_decl (decl, expr, NULL_TREE);
   return;
 }
@@ -8381,192 +8297,158 @@ static void
 handle_class_ref (chain)
      tree chain;
 {
-  char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
-  if (! flag_next_runtime)
-    {
-      tree decl;
-      char *string = (char *) alloca (strlen (name) + 30);
-      tree exp;
-
-      sprintf (string, "%sobjc_class_name_%s",
-              (flag_next_runtime ? "." : "__"), name);
-
-      /* Make a decl for this name, so we can use its address in a tree.  */
-      decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
-      DECL_EXTERNAL (decl) = 1;
-      TREE_PUBLIC (decl) = 1;
+  const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
+  char *string = (char *) alloca (strlen (name) + 30);
+  tree decl;
+  tree exp;
 
-      pushdecl (decl);
-      rest_of_decl_compilation (decl, 0, 0, 0);
+  sprintf (string, "%sobjc_class_name_%s",
+          (flag_next_runtime ? "." : "__"), name);
 
-      /* Make following constant read-only (why not)?  */
-      readonly_data_section ();
+#ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
+  if (flag_next_runtime)
+    {
+      ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
+      return;
+    }
+#endif
 
-      exp = build1 (ADDR_EXPR, string_type_node, decl);
+  /* Make a decl for this name, so we can use its address in a tree.  */
+  decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
+  DECL_EXTERNAL (decl) = 1;
+  TREE_PUBLIC (decl) = 1;
 
-      /* Align the section properly.  */
-      assemble_constant_align (exp);
+  pushdecl (decl);
+  rest_of_decl_compilation (decl, 0, 0, 0);
 
-      /* Inform the assembler about this new external thing.  */
-      assemble_external (decl);
+  /* Make a decl for the address.  */
+  sprintf (string, "%sobjc_class_ref_%s",
+          (flag_next_runtime ? "." : "__"), name);
+  exp = build1 (ADDR_EXPR, string_type_node, decl);
+  decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
+  DECL_INITIAL (decl) = exp;
+  TREE_STATIC (decl) = 1;
 
-      /* Output a constant to reference this address.  */
-      output_constant (exp, int_size_in_bytes (string_type_node));
-    }
-  else
-    {
-      /* This overreliance on our assembler (i.e. lack of portability)
-        should be dealt with at some point.  The GNU strategy (above)
-        won't work either, but it is a start.  */
-      char *string = (char *) alloca (strlen (name) + 30);
-      sprintf (string, ".reference .objc_class_name_%s", name);
-      assemble_asm (my_build_string (strlen (string) + 1, string));
-    }
+  pushdecl (decl);
+  rest_of_decl_compilation (decl, 0, 0, 0);
 }
 
 static void
 handle_impent (impent)
      struct imp_entry *impent;
 {
-  implementation_context = impent->imp_context;
+  char *string;
+
+  objc_implementation_context = impent->imp_context;
   implementation_template = impent->imp_template;
 
   if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
     {
-      char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
-      char *string = (char *) alloca (strlen (class_name) + 30);
+      const char *const class_name =
+       IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
 
-      if (flag_next_runtime)
-       {
-         /* Grossly unportable.
-            People should know better than to assume
-            such things about assembler syntax!  */
-         sprintf (string, ".objc_class_name_%s=0", class_name);
-         assemble_asm (my_build_string (strlen (string) + 1, string));
-
-         sprintf (string, ".globl .objc_class_name_%s", class_name);
-         assemble_asm (my_build_string (strlen (string) + 1, string));
-       }
+      string = (char *) alloca (strlen (class_name) + 30);
 
-      else
-       {
-         sprintf (string, "%sobjc_class_name_%s",
-                  (flag_next_runtime ? "." : "__"), class_name);
-         assemble_global (string);
-         assemble_label (string);
-       }
+      sprintf (string, "*%sobjc_class_name_%s",
+               (flag_next_runtime ? "." : "__"), class_name);
     }
-
   else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
     {
-      char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
-      char *class_super_name
-       = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
-      char *string = (char *) alloca (strlen (class_name)
-                                     + strlen (class_super_name) + 30);
+      const char *const class_name =
+       IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
+      const char *const class_super_name =
+        IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
 
-      /* 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.  */
-      if (flag_next_runtime)
-       {
-         /* Grossly unportable.  */
-         sprintf (string, ".objc_category_name_%s_%s=0",
-                  class_name, class_super_name);
-         assemble_asm (my_build_string (strlen (string) + 1, string));
-
-         sprintf (string, ".globl .objc_category_name_%s_%s",
-                  class_name, class_super_name);
-         assemble_asm (my_build_string (strlen (string) + 1, string));
-       }
+      string = (char *) alloca (strlen (class_name)
+                               + strlen (class_super_name) + 30);
 
-      else
-       {
-         sprintf (string, "%sobjc_category_name_%s_%s",
-                  (flag_next_runtime ? "." : "__"),
-                  class_name, class_super_name);
-         assemble_global (string);
-         assemble_label (string);
-       }
+      /* 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. */
+      sprintf (string, "*%sobjc_category_name_%s_%s",
+               (flag_next_runtime ? "." : "__"), class_name, class_super_name);
     }
+  else
+    return;
+
+#ifdef ASM_DECLARE_CLASS_REFERENCE
+  if (flag_next_runtime)
+    {
+      ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
+      return;
+    }
+#endif
+
+  /* (Should this be a routine in varasm.c?) */
+  readonly_data_section ();
+  assemble_global (string);
+  assemble_align (UNITS_PER_WORD);
+  assemble_label (string);
+  assemble_zeros (UNITS_PER_WORD);
 }
 \f
-#ifdef DEBUG
-
 static void
-objc_debug (fp)
-     FILE *fp;
+ggc_mark_imp_list (arg)
+    void *arg;
 {
-  char *buf = (char *)xmalloc (256);
-
-  {                            /* dump function prototypes */
-    tree loop = UOBJC_MODULES_decl;
-
-    fprintf (fp, "\n\nfunction prototypes:\n");
-    while (loop)
-      {
-       if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
-         {
-           /* We have a function definition: generate prototype.  */
-            bzero (errbuf, BUFSIZE);
-           gen_declaration (loop, errbuf);
-           fprintf (fp, "%s;\n", errbuf);
-         }
-       loop = TREE_CHAIN (loop);
-      }
-  }
-  {
-    /* Dump global chains.  */
-    tree loop;
-    int i, index = 0, offset = 0;
-    hash hashlist;
+  struct imp_entry *impent;
 
-    for (i = 0; i < SIZEHASHTABLE; i++)
-      {
-       if (hashlist = nst_method_hash_list[i])
-         {
-           fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
-           do
-             {
-               bzero (buf, 256);
-               fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
-               hashlist = hashlist->next;
-             }
-           while (hashlist);
-         }
-      }
+  for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
+    {
+      ggc_mark_tree (impent->imp_context);
+      ggc_mark_tree (impent->imp_template);
+      ggc_mark_tree (impent->class_decl);
+      ggc_mark_tree (impent->meta_decl);
+    }
+}
 
-    for (i = 0; i < SIZEHASHTABLE; i++)
-      {
-       if (hashlist = cls_method_hash_list[i])
-         {
-           fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
-           do
-             {
-               bzero (buf, 256);
-               fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
-               hashlist = hashlist->next;
-             }
-           while (hashlist);
-         }
-      }
+static void
+ggc_mark_hash_table (arg)
+    void *arg;
+{
+  hash *hash_table = *(hash **)arg;
+  hash hst;
+  attr list;
+  int i;
 
-    fprintf (fp, "\nsel_refdef_chain:\n");
-    for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
+  if (hash_table == NULL)
+    return;
+  for (i = 0; i < SIZEHASHTABLE; i++)
+    for (hst = hash_table [i]; hst; hst = hst->next)
       {
-       fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
-                IDENTIFIER_POINTER (TREE_VALUE (loop)));
-       index++;
-       /* add one for the '\0' character */
-       offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
+       ggc_mark_tree (hst->key);
+       for (list = hst->list; list; list = list->next)
+         ggc_mark_tree (list->value);
       }
+}
 
-    fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
-  }
+/* Add GC roots for variables local to this file.  */
+static void
+objc_act_parse_init ()
+{
+  ggc_add_tree_root (objc_global_trees, OCTI_MAX);
+  ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
+  ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
+  ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
 }
-#endif
 
-void
-print_lang_statistics ()
+/* Look up ID as an instance variable.  */
+tree
+lookup_objc_ivar (id)
+     tree id;
 {
+  tree decl;
+
+  if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
+    /* we have a message to super */
+    return get_super_receiver ();
+  else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
+    {
+      if (is_private (decl))
+       return error_mark_node;
+      else
+        return build_ivar_reference (id);
+    }
+  else
+    return 0;
 }
This page took 0.184038 seconds and 5 git commands to generate.